Compare commits

...

11 Commits

Author SHA1 Message Date
Spencer Comfort d8fbd0a755
Update actions & add go 1.19.x and 1.20.x to go workflow (#1414)
* Update actions

* Update go.yml

* Update go.yml

* Update go.yml
2023-02-02 19:52:49 +01:00
dnschecktool f8a185d39e
readme: add some very thankful users (#1415) 2023-01-22 16:52:13 +01:00
Kian-Meng Ang 0089167cae
Fix typos (#1413)
Found via `codespell -L ede,ans,te,crasher`
2023-01-14 08:19:09 +01:00
Ali Mosajjal fe20d5d323
Update edns.go (#1409) 2023-01-06 08:54:28 +01:00
Tom Thorogood 41a7730f43
Remove space between NextLabel func and doc comment (#1410)
This was mistakenly added in #1406.
2023-01-06 08:51:52 +01:00
Miek Gieben 4bd038eb76
Run gofmt -w -s *.go (#1408)
Signed-off-by: Miek Gieben <miek@miek.nl>

Signed-off-by: Miek Gieben <miek@miek.nl>
2023-01-05 07:53:57 +01:00
Sam Therapy caa3fe0583
edns: add missing dig options (#1389)
* edns: add missing dig options

Signed-off-by: Sam Therapy <sam@samtherapy.net>

* Apply suggested change

Signed-off-by: Sam Therapy <sam@samtherapy.net>

Signed-off-by: Sam Therapy <sam@samtherapy.net>
2023-01-05 07:53:34 +01:00
Miek Gieben 3b7e0b9bdd
NextLabel: document neg. offset will panic (#1406)
Fixes: #1404

Signed-off-by: Miek Gieben <miek@miek.nl>

Signed-off-by: Miek Gieben <miek@miek.nl>
2023-01-05 07:52:29 +01:00
Caleb Jasik 8c643eba82
Add slackhq/nebula to users (#1403)
This is currently used to provide DNS server capabilities to the nebula lighthouses.
2022-12-30 18:08:40 +01:00
Simon Elsbrock 16b12df562
fix: example in docs with invalid syntax (#1401)
fixes invalid syntax in one of the examples of the README
2022-11-12 12:38:48 +01:00
Mike Schinkel 4822b271aa
Restructure license so Github will recognize it. (#1397) 2022-11-12 12:37:31 +01:00
27 changed files with 138 additions and 124 deletions

View File

@ -15,7 +15,7 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v3
with:
fetch-depth: 2
@ -23,10 +23,10 @@ jobs:
if: ${{ github.event_name == 'pull_request' }}
- name: Initialize CodeQL
uses: github/codeql-action/init@v1
uses: github/codeql-action/init@v2
- name: Autobuild
uses: github/codeql-action/autobuild@v1
uses: github/codeql-action/autobuild@v2
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v1
uses: github/codeql-action/analyze@v2

View File

@ -7,16 +7,16 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
go: [ 1.17.x, 1.18.x ]
go: [ 1.19.x, 1.20.x ]
steps:
- name: Set up Go
uses: actions/setup-go@v2
uses: actions/setup-go@v3
with:
go-version: ${{ matrix.go }}
- name: Check out code
uses: actions/checkout@v2
uses: actions/checkout@v3
- name: Build
run: go build -v ./...

49
LICENSE
View File

@ -1,30 +1,29 @@
Copyright (c) 2009 The Go Authors. All rights reserved.
BSD 3-Clause License
Copyright (c) 2009, The Go Authors. Extensions copyright (c) 2011, Miek Gieben.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above
copyright notice, this list of conditions and the following disclaimer
in the documentation and/or other materials provided with the
distribution.
* Neither the name of Google Inc. nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its
contributors may be used to endorse or promote products derived from
this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
As this is fork of the official Go code the same license applies.
Extensions of the original work are copyright (c) 2011 Miek Gieben

View File

@ -77,6 +77,9 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://ping.sx/dig
* https://fleetdeck.io/
* https://github.com/markdingo/autoreverse
* https://github.com/slackhq/nebula
* https://github.com/dnschecktool/dow-proxy
* https://dnscheck.tools/
Send pull request if you want to be listed here.

View File

@ -19,7 +19,6 @@ type MsgAcceptFunc func(dh Header) MsgAcceptAction
// * has more than 0 RRs in the Authority section
//
// * has more than 2 RRs in the Additional section
//
var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc
// MsgAcceptAction represents the action to be taken.

View File

@ -185,7 +185,7 @@ func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, er
// that entails when using "tcp" and especially "tcp-tls" clients.
//
// When the singleflight is set for this client the context is _not_ forwarded to the (shared) exchange, to
// prevent one cancelation from canceling all outstanding requests.
// prevent one cancellation from canceling all outstanding requests.
func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) {
return c.exchangeWithConnContext(context.Background(), m, conn)
}
@ -198,7 +198,7 @@ func (c *Client) exchangeWithConnContext(ctx context.Context, m *Msg, conn *Conn
q := m.Question[0]
key := fmt.Sprintf("%s:%d:%d", q.Name, q.Qtype, q.Qclass)
r, rtt, err, shared := c.group.Do(key, func() (*Msg, time.Duration, error) {
// When we're doing singleflight we don't want one context cancelation, cancel _all_ outstanding queries.
// When we're doing singleflight we don't want one context cancellation, cancel _all_ outstanding queries.
// Hence we ignore the context and use Background().
return c.exchangeContext(context.Background(), m, conn)
})
@ -431,7 +431,6 @@ func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error)
// co.WriteMsg(m)
// in, _ := co.ReadMsg()
// co.Close()
//
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
println("dns: ExchangeConn: this function is deprecated")
co := new(Conn)

View File

@ -63,7 +63,7 @@ func TestTrimDomainName(t *testing.T) {
// Paranoid tests.
// These test shouldn't be needed but I was weary of off-by-one errors.
// In theory, these can't happen because there are no single-letter TLDs,
// but it is good to exercize the code this way.
// but it is good to exercise the code this way.
tests := []struct{ experiment, expected string }{
{"", "@"},
{".", "."},

86
doc.go
View File

@ -13,28 +13,28 @@ names in a message will result in a packing failure.
Resource records are native types. They are not stored in wire format. Basic
usage 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 = 10
r.Mx = "mx.miek.nl."
r := new(dns.MX)
r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600}
r.Preference = 10
r.Mx = "mx.miek.nl."
Or directly from a string:
mx, err := dns.NewRR("miek.nl. 3600 IN MX 10 mx.miek.nl.")
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")
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")
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)
m := new(dns.Msg)
m.SetQuestion("miek.nl.", dns.TypeMX)
Or when not certain if the domain name is fully qualified:
@ -45,17 +45,17 @@ records for the miek.nl. zone.
The following is slightly more verbose, but more flexible:
m1 := new(dns.Msg)
m1.Id = dns.Id()
m1.RecursionDesired = true
m1.Question = make([]dns.Question, 1)
m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
m1 := new(dns.Msg)
m1.Id = dns.Id()
m1.RecursionDesired = true
m1.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 synchronous
querying 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")
c := new(dns.Client)
in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
Suppressing multiple outstanding queries (with the same question, type and
class) is as easy as setting:
@ -72,7 +72,7 @@ and port to use for the connection:
Port: 12345,
Zone: "",
}
c.Dialer := &net.Dialer{
c.Dialer = &net.Dialer{
Timeout: 200 * time.Millisecond,
LocalAddr: &laddr,
}
@ -96,7 +96,7 @@ the Answer section:
// do something with t.Txt
}
Domain Name and TXT Character String Representations
# Domain Name and TXT Character String Representations
Both domain names and TXT character strings are converted to presentation form
both when unpacked and when converted to strings.
@ -108,7 +108,7 @@ be 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.
DNSSEC
# DNSSEC
DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses
public key cryptography to sign resource records. The public keys are stored in
@ -117,12 +117,12 @@ DNSKEY 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)
m := new(dns.Msg)
m.SetEdns0(4096, true)
Signature generation, signature verification and key generation are all supported.
DYNAMIC UPDATES
# DYNAMIC UPDATES
Dynamic updates reuses the DNS message format, but renames three of the
sections. Question is Zone, Answer is Prerequisite, Authority is Update, only
@ -133,30 +133,30 @@ certain resource records or names in a zone to specify if resource records
should be added or removed. The table from RFC 2136 supplemented with the Go
DNS function shows which functions exist to specify the prerequisites.
3.2.4 - Table Of Metavalues Used In Prerequisite Section
3.2.4 - Table Of Metavalues Used In Prerequisite Section
CLASS TYPE RDATA Meaning Function
--------------------------------------------------------------
ANY ANY empty Name is in use dns.NameUsed
ANY rrset empty RRset exists (value indep) dns.RRsetUsed
NONE ANY empty Name is not in use dns.NameNotUsed
NONE rrset empty RRset does not exist dns.RRsetNotUsed
zone rrset rr RRset exists (value dep) dns.Used
CLASS TYPE RDATA Meaning Function
--------------------------------------------------------------
ANY ANY empty Name is in use dns.NameUsed
ANY rrset empty RRset exists (value indep) dns.RRsetUsed
NONE ANY empty Name is not in use dns.NameNotUsed
NONE rrset empty RRset does not exist dns.RRsetNotUsed
zone rrset rr RRset exists (value dep) dns.Used
The prerequisite section can also be left empty. If you have decided on the
prerequisites you can tell what RRs should be added or deleted. The next table
shows the options you have and what functions to call.
3.4.2.6 - Table Of Metavalues Used In Update Section
3.4.2.6 - Table Of Metavalues Used In Update Section
CLASS TYPE RDATA Meaning Function
---------------------------------------------------------------
ANY ANY empty Delete all RRsets from name dns.RemoveName
ANY rrset empty Delete an RRset dns.RemoveRRset
NONE rrset rr Delete an RR from RRset dns.Remove
zone rrset rr Add to an RRset dns.Insert
CLASS TYPE RDATA Meaning Function
---------------------------------------------------------------
ANY ANY empty Delete all RRsets from name dns.RemoveName
ANY rrset empty Delete an RRset dns.RemoveRRset
NONE rrset rr Delete an RR from RRset dns.Remove
zone rrset rr Add to an RRset dns.Insert
TRANSACTION SIGNATURE
# TRANSACTION SIGNATURE
An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
The supported algorithms include: HmacSHA1, HmacSHA256 and HmacSHA512.
@ -239,7 +239,7 @@ Basic use pattern validating and replying to a message that has TSIG set.
w.WriteMsg(m)
}
PRIVATE RRS
# PRIVATE RRS
RFC 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 these
@ -248,7 +248,7 @@ can 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 more
information.
EDNS0
# EDNS0
EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by
RFC 6891. It defines a new RR type, the OPT RR, which is then completely
@ -279,9 +279,9 @@ SIG(0)
From RFC 2931:
SIG(0) provides protection for DNS transactions and requests ....
... protection for glue records, DNS requests, protection for message headers
on requests and responses, and protection of the overall integrity of a response.
SIG(0) provides protection for DNS transactions and requests ....
... protection for glue records, DNS requests, protection for message headers
on 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 of
the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256,

View File

@ -1,4 +1,5 @@
//+build ignore
//go:build ignore
// +build ignore
// types_generate.go is meant to run with go generate. It will use
// go/{importer,types} to track down all the RR struct types. Then for each type

View File

@ -78,7 +78,10 @@ func (rr *OPT) String() string {
if rr.Do() {
s += "flags: do; "
} else {
s += "flags: ; "
s += "flags:; "
}
if rr.Hdr.Ttl&0x7FFF != 0 {
s += fmt.Sprintf("MBZ: 0x%04x, ", rr.Hdr.Ttl&0x7FFF)
}
s += "udp: " + strconv.Itoa(int(rr.UDPSize()))
@ -98,6 +101,8 @@ func (rr *OPT) String() string {
s += "\n; SUBNET: " + o.String()
case *EDNS0_COOKIE:
s += "\n; COOKIE: " + o.String()
case *EDNS0_EXPIRE:
s += "\n; EXPIRE: " + o.String()
case *EDNS0_TCP_KEEPALIVE:
s += "\n; KEEPALIVE: " + o.String()
case *EDNS0_UL:
@ -258,7 +263,7 @@ func (e *EDNS0_NSID) copy() EDNS0 { return &EDNS0_NSID{e.Code, e.Nsid}
// o.Hdr.Name = "."
// o.Hdr.Rrtype = dns.TypeOPT
// e := new(dns.EDNS0_SUBNET)
// e.Code = dns.EDNS0SUBNET
// e.Code = dns.EDNS0SUBNET // by default this is filled in through unpacking OPT packets (unpackDataOpt)
// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6
// e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6
// e.SourceScope = 0

View File

@ -1,3 +1,4 @@
//go:build fuzz
// +build fuzz
package dns

View File

@ -122,7 +122,7 @@ func Split(s string) []int {
}
// NextLabel returns the index of the start of the next label in the
// string s starting at offset.
// string s starting at offset. A negative offset will cause a panic.
// The bool end is true when the end of the string has been reached.
// Also see PrevLabel.
func NextLabel(s string, offset int) (i int, end bool) {

View File

@ -1,3 +1,4 @@
//go:build !go1.11 || (!aix && !darwin && !dragonfly && !freebsd && !linux && !netbsd && !openbsd)
// +build !go1.11 !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
package dns

View File

@ -1,3 +1,4 @@
//go:build go1.11 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd)
// +build go1.11
// +build aix darwin dragonfly freebsd linux netbsd openbsd

4
msg.go
View File

@ -680,9 +680,9 @@ func unpackRRslice(l int, msg []byte, off int) (dst1 []RR, off1 int, err error)
// Convert a MsgHdr to a string, with dig-like headers:
//
//;; opcode: QUERY, status: NOERROR, id: 48404
// ;; opcode: QUERY, status: NOERROR, id: 48404
//
//;; flags: qr aa rd ra;
// ;; flags: qr aa rd ra;
func (h *MsgHdr) String() string {
if h == nil {
return "<nil> MsgHdr"

View File

@ -1,4 +1,5 @@
//+build ignore
//go:build ignore
// +build ignore
// msg_generate.go is meant to run with go generate. It will use
// go/{importer,types} to track down all the RR struct types. Then for each type

View File

@ -18,7 +18,7 @@ func TestRequestTruncateAnswer(t *testing.T) {
reply.Truncate(MinMsgSize)
if want, got := MinMsgSize, reply.Len(); want < got {
t.Errorf("message length should be bellow %d bytes, got %d bytes", want, got)
t.Errorf("message length should be below %d bytes, got %d bytes", want, got)
}
if !reply.Truncated {
t.Errorf("truncated bit should be set")
@ -38,7 +38,7 @@ func TestRequestTruncateExtra(t *testing.T) {
reply.Truncate(MinMsgSize)
if want, got := MinMsgSize, reply.Len(); want < got {
t.Errorf("message length should be bellow %d bytes, got %d bytes", want, got)
t.Errorf("message length should be below %d bytes, got %d bytes", want, got)
}
if !reply.Truncated {
t.Errorf("truncated bit should be set")
@ -62,7 +62,7 @@ func TestRequestTruncateExtraEdns0(t *testing.T) {
reply.Truncate(size)
if want, got := size, reply.Len(); want < got {
t.Errorf("message length should be bellow %d bytes, got %d bytes", want, got)
t.Errorf("message length should be below %d bytes, got %d bytes", want, got)
}
if !reply.Truncated {
t.Errorf("truncated bit should be set")
@ -94,7 +94,7 @@ func TestRequestTruncateExtraRegression(t *testing.T) {
reply.Truncate(size)
if want, got := size, reply.Len(); want < got {
t.Errorf("message length should be bellow %d bytes, got %d bytes", want, got)
t.Errorf("message length should be below %d bytes, got %d bytes", want, got)
}
if !reply.Truncated {
t.Errorf("truncated bit should be set")
@ -130,7 +130,7 @@ func TestTruncation(t *testing.T) {
copy.Truncate(bufsize)
if want, got := bufsize, copy.Len(); want < got {
t.Errorf("message length should be bellow %d bytes, got %d bytes", want, got)
t.Errorf("message length should be below %d bytes, got %d bytes", want, got)
}
}
}
@ -150,7 +150,7 @@ func TestRequestTruncateAnswerExact(t *testing.T) {
reply.Truncate(size)
if want, got := size, reply.Len(); want < got {
t.Errorf("message length should be bellow %d bytes, got %d bytes", want, got)
t.Errorf("message length should be below %d bytes, got %d bytes", want, got)
}
if expected := 52; len(reply.Answer) != expected {
t.Errorf("wrong number of answers; expected %d, got %d", expected, len(reply.Answer))

View File

@ -373,10 +373,10 @@ func TestNSEC(t *testing.T) {
func TestParseLOC(t *testing.T) {
lt := map[string]string{
"SW1A2AA.find.me.uk. LOC 51 30 12.748 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 30 12.748 N 00 07 39.611 W 0m 0.00m 0.00m 0.00m",
"SW1A2AA.find.me.uk. LOC 51 0 0.0 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 00 0.000 N 00 07 39.611 W 0m 0.00m 0.00m 0.00m",
"SW1A2AA.find.me.uk. LOC 51 30 12.748 N 00 07 39.611 W 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 30 12.748 N 00 07 39.611 W 0m 1m 10000m 10m",
"SW1A2AA.find.me.uk. LOC 51 0 0.0 N 00 07 39.611 W 0.00m 0.00m 0.00m 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 00 0.000 N 00 07 39.611 W 0m 0.00m 0.00m 0.00m",
"SW1A2AA.find.me.uk. LOC 51 30 12.748 N 00 07 39.611 W 0.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t51 30 12.748 N 00 07 39.611 W 0m 1m 10000m 10m",
// Exercise boundary cases
"SW1A2AA.find.me.uk. LOC 90 0 0.0 N 180 0 0.0 W 42849672.95 90000000.00m 90000000.00m 90000000.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t90 00 0.000 N 180 00 0.000 W 42849672.95m 90000000m 90000000m 90000000m",
"SW1A2AA.find.me.uk. LOC 90 0 0.0 N 180 0 0.0 W 42849672.95 90000000.00m 90000000.00m 90000000.00m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t90 00 0.000 N 180 00 0.000 W 42849672.95m 90000000m 90000000m 90000000m",
"SW1A2AA.find.me.uk. LOC 89 59 59.999 N 179 59 59.999 W -100000 90000000.00m 90000000.00m 90000000m": "SW1A2AA.find.me.uk.\t3600\tIN\tLOC\t89 59 59.999 N 179 59 59.999 W -100000m 90000000m 90000000m 90000000m",
// use float64 to have enough precision.
"example.com. LOC 42 21 43.952 N 71 5 6.344 W -24m 1m 200m 10m": "example.com.\t3600\tIN\tLOC\t42 21 43.952 N 71 05 6.344 W -24m 1m 200m 10m",
@ -532,7 +532,7 @@ func TestParseClass(t *testing.T) {
"t.example.com. CH A 127.0.0.1": "t.example.com. 3600 CH A 127.0.0.1",
// ClassANY can not occur in zone files
// "t.example.com. ANY A 127.0.0.1": "t.example.com. 3600 ANY A 127.0.0.1",
"t.example.com. NONE A 127.0.0.1": "t.example.com. 3600 NONE A 127.0.0.1",
"t.example.com. NONE A 127.0.0.1": "t.example.com. 3600 NONE A 127.0.0.1",
"t.example.com. CLASS255 A 127.0.0.1": "t.example.com. 3600 CLASS255 A 127.0.0.1",
}
for i, o := range tests {
@ -1515,10 +1515,10 @@ func TestParseSSHFP(t *testing.T) {
func TestParseHINFO(t *testing.T) {
dt := map[string]string{
"example.net. HINFO A B": "example.net. 3600 IN HINFO \"A\" \"B\"",
"example.net. HINFO A B": "example.net. 3600 IN HINFO \"A\" \"B\"",
"example.net. HINFO \"A\" \"B\"": "example.net. 3600 IN HINFO \"A\" \"B\"",
"example.net. HINFO A B C D E F": "example.net. 3600 IN HINFO \"A\" \"B C D E F\"",
"example.net. HINFO AB": "example.net. 3600 IN HINFO \"AB\" \"\"",
"example.net. HINFO AB": "example.net. 3600 IN HINFO \"AB\" \"\"",
// "example.net. HINFO PC-Intel-700mhz \"Redhat Linux 7.1\"": "example.net. 3600 IN HINFO \"PC-Intel-700mhz\" \"Redhat Linux 7.1\"",
// This one is recommended in Pro Bind book http://www.zytrax.com/books/dns/ch8/hinfo.html
// but effectively, even Bind would replace it to correctly formed text when you AXFR
@ -1538,9 +1538,9 @@ func TestParseHINFO(t *testing.T) {
func TestParseCAA(t *testing.T) {
lt := map[string]string{
"example.net. CAA 0 issue \"symantec.com\"": "example.net.\t3600\tIN\tCAA\t0 issue \"symantec.com\"",
"example.net. CAA 0 issue \"symantec.com\"": "example.net.\t3600\tIN\tCAA\t0 issue \"symantec.com\"",
"example.net. CAA 0 issuewild \"symantec.com; stuff\"": "example.net.\t3600\tIN\tCAA\t0 issuewild \"symantec.com; stuff\"",
"example.net. CAA 128 tbs \"critical\"": "example.net.\t3600\tIN\tCAA\t128 tbs \"critical\"",
"example.net. CAA 128 tbs \"critical\"": "example.net.\t3600\tIN\tCAA\t128 tbs \"critical\"",
"example.net. CAA 2 auth \"0>09\\006\\010+\\006\\001\\004\\001\\214y\\002\\003\\001\\006\\009`\\134H\\001e\\003\\004\\002\\001\\004 y\\209\\012\\221r\\220\\156Q\\218\\150\\150{\\166\\245:\\231\\182%\\157:\\133\\179}\\1923r\\238\\151\\255\\128q\\145\\002\\001\\000\"": "example.net.\t3600\tIN\tCAA\t2 auth \"0>09\\006\\010+\\006\\001\\004\\001\\214y\\002\\003\\001\\006\\009`\\134H\\001e\\003\\004\\002\\001\\004 y\\209\\012\\221r\\220\\156Q\\218\\150\\150{\\166\\245:\\231\\182%\\157:\\133\\179}\\1923r\\238\\151\\255\\128q\\145\\002\\001\\000\"",
"example.net. TYPE257 0 issue \"symantec.com\"": "example.net.\t3600\tIN\tCAA\t0 issue \"symantec.com\"",
}
@ -1636,24 +1636,24 @@ func TestParseCSYNC(t *testing.T) {
func TestParseSVCB(t *testing.T) {
svcbs := map[string]string{
`example.com. 3600 IN SVCB 0 cloudflare.com.`: `example.com. 3600 IN SVCB 0 cloudflare.com.`,
`example.com. 3600 IN SVCB 0 cloudflare.com.`: `example.com. 3600 IN SVCB 0 cloudflare.com.`,
`example.com. 3600 IN SVCB 65000 cloudflare.com. alpn=h2 ipv4hint=3.4.3.2`: `example.com. 3600 IN SVCB 65000 cloudflare.com. alpn="h2" ipv4hint="3.4.3.2"`,
`example.com. 3600 IN SVCB 65000 cloudflare.com. key65000=4\ 3 key65001="\" " key65002 key65003= key65004="" key65005== key65006==\"\" key65007=\254 key65008=\032`: `example.com. 3600 IN SVCB 65000 cloudflare.com. key65000="4\ 3" key65001="\"\ " key65002="" key65003="" key65004="" key65005="=" key65006="=\"\"" key65007="\254" key65008="\ "`,
// Explained in svcb.go "In AliasMode, records SHOULD NOT include any SvcParams,"
`example.com. 3600 IN SVCB 0 no-default-alpn`: `example.com. 3600 IN SVCB 0 no-default-alpn.`,
// From the specification
`example.com. HTTPS 0 foo.example.com.`: `example.com. 3600 IN HTTPS 0 foo.example.com.`,
`example.com. SVCB 1 .`: `example.com. 3600 IN SVCB 1 .`,
`example.com. SVCB 16 foo.example.com. port=53`: `example.com. 3600 IN SVCB 16 foo.example.com. port="53"`,
`example.com. SVCB 1 foo.example.com. key667=hello`: `example.com. 3600 IN SVCB 1 foo.example.com. key667="hello"`,
`example.com. SVCB 1 foo.example.com. key667="hello\210qoo"`: `example.com. 3600 IN SVCB 1 foo.example.com. key667="hello\210qoo"`,
`example.com. SVCB 1 foo.example.com. ipv6hint="2001:db8::1,2001:db8::53:1"`: `example.com. 3600 IN SVCB 1 foo.example.com. ipv6hint="2001:db8::1,2001:db8::53:1"`,
`example.com. SVCB 1 example.com. ipv6hint="2001:db8::198.51.100.100"`: `example.com. 3600 IN SVCB 1 example.com. ipv6hint="2001:db8::c633:6464"`,
`example.com. HTTPS 0 foo.example.com.`: `example.com. 3600 IN HTTPS 0 foo.example.com.`,
`example.com. SVCB 1 .`: `example.com. 3600 IN SVCB 1 .`,
`example.com. SVCB 16 foo.example.com. port=53`: `example.com. 3600 IN SVCB 16 foo.example.com. port="53"`,
`example.com. SVCB 1 foo.example.com. key667=hello`: `example.com. 3600 IN SVCB 1 foo.example.com. key667="hello"`,
`example.com. SVCB 1 foo.example.com. key667="hello\210qoo"`: `example.com. 3600 IN SVCB 1 foo.example.com. key667="hello\210qoo"`,
`example.com. SVCB 1 foo.example.com. ipv6hint="2001:db8::1,2001:db8::53:1"`: `example.com. 3600 IN SVCB 1 foo.example.com. ipv6hint="2001:db8::1,2001:db8::53:1"`,
`example.com. SVCB 1 example.com. ipv6hint="2001:db8::198.51.100.100"`: `example.com. 3600 IN SVCB 1 example.com. ipv6hint="2001:db8::c633:6464"`,
`example.com. SVCB 16 foo.example.org. alpn=h2,h3-19 mandatory=ipv4hint,alpn ipv4hint=192.0.2.1`: `example.com. 3600 IN SVCB 16 foo.example.org. alpn="h2,h3-19" mandatory="ipv4hint,alpn" ipv4hint="192.0.2.1"`,
`example.com. SVCB 16 foo.example.org. alpn="f\\\\oo\\,bar,h2"`: `example.com. 3600 IN SVCB 16 foo.example.org. alpn="f\\\092oo\\\044bar,h2"`,
`example.com. SVCB 16 foo.example.org. alpn=f\\\092oo\092,bar,h2`: `example.com. 3600 IN SVCB 16 foo.example.org. alpn="f\\\092oo\\\044bar,h2"`,
`example.com. SVCB 16 foo.example.org. alpn="f\\\\oo\\,bar,h2"`: `example.com. 3600 IN SVCB 16 foo.example.org. alpn="f\\\092oo\\\044bar,h2"`,
`example.com. SVCB 16 foo.example.org. alpn=f\\\092oo\092,bar,h2`: `example.com. 3600 IN SVCB 16 foo.example.org. alpn="f\\\092oo\\\044bar,h2"`,
// From draft-ietf-add-ddr-06
`_dns.example.net. SVCB 1 example.net. alpn=h2 dohpath=/dns-query{?dns}`: `_dns.example.net. 3600 IN SVCB 1 example.net. alpn="h2" dohpath="/dns-query{?dns}"`,
`_dns.example.net. SVCB 1 example.net. alpn=h2 dohpath=/dns-query{?dns}`: `_dns.example.net. 3600 IN SVCB 1 example.net. alpn="h2" dohpath="/dns-query{?dns}"`,
`_dns.example.net. SVCB 1 example.net. alpn=h2 dohpath=/dns\045query{\?dns}`: `_dns.example.net. 3600 IN SVCB 1 example.net. alpn="h2" dohpath="/dns-query{?dns}"`,
}
for s, o := range svcbs {

View File

@ -18,7 +18,7 @@ import (
const maxTCPQueries = 128
// aLongTimeAgo is a non-zero time, far in the past, used for
// immediate cancelation of network operations.
// immediate cancellation of network operations.
var aLongTimeAgo = time.Unix(1, 0)
// Handler is implemented by any value that implements ServeDNS.

16
svcb.go
View File

@ -353,7 +353,7 @@ func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
func (s *SVCBAlpn) String() string {
// An ALPN value is a comma-separated list of values, each of which can be
// an arbitrary binary value. In order to allow parsing, the comma and
// backslash characters are themselves excaped.
// backslash characters are themselves escaped.
//
// However, this escaping is done in addition to the normal escaping which
// happens in zone files, meaning that these values must be
@ -563,15 +563,15 @@ func (s *SVCBPort) parse(b string) error {
// to the hinted IP address may be terminated and a new connection may be opened.
// Basic use pattern for creating an ipv4hint option:
//
// h := new(dns.HTTPS)
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
// e := new(dns.SVCBIPv4Hint)
// e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()}
// h := new(dns.HTTPS)
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
// e := new(dns.SVCBIPv4Hint)
// e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()}
//
// Or
// Or
//
// e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
// h.Value = append(h.Value, e)
// e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
// h.Value = append(h.Value, e)
type SVCBIPv4Hint struct {
Hint []net.IP
}

View File

@ -1,3 +1,4 @@
//go:build tools
// +build tools
// We include our tool dependencies for `go generate` here to ensure they're

View File

@ -1,4 +1,5 @@
//+build ignore
//go:build ignore
// +build ignore
// types_generate.go is meant to run with go generate. It will use
// go/{importer,types} to track down all the RR struct types. Then for each type

1
udp.go
View File

@ -1,3 +1,4 @@
//go:build !windows
// +build !windows
package dns

View File

@ -1,3 +1,4 @@
//go:build linux && !appengine
// +build linux,!appengine
package dns

View File

@ -1,3 +1,4 @@
//go:build windows
// +build windows
package dns

View File

@ -92,7 +92,7 @@ func TestRemoveRRset(t *testing.T) {
}
func TestPreReqAndRemovals(t *testing.T) {
// Build a list of multiple prereqs and then somes removes followed by an insert.
// Build a list of multiple prereqs and then some removes followed by an insert.
// We should be able to add multiple prereqs and updates.
m := new(Msg)
m.SetUpdate("example.org.")

1
xfr.go
View File

@ -44,7 +44,6 @@ func (t *Transfer) tsigProvider() TsigProvider {
// dnscon := &dns.Conn{Conn:con}
// transfer = &dns.Transfer{Conn: dnscon}
// channel, err := transfer.In(message, master)
//
func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
switch q.Question[0].Qtype {
case TypeAXFR, TypeIXFR: