Source File
doc.go
Belonging Package
github.com/miekg/dns
/*Package dns implements a full featured interface to the Domain Name System.Both server- and client-side programming is supported. The package allowscomplete control over what is sent out to the DNS. The API follows theless-is-more principle, by presenting a small, clean interface.It supports (asynchronous) querying/replying, incoming/outgoing zone transfers,TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing.Note that domain names MUST be fully qualified before sending them, unqualifiednames in a message will result in a packing failure.Resource records are native types. They are not stored in wire format. Basicusage pattern for creating a new resource record:r := new(dns.MX)r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600}r.Preference = 10r.Mx = "mx.miek.nl."Or directly from a string:mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")Or when the default origin (.) and TTL (3600) and class (IN) suit you:mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl")Or even:mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")In the DNS messages are exchanged, these messages contain resource records(sets). Use pattern for creating a message:m := new(dns.Msg)m.SetQuestion("miek.nl.", dns.TypeMX)Or when not certain if the domain name is fully qualified:m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX)The message m is now a message with the question section set to ask the MXrecords for the miek.nl. zone.The following is slightly more verbose, but more flexible:m1 := new(dns.Msg)m1.Id = dns.Id()m1.RecursionDesired = truem1.Question = make([]dns.Question, 1)m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}After creating a message it can be sent. Basic use pattern for synchronousquerying the DNS at a server configured on 127.0.0.1 and port 53:c := new(dns.Client)in, rtt, err := c.Exchange(m1, "127.0.0.1:53")Suppressing multiple outstanding queries (with the same question, type andclass) is as easy as setting:c.SingleInflight = trueMore advanced options are available using a net.Dialer and the corresponding API.For example it is possible to set a timeout, or to specify a source IP addressand port to use for the connection:c := new(dns.Client)laddr := net.UDPAddr{IP: net.ParseIP("[::1]"),Port: 12345,Zone: "",}c.Dialer = &net.Dialer{Timeout: 200 * time.Millisecond,LocalAddr: &laddr,}in, rtt, err := c.Exchange(m1, "8.8.8.8:53")If these "advanced" features are not needed, a simple UDP query can be sent,with:in, err := dns.Exchange(m1, "127.0.0.1:53")When this functions returns you will get DNS message. A DNS message consistsout of four sections.The question section: in.Question, the answer section: in.Answer,the authority section: in.Ns and the additional section: in.Extra.Each of these sections (except the Question section) contain a []RR. Basicuse pattern for accessing the rdata of a TXT RR as the first RR inthe Answer section:if t, ok := in.Answer[0].(*dns.TXT); ok {// do something with t.Txt}# Domain Name and TXT Character String RepresentationsBoth domain names and TXT character strings are converted to presentation formboth when unpacked and when converted to strings.For TXT character strings, tabs, carriage returns and line feeds will beconverted to \t, \r and \n respectively. Back slashes and quotations marks willbe escaped. Bytes below 32 and above 127 will be converted to \DDD form.For domain names, in addition to the above rules brackets, periods, spaces,semicolons and the at symbol are escaped.# DNSSECDNSSEC (DNS Security Extension) adds a layer of security to the DNS. It usespublic key cryptography to sign resource records. The public keys are stored inDNSKEY records and the signatures in RRSIG records.Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK)bit to a request.m := new(dns.Msg)m.SetEdns0(4096, true)Signature generation, signature verification and key generation are all supported.# DYNAMIC UPDATESDynamic updates reuses the DNS message format, but renames three of thesections. Question is Zone, Answer is Prerequisite, Authority is Update, onlythe Additional is not renamed. See RFC 2136 for the gory details.You can set a rather complex set of rules for the existence of absence ofcertain resource records or names in a zone to specify if resource recordsshould be added or removed. The table from RFC 2136 supplemented with the GoDNS function shows which functions exist to specify the prerequisites.3.2.4 - Table Of Metavalues Used In Prerequisite SectionCLASS TYPE RDATA Meaning Function--------------------------------------------------------------ANY ANY empty Name is in use dns.NameUsedANY rrset empty RRset exists (value indep) dns.RRsetUsedNONE ANY empty Name is not in use dns.NameNotUsedNONE rrset empty RRset does not exist dns.RRsetNotUsedzone rrset rr RRset exists (value dep) dns.UsedThe prerequisite section can also be left empty. If you have decided on theprerequisites you can tell what RRs should be added or deleted. The next tableshows the options you have and what functions to call.3.4.2.6 - Table Of Metavalues Used In Update SectionCLASS TYPE RDATA Meaning Function---------------------------------------------------------------ANY ANY empty Delete all RRsets from name dns.RemoveNameANY rrset empty Delete an RRset dns.RemoveRRsetNONE rrset rr Delete an RR from RRset dns.Removezone rrset rr Add to an RRset dns.Insert# TRANSACTION SIGNATUREAn TSIG or transaction signature adds a HMAC TSIG record to each message sent.The supported algorithms include: HmacSHA1, HmacSHA256 and HmacSHA512.Basic use pattern when querying with a TSIG name "axfr." (note that these key namesmust be fully qualified - as they are domain names) and the base64 secret"so6ZGir4GPAqINNh9U5c3A==":If an incoming message contains a TSIG record it MUST be the last record inthe additional section (RFC2845 3.2). This means that you should make thecall to SetTsig last, right before executing the query. If you make anychanges to the RRset after calling SetTsig() the signature will be incorrect.c := new(dns.Client)c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}m := new(dns.Msg)m.SetQuestion("miek.nl.", dns.TypeMX)m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())...// When sending the TSIG RR is calculated and filled in before sendingWhen requesting an zone transfer (almost all TSIG usage is when requesting zonetransfers), with TSIG, this is the basic use pattern. In this example werequest an AXFR for miek.nl. with TSIG key named "axfr." and secret"so6ZGir4GPAqINNh9U5c3A==" and using the server 176.58.119.54:t := new(dns.Transfer)m := new(dns.Msg)t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}m.SetAxfr("miek.nl.")m.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())c, err := t.In(m, "176.58.119.54:53")for r := range c { ... }You can now read the records from the transfer as they come in. Each envelopeis checked with TSIG. If something is not correct an error is returned.A custom TSIG implementation can be used. This requires additional code toperform any session establishment and signature generation/verification. Theclient must be configured with an implementation of the TsigProvider interface:type Provider struct{}func (*Provider) Generate(msg []byte, tsig *dns.TSIG) ([]byte, error) {// Use tsig.Hdr.Name and tsig.Algorithm in your code to// generate the MAC using msg as the payload.}func (*Provider) Verify(msg []byte, tsig *dns.TSIG) error {// Use tsig.Hdr.Name and tsig.Algorithm in your code to verify// that msg matches the value in tsig.MAC.}c := new(dns.Client)c.TsigProvider = new(Provider)m := new(dns.Msg)m.SetQuestion("miek.nl.", dns.TypeMX)m.SetTsig(keyname, dns.HmacSHA256, 300, time.Now().Unix())...// TSIG RR is calculated by calling your Generate methodBasic use pattern validating and replying to a message that has TSIG set.server := &dns.Server{Addr: ":53", Net: "udp"}server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}go server.ListenAndServe()dns.HandleFunc(".", handleRequest)func handleRequest(w dns.ResponseWriter, r *dns.Msg) {m := new(dns.Msg)m.SetReply(r)if r.IsTsig() != nil {if w.TsigStatus() == nil {// *Msg r has an TSIG record and it was validatedm.SetTsig("axfr.", dns.HmacSHA256, 300, time.Now().Unix())} else {// *Msg r has an TSIG records and it was not validated}}w.WriteMsg(m)}# PRIVATE RRSRFC 6895 sets aside a range of type codes for private use. This range is 65,280- 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records thesecan be used, before requesting an official type code from IANA.See https://miek.nl/2014/september/21/idn-and-private-rr-in-go-dns/ for moreinformation.# EDNS0EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated byRFC 6891. It defines a new RR type, the OPT RR, which is then completelyabused.Basic use pattern for creating an (empty) OPT RR:o := new(dns.OPT)o.Hdr.Name = "." // MUST be the root zone, per definition.o.Hdr.Rrtype = dns.TypeOPTThe rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891) interfaces.Currently only a few have been standardized: EDNS0_NSID (RFC 5001) andEDNS0_SUBNET (RFC 7871). Note that these options may be combined in an OPT RR.Basic use pattern for a server to check if (and which) options are set:// o is a dns.OPTfor _, s := range o.Option {switch e := s.(type) {case *dns.EDNS0_NSID:// do stuff with e.Nsidcase *dns.EDNS0_SUBNET:// access e.Family, e.Address, etc.}}SIG(0)From RFC 2931:SIG(0) provides protection for DNS transactions and requests ....... protection for glue records, DNS requests, protection for message headerson requests and responses, and protection of the overall integrity of a response.It works like TSIG, except that SIG(0) uses public key cryptography, instead ofthe shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256,ECDSAP384SHA384, RSASHA1, RSASHA256 and RSASHA512.Signing subsequent messages in multi-message sessions is not implemented.*/package dns
![]() |
The pages are generated with Golds v0.8.2. (GOOS=linux GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @zigo_101 (reachable from the left QR code) to get the latest news of Golds. |