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