1/*
2Package dns implements a full featured interface to the Domain Name System.
3Server- and client-side programming is supported.
4The package allows complete control over what is sent out to the DNS. The package
5API follows the less-is-more principle, by presenting a small, clean interface.
6
7The package dns supports (asynchronous) querying/replying, incoming/outgoing zone transfers,
8TSIG, EDNS0, dynamic updates, notifies and DNSSEC validation/signing.
9Note that domain names MUST be fully qualified, before sending them, unqualified
10names in a message will result in a packing failure.
11
12Resource records are native types. They are not stored in wire format.
13Basic usage pattern for creating a new resource record:
14
15     r := new(dns.MX)
16     r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX,
17     Class: dns.ClassINET, Ttl: 3600}
18     r.Preference = 10
19     r.Mx = "mx.miek.nl."
20
21Or directly from a string:
22
23     mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
24
25Or when the default origin (.) and TTL (3600) and class (IN) suit you:
26
27     mx, err := dns.NewRR("miek.nl MX 10 mx.miek.nl")
28
29Or even:
30
31     mx, err := dns.NewRR("$ORIGIN nl.\nmiek 1H IN MX 10 mx.miek")
32
33In the DNS messages are exchanged, these messages contain resource
34records (sets). Use pattern for creating a message:
35
36     m := new(dns.Msg)
37     m.SetQuestion("miek.nl.", dns.TypeMX)
38
39Or when not certain if the domain name is fully qualified:
40
41	m.SetQuestion(dns.Fqdn("miek.nl"), dns.TypeMX)
42
43The message m is now a message with the question section set to ask
44the MX records for the miek.nl. zone.
45
46The following is slightly more verbose, but more flexible:
47
48     m1 := new(dns.Msg)
49     m1.Id = dns.Id()
50     m1.RecursionDesired = true
51     m1.Question = make([]dns.Question, 1)
52     m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
53
54After creating a message it can be sent.
55Basic use pattern for synchronous querying the DNS at a
56server configured on 127.0.0.1 and port 53:
57
58     c := new(dns.Client)
59     in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
60
61Suppressing multiple outstanding queries (with the same question, type and
62class) is as easy as setting:
63
64	c.SingleInflight = true
65
66More advanced options are available using a net.Dialer and the corresponding API.
67For example it is possible to set a timeout, or to specify a source IP address
68and port to use for the connection:
69
70	c := new(dns.Client)
71	laddr := net.UDPAddr{
72		IP: net.ParseIP("[::1]"),
73		Port: 12345,
74		Zone: "",
75	}
76	c.Dialer := &net.Dialer{
77		Timeout: 200 * time.Millisecond,
78		LocalAddr: &laddr,
79	}
80	in, rtt, err := c.Exchange(m1, "8.8.8.8:53")
81
82If these "advanced" features are not needed, a simple UDP query can be sent,
83with:
84
85	in, err := dns.Exchange(m1, "127.0.0.1:53")
86
87When this functions returns you will get dns message. A dns message consists
88out of four sections.
89The question section: in.Question, the answer section: in.Answer,
90the authority section: in.Ns and the additional section: in.Extra.
91
92Each of these sections (except the Question section) contain a []RR. Basic
93use pattern for accessing the rdata of a TXT RR as the first RR in
94the Answer section:
95
96	if t, ok := in.Answer[0].(*dns.TXT); ok {
97		// do something with t.Txt
98	}
99
100Domain Name and TXT Character String Representations
101
102Both domain names and TXT character strings are converted to presentation
103form both when unpacked and when converted to strings.
104
105For TXT character strings, tabs, carriage returns and line feeds will be
106converted to \t, \r and \n respectively. Back slashes and quotations marks
107will be escaped. Bytes below 32 and above 127 will be converted to \DDD
108form.
109
110For domain names, in addition to the above rules brackets, periods,
111spaces, semicolons and the at symbol are escaped.
112
113DNSSEC
114
115DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It
116uses public key cryptography to sign resource records. The
117public keys are stored in DNSKEY records and the signatures in RRSIG records.
118
119Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK) bit
120to a request.
121
122     m := new(dns.Msg)
123     m.SetEdns0(4096, true)
124
125Signature generation, signature verification and key generation are all supported.
126
127DYNAMIC UPDATES
128
129Dynamic updates reuses the DNS message format, but renames three of
130the sections. Question is Zone, Answer is Prerequisite, Authority is
131Update, only the Additional is not renamed. See RFC 2136 for the gory details.
132
133You can set a rather complex set of rules for the existence of absence of
134certain resource records or names in a zone to specify if resource records
135should be added or removed. The table from RFC 2136 supplemented with the Go
136DNS function shows which functions exist to specify the prerequisites.
137
138 3.2.4 - Table Of Metavalues Used In Prerequisite Section
139
140  CLASS    TYPE     RDATA    Meaning                    Function
141  --------------------------------------------------------------
142  ANY      ANY      empty    Name is in use             dns.NameUsed
143  ANY      rrset    empty    RRset exists (value indep) dns.RRsetUsed
144  NONE     ANY      empty    Name is not in use         dns.NameNotUsed
145  NONE     rrset    empty    RRset does not exist       dns.RRsetNotUsed
146  zone     rrset    rr       RRset exists (value dep)   dns.Used
147
148The prerequisite section can also be left empty.
149If you have decided on the prerequisites you can tell what RRs should
150be added or deleted. The next table shows the options you have and
151what functions to call.
152
153 3.4.2.6 - Table Of Metavalues Used In Update Section
154
155  CLASS    TYPE     RDATA    Meaning                     Function
156  ---------------------------------------------------------------
157  ANY      ANY      empty    Delete all RRsets from name dns.RemoveName
158  ANY      rrset    empty    Delete an RRset             dns.RemoveRRset
159  NONE     rrset    rr       Delete an RR from RRset     dns.Remove
160  zone     rrset    rr       Add to an RRset             dns.Insert
161
162TRANSACTION SIGNATURE
163
164An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
165The supported algorithms include: HmacMD5, HmacSHA1, HmacSHA256 and HmacSHA512.
166
167Basic use pattern when querying with a TSIG name "axfr." (note that these key names
168must be fully qualified - as they are domain names) and the base64 secret
169"so6ZGir4GPAqINNh9U5c3A==":
170
171If an incoming message contains a TSIG record it MUST be the last record in
172the additional section (RFC2845 3.2).  This means that you should make the
173call to SetTsig last, right before executing the query.  If you make any
174changes to the RRset after calling SetTsig() the signature will be incorrect.
175
176	c := new(dns.Client)
177	c.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
178	m := new(dns.Msg)
179	m.SetQuestion("miek.nl.", dns.TypeMX)
180	m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
181	...
182	// When sending the TSIG RR is calculated and filled in before sending
183
184When requesting an zone transfer (almost all TSIG usage is when requesting zone transfers), with
185TSIG, this is the basic use pattern. In this example we request an AXFR for
186miek.nl. with TSIG key named "axfr." and secret "so6ZGir4GPAqINNh9U5c3A=="
187and using the server 176.58.119.54:
188
189	t := new(dns.Transfer)
190	m := new(dns.Msg)
191	t.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
192	m.SetAxfr("miek.nl.")
193	m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
194	c, err := t.In(m, "176.58.119.54:53")
195	for r := range c { ... }
196
197You can now read the records from the transfer as they come in. Each envelope is checked with TSIG.
198If something is not correct an error is returned.
199
200Basic use pattern validating and replying to a message that has TSIG set.
201
202	server := &dns.Server{Addr: ":53", Net: "udp"}
203	server.TsigSecret = map[string]string{"axfr.": "so6ZGir4GPAqINNh9U5c3A=="}
204	go server.ListenAndServe()
205	dns.HandleFunc(".", handleRequest)
206
207	func handleRequest(w dns.ResponseWriter, r *dns.Msg) {
208		m := new(dns.Msg)
209		m.SetReply(r)
210		if r.IsTsig() != nil {
211			if w.TsigStatus() == nil {
212				// *Msg r has an TSIG record and it was validated
213				m.SetTsig("axfr.", dns.HmacMD5, 300, time.Now().Unix())
214			} else {
215				// *Msg r has an TSIG records and it was not valided
216			}
217		}
218		w.WriteMsg(m)
219	}
220
221PRIVATE RRS
222
223RFC 6895 sets aside a range of type codes for private use. This range
224is 65,280 - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these
225can be used, before requesting an official type code from IANA.
226
227see http://miek.nl/2014/September/21/idn-and-private-rr-in-go-dns/ for more
228information.
229
230EDNS0
231
232EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated
233by RFC 6891. It defines an new RR type, the OPT RR, which is then completely
234abused.
235Basic use pattern for creating an (empty) OPT RR:
236
237	o := new(dns.OPT)
238	o.Hdr.Name = "." // MUST be the root zone, per definition.
239	o.Hdr.Rrtype = dns.TypeOPT
240
241The rdata of an OPT RR consists out of a slice of EDNS0 (RFC 6891)
242interfaces. Currently only a few have been standardized: EDNS0_NSID
243(RFC 5001) and EDNS0_SUBNET (draft-vandergaast-edns-client-subnet-02). Note
244that these options may be combined in an OPT RR.
245Basic use pattern for a server to check if (and which) options are set:
246
247	// o is a dns.OPT
248	for _, s := range o.Option {
249		switch e := s.(type) {
250		case *dns.EDNS0_NSID:
251			// do stuff with e.Nsid
252		case *dns.EDNS0_SUBNET:
253			// access e.Family, e.Address, etc.
254		}
255	}
256
257SIG(0)
258
259From RFC 2931:
260
261    SIG(0) provides protection for DNS transactions and requests ....
262    ... protection for glue records, DNS requests, protection for message headers
263    on requests and responses, and protection of the overall integrity of a response.
264
265It works like TSIG, except that SIG(0) uses public key cryptography, instead of the shared
266secret approach in TSIG.
267Supported algorithms: DSA, ECDSAP256SHA256, ECDSAP384SHA384, RSASHA1, RSASHA256 and
268RSASHA512.
269
270Signing subsequent messages in multi-message sessions is not implemented.
271*/
272package dns
273