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