Compare commits
11 Commits
Author | SHA1 | Date |
---|---|---|
Spencer Comfort | d8fbd0a755 | |
dnschecktool | f8a185d39e | |
Kian-Meng Ang | 0089167cae | |
Ali Mosajjal | fe20d5d323 | |
Tom Thorogood | 41a7730f43 | |
Miek Gieben | 4bd038eb76 | |
Sam Therapy | caa3fe0583 | |
Miek Gieben | 3b7e0b9bdd | |
Caleb Jasik | 8c643eba82 | |
Simon Elsbrock | 16b12df562 | |
Mike Schinkel | 4822b271aa |
|
@ -15,7 +15,7 @@ jobs:
|
||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout repository
|
- name: Checkout repository
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 2
|
fetch-depth: 2
|
||||||
|
|
||||||
|
@ -23,10 +23,10 @@ jobs:
|
||||||
if: ${{ github.event_name == 'pull_request' }}
|
if: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
- name: Initialize CodeQL
|
- name: Initialize CodeQL
|
||||||
uses: github/codeql-action/init@v1
|
uses: github/codeql-action/init@v2
|
||||||
|
|
||||||
- name: Autobuild
|
- name: Autobuild
|
||||||
uses: github/codeql-action/autobuild@v1
|
uses: github/codeql-action/autobuild@v2
|
||||||
|
|
||||||
- name: Perform CodeQL Analysis
|
- name: Perform CodeQL Analysis
|
||||||
uses: github/codeql-action/analyze@v1
|
uses: github/codeql-action/analyze@v2
|
||||||
|
|
|
@ -7,16 +7,16 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
strategy:
|
strategy:
|
||||||
matrix:
|
matrix:
|
||||||
go: [ 1.17.x, 1.18.x ]
|
go: [ 1.19.x, 1.20.x ]
|
||||||
steps:
|
steps:
|
||||||
|
|
||||||
- name: Set up Go
|
- name: Set up Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: ${{ matrix.go }}
|
go-version: ${{ matrix.go }}
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Build
|
- name: Build
|
||||||
run: go build -v ./...
|
run: go build -v ./...
|
||||||
|
|
49
LICENSE
49
LICENSE
|
@ -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
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are met:
|
||||||
met:
|
|
||||||
|
|
||||||
* Redistributions of source code must retain the above copyright
|
1. Redistributions of source code must retain the above copyright notice, this
|
||||||
notice, this list of conditions and the following disclaimer.
|
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.
|
|
||||||
|
|
||||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
2. Redistributions in binary form must reproduce the above copyright notice,
|
||||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
this list of conditions and the following disclaimer in the documentation
|
||||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
and/or other materials provided with the distribution.
|
||||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
|
||||||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
3. Neither the name of the copyright holder nor the names of its
|
||||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
contributors may be used to endorse or promote products derived from
|
||||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
this software without specific prior written permission.
|
||||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
|
||||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
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.
|
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
|
|
||||||
|
|
|
@ -77,6 +77,9 @@ A not-so-up-to-date-list-that-may-be-actually-current:
|
||||||
* https://ping.sx/dig
|
* https://ping.sx/dig
|
||||||
* https://fleetdeck.io/
|
* https://fleetdeck.io/
|
||||||
* https://github.com/markdingo/autoreverse
|
* 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.
|
Send pull request if you want to be listed here.
|
||||||
|
|
|
@ -19,7 +19,6 @@ type MsgAcceptFunc func(dh Header) MsgAcceptAction
|
||||||
// * has more than 0 RRs in the Authority section
|
// * has more than 0 RRs in the Authority section
|
||||||
//
|
//
|
||||||
// * has more than 2 RRs in the Additional section
|
// * has more than 2 RRs in the Additional section
|
||||||
//
|
|
||||||
var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc
|
var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc
|
||||||
|
|
||||||
// MsgAcceptAction represents the action to be taken.
|
// MsgAcceptAction represents the action to be taken.
|
||||||
|
|
|
@ -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.
|
// 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
|
// 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) {
|
func (c *Client) ExchangeWithConn(m *Msg, conn *Conn) (r *Msg, rtt time.Duration, err error) {
|
||||||
return c.exchangeWithConnContext(context.Background(), m, conn)
|
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]
|
q := m.Question[0]
|
||||||
key := fmt.Sprintf("%s:%d:%d", q.Name, q.Qtype, q.Qclass)
|
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) {
|
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().
|
// Hence we ignore the context and use Background().
|
||||||
return c.exchangeContext(context.Background(), m, conn)
|
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)
|
// co.WriteMsg(m)
|
||||||
// in, _ := co.ReadMsg()
|
// in, _ := co.ReadMsg()
|
||||||
// co.Close()
|
// co.Close()
|
||||||
//
|
|
||||||
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
|
func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
|
||||||
println("dns: ExchangeConn: this function is deprecated")
|
println("dns: ExchangeConn: this function is deprecated")
|
||||||
co := new(Conn)
|
co := new(Conn)
|
||||||
|
|
|
@ -63,7 +63,7 @@ func TestTrimDomainName(t *testing.T) {
|
||||||
// Paranoid tests.
|
// Paranoid tests.
|
||||||
// These test shouldn't be needed but I was weary of off-by-one errors.
|
// 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,
|
// 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 }{
|
tests := []struct{ experiment, expected string }{
|
||||||
{"", "@"},
|
{"", "@"},
|
||||||
{".", "."},
|
{".", "."},
|
||||||
|
|
86
doc.go
86
doc.go
|
@ -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
|
Resource records are native types. They are not stored in wire format. Basic
|
||||||
usage pattern for creating a new resource record:
|
usage pattern for creating a new resource record:
|
||||||
|
|
||||||
r := new(dns.MX)
|
r := new(dns.MX)
|
||||||
r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600}
|
r.Hdr = dns.RR_Header{Name: "miek.nl.", Rrtype: dns.TypeMX, Class: dns.ClassINET, Ttl: 3600}
|
||||||
r.Preference = 10
|
r.Preference = 10
|
||||||
r.Mx = "mx.miek.nl."
|
r.Mx = "mx.miek.nl."
|
||||||
|
|
||||||
Or directly from a string:
|
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:
|
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:
|
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
|
In the DNS messages are exchanged, these messages contain resource records
|
||||||
(sets). Use pattern for creating a message:
|
(sets). Use pattern for creating a message:
|
||||||
|
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetQuestion("miek.nl.", dns.TypeMX)
|
m.SetQuestion("miek.nl.", dns.TypeMX)
|
||||||
|
|
||||||
Or when not certain if the domain name is fully qualified:
|
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:
|
The following is slightly more verbose, but more flexible:
|
||||||
|
|
||||||
m1 := new(dns.Msg)
|
m1 := new(dns.Msg)
|
||||||
m1.Id = dns.Id()
|
m1.Id = dns.Id()
|
||||||
m1.RecursionDesired = true
|
m1.RecursionDesired = true
|
||||||
m1.Question = make([]dns.Question, 1)
|
m1.Question = make([]dns.Question, 1)
|
||||||
m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
|
m1.Question[0] = dns.Question{"miek.nl.", dns.TypeMX, dns.ClassINET}
|
||||||
|
|
||||||
After creating a message it can be sent. Basic use pattern for synchronous
|
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:
|
querying the DNS at a server configured on 127.0.0.1 and port 53:
|
||||||
|
|
||||||
c := new(dns.Client)
|
c := new(dns.Client)
|
||||||
in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
|
in, rtt, err := c.Exchange(m1, "127.0.0.1:53")
|
||||||
|
|
||||||
Suppressing multiple outstanding queries (with the same question, type and
|
Suppressing multiple outstanding queries (with the same question, type and
|
||||||
class) is as easy as setting:
|
class) is as easy as setting:
|
||||||
|
@ -72,7 +72,7 @@ and port to use for the connection:
|
||||||
Port: 12345,
|
Port: 12345,
|
||||||
Zone: "",
|
Zone: "",
|
||||||
}
|
}
|
||||||
c.Dialer := &net.Dialer{
|
c.Dialer = &net.Dialer{
|
||||||
Timeout: 200 * time.Millisecond,
|
Timeout: 200 * time.Millisecond,
|
||||||
LocalAddr: &laddr,
|
LocalAddr: &laddr,
|
||||||
}
|
}
|
||||||
|
@ -96,7 +96,7 @@ the Answer section:
|
||||||
// do something with t.Txt
|
// 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 domain names and TXT character strings are converted to presentation form
|
||||||
both when unpacked and when converted to strings.
|
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,
|
For domain names, in addition to the above rules brackets, periods, spaces,
|
||||||
semicolons and the at symbol are escaped.
|
semicolons and the at symbol are escaped.
|
||||||
|
|
||||||
DNSSEC
|
# DNSSEC
|
||||||
|
|
||||||
DNSSEC (DNS Security Extension) adds a layer of security to the DNS. It uses
|
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
|
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)
|
Requesting DNSSEC information for a zone is done by adding the DO (DNSSEC OK)
|
||||||
bit to a request.
|
bit to a request.
|
||||||
|
|
||||||
m := new(dns.Msg)
|
m := new(dns.Msg)
|
||||||
m.SetEdns0(4096, true)
|
m.SetEdns0(4096, true)
|
||||||
|
|
||||||
Signature generation, signature verification and key generation are all supported.
|
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
|
Dynamic updates reuses the DNS message format, but renames three of the
|
||||||
sections. Question is Zone, Answer is Prerequisite, Authority is Update, only
|
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
|
should be added or removed. The table from RFC 2136 supplemented with the Go
|
||||||
DNS function shows which functions exist to specify the prerequisites.
|
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
|
CLASS TYPE RDATA Meaning Function
|
||||||
--------------------------------------------------------------
|
--------------------------------------------------------------
|
||||||
ANY ANY empty Name is in use dns.NameUsed
|
ANY ANY empty Name is in use dns.NameUsed
|
||||||
ANY rrset empty RRset exists (value indep) dns.RRsetUsed
|
ANY rrset empty RRset exists (value indep) dns.RRsetUsed
|
||||||
NONE ANY empty Name is not in use dns.NameNotUsed
|
NONE ANY empty Name is not in use dns.NameNotUsed
|
||||||
NONE rrset empty RRset does not exist dns.RRsetNotUsed
|
NONE rrset empty RRset does not exist dns.RRsetNotUsed
|
||||||
zone rrset rr RRset exists (value dep) dns.Used
|
zone rrset rr RRset exists (value dep) dns.Used
|
||||||
|
|
||||||
The prerequisite section can also be left empty. If you have decided on the
|
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
|
prerequisites you can tell what RRs should be added or deleted. The next table
|
||||||
shows the options you have and what functions to call.
|
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
|
CLASS TYPE RDATA Meaning Function
|
||||||
---------------------------------------------------------------
|
---------------------------------------------------------------
|
||||||
ANY ANY empty Delete all RRsets from name dns.RemoveName
|
ANY ANY empty Delete all RRsets from name dns.RemoveName
|
||||||
ANY rrset empty Delete an RRset dns.RemoveRRset
|
ANY rrset empty Delete an RRset dns.RemoveRRset
|
||||||
NONE rrset rr Delete an RR from RRset dns.Remove
|
NONE rrset rr Delete an RR from RRset dns.Remove
|
||||||
zone rrset rr Add to an RRset dns.Insert
|
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.
|
An TSIG or transaction signature adds a HMAC TSIG record to each message sent.
|
||||||
The supported algorithms include: HmacSHA1, HmacSHA256 and HmacSHA512.
|
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)
|
w.WriteMsg(m)
|
||||||
}
|
}
|
||||||
|
|
||||||
PRIVATE RRS
|
# PRIVATE RRS
|
||||||
|
|
||||||
RFC 6895 sets aside a range of type codes for private use. This range is 65,280
|
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
|
- 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
|
See https://miek.nl/2014/september/21/idn-and-private-rr-in-go-dns/ for more
|
||||||
information.
|
information.
|
||||||
|
|
||||||
EDNS0
|
# EDNS0
|
||||||
|
|
||||||
EDNS0 is an extension mechanism for the DNS defined in RFC 2671 and updated by
|
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
|
RFC 6891. It defines a new RR type, the OPT RR, which is then completely
|
||||||
|
@ -279,9 +279,9 @@ SIG(0)
|
||||||
|
|
||||||
From RFC 2931:
|
From RFC 2931:
|
||||||
|
|
||||||
SIG(0) provides protection for DNS transactions and requests ....
|
SIG(0) provides protection for DNS transactions and requests ....
|
||||||
... protection for glue records, DNS requests, protection for message headers
|
... protection for glue records, DNS requests, protection for message headers
|
||||||
on requests and responses, and protection of the overall integrity of a response.
|
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
|
It works like TSIG, except that SIG(0) uses public key cryptography, instead of
|
||||||
the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256,
|
the shared secret approach in TSIG. Supported algorithms: ECDSAP256SHA256,
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
//+build ignore
|
//go:build ignore
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
// types_generate.go is meant to run with go generate. It will use
|
// 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
|
// go/{importer,types} to track down all the RR struct types. Then for each type
|
||||||
|
|
9
edns.go
9
edns.go
|
@ -78,7 +78,10 @@ func (rr *OPT) String() string {
|
||||||
if rr.Do() {
|
if rr.Do() {
|
||||||
s += "flags: do; "
|
s += "flags: do; "
|
||||||
} else {
|
} 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()))
|
s += "udp: " + strconv.Itoa(int(rr.UDPSize()))
|
||||||
|
|
||||||
|
@ -98,6 +101,8 @@ func (rr *OPT) String() string {
|
||||||
s += "\n; SUBNET: " + o.String()
|
s += "\n; SUBNET: " + o.String()
|
||||||
case *EDNS0_COOKIE:
|
case *EDNS0_COOKIE:
|
||||||
s += "\n; COOKIE: " + o.String()
|
s += "\n; COOKIE: " + o.String()
|
||||||
|
case *EDNS0_EXPIRE:
|
||||||
|
s += "\n; EXPIRE: " + o.String()
|
||||||
case *EDNS0_TCP_KEEPALIVE:
|
case *EDNS0_TCP_KEEPALIVE:
|
||||||
s += "\n; KEEPALIVE: " + o.String()
|
s += "\n; KEEPALIVE: " + o.String()
|
||||||
case *EDNS0_UL:
|
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.Name = "."
|
||||||
// o.Hdr.Rrtype = dns.TypeOPT
|
// o.Hdr.Rrtype = dns.TypeOPT
|
||||||
// e := new(dns.EDNS0_SUBNET)
|
// 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.Family = 1 // 1 for IPv4 source address, 2 for IPv6
|
||||||
// e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6
|
// e.SourceNetmask = 32 // 32 for IPV4, 128 for IPv6
|
||||||
// e.SourceScope = 0
|
// e.SourceScope = 0
|
||||||
|
|
1
fuzz.go
1
fuzz.go
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build fuzz
|
||||||
// +build fuzz
|
// +build fuzz
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
|
@ -122,7 +122,7 @@ func Split(s string) []int {
|
||||||
}
|
}
|
||||||
|
|
||||||
// NextLabel returns the index of the start of the next label in the
|
// 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.
|
// The bool end is true when the end of the string has been reached.
|
||||||
// Also see PrevLabel.
|
// Also see PrevLabel.
|
||||||
func NextLabel(s string, offset int) (i int, end bool) {
|
func NextLabel(s string, offset int) (i int, end bool) {
|
||||||
|
|
|
@ -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
|
// +build !go1.11 !aix,!darwin,!dragonfly,!freebsd,!linux,!netbsd,!openbsd
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build go1.11 && (aix || darwin || dragonfly || freebsd || linux || netbsd || openbsd)
|
||||||
// +build go1.11
|
// +build go1.11
|
||||||
// +build aix darwin dragonfly freebsd linux netbsd openbsd
|
// +build aix darwin dragonfly freebsd linux netbsd openbsd
|
||||||
|
|
||||||
|
|
4
msg.go
4
msg.go
|
@ -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:
|
// 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 {
|
func (h *MsgHdr) String() string {
|
||||||
if h == nil {
|
if h == nil {
|
||||||
return "<nil> MsgHdr"
|
return "<nil> MsgHdr"
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
//+build ignore
|
//go:build ignore
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
// msg_generate.go is meant to run with go generate. It will use
|
// 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
|
// go/{importer,types} to track down all the RR struct types. Then for each type
|
||||||
|
|
|
@ -18,7 +18,7 @@ func TestRequestTruncateAnswer(t *testing.T) {
|
||||||
|
|
||||||
reply.Truncate(MinMsgSize)
|
reply.Truncate(MinMsgSize)
|
||||||
if want, got := MinMsgSize, reply.Len(); want < got {
|
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 {
|
if !reply.Truncated {
|
||||||
t.Errorf("truncated bit should be set")
|
t.Errorf("truncated bit should be set")
|
||||||
|
@ -38,7 +38,7 @@ func TestRequestTruncateExtra(t *testing.T) {
|
||||||
|
|
||||||
reply.Truncate(MinMsgSize)
|
reply.Truncate(MinMsgSize)
|
||||||
if want, got := MinMsgSize, reply.Len(); want < got {
|
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 {
|
if !reply.Truncated {
|
||||||
t.Errorf("truncated bit should be set")
|
t.Errorf("truncated bit should be set")
|
||||||
|
@ -62,7 +62,7 @@ func TestRequestTruncateExtraEdns0(t *testing.T) {
|
||||||
|
|
||||||
reply.Truncate(size)
|
reply.Truncate(size)
|
||||||
if want, got := size, reply.Len(); want < got {
|
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 {
|
if !reply.Truncated {
|
||||||
t.Errorf("truncated bit should be set")
|
t.Errorf("truncated bit should be set")
|
||||||
|
@ -94,7 +94,7 @@ func TestRequestTruncateExtraRegression(t *testing.T) {
|
||||||
|
|
||||||
reply.Truncate(size)
|
reply.Truncate(size)
|
||||||
if want, got := size, reply.Len(); want < got {
|
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 {
|
if !reply.Truncated {
|
||||||
t.Errorf("truncated bit should be set")
|
t.Errorf("truncated bit should be set")
|
||||||
|
@ -130,7 +130,7 @@ func TestTruncation(t *testing.T) {
|
||||||
|
|
||||||
copy.Truncate(bufsize)
|
copy.Truncate(bufsize)
|
||||||
if want, got := bufsize, copy.Len(); want < got {
|
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)
|
reply.Truncate(size)
|
||||||
if want, got := size, reply.Len(); want < got {
|
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 {
|
if expected := 52; len(reply.Answer) != expected {
|
||||||
t.Errorf("wrong number of answers; expected %d, got %d", expected, len(reply.Answer))
|
t.Errorf("wrong number of answers; expected %d, got %d", expected, len(reply.Answer))
|
||||||
|
|
|
@ -373,10 +373,10 @@ func TestNSEC(t *testing.T) {
|
||||||
func TestParseLOC(t *testing.T) {
|
func TestParseLOC(t *testing.T) {
|
||||||
lt := map[string]string{
|
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 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 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 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
|
// 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",
|
"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.
|
// 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",
|
"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",
|
"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
|
// 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. 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",
|
"t.example.com. CLASS255 A 127.0.0.1": "t.example.com. 3600 CLASS255 A 127.0.0.1",
|
||||||
}
|
}
|
||||||
for i, o := range tests {
|
for i, o := range tests {
|
||||||
|
@ -1515,10 +1515,10 @@ func TestParseSSHFP(t *testing.T) {
|
||||||
|
|
||||||
func TestParseHINFO(t *testing.T) {
|
func TestParseHINFO(t *testing.T) {
|
||||||
dt := map[string]string{
|
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\"": "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 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\"",
|
// "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
|
// 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
|
// 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) {
|
func TestParseCAA(t *testing.T) {
|
||||||
lt := map[string]string{
|
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 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. 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\"",
|
"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) {
|
func TestParseSVCB(t *testing.T) {
|
||||||
svcbs := map[string]string{
|
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. 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="\ "`,
|
`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,"
|
// 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.`,
|
`example.com. 3600 IN SVCB 0 no-default-alpn`: `example.com. 3600 IN SVCB 0 no-default-alpn.`,
|
||||||
// From the specification
|
// From the specification
|
||||||
`example.com. HTTPS 0 foo.example.com.`: `example.com. 3600 IN HTTPS 0 foo.example.com.`,
|
`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 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 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`: `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. 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 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 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=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\\\\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\\\092oo\092,bar,h2`: `example.com. 3600 IN SVCB 16 foo.example.org. alpn="f\\\092oo\\\044bar,h2"`,
|
||||||
// From draft-ietf-add-ddr-06
|
// 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}"`,
|
`_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 {
|
for s, o := range svcbs {
|
||||||
|
|
|
@ -18,7 +18,7 @@ import (
|
||||||
const maxTCPQueries = 128
|
const maxTCPQueries = 128
|
||||||
|
|
||||||
// aLongTimeAgo is a non-zero time, far in the past, used for
|
// 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)
|
var aLongTimeAgo = time.Unix(1, 0)
|
||||||
|
|
||||||
// Handler is implemented by any value that implements ServeDNS.
|
// Handler is implemented by any value that implements ServeDNS.
|
||||||
|
|
16
svcb.go
16
svcb.go
|
@ -353,7 +353,7 @@ func (*SVCBAlpn) Key() SVCBKey { return SVCB_ALPN }
|
||||||
func (s *SVCBAlpn) String() string {
|
func (s *SVCBAlpn) String() string {
|
||||||
// An ALPN value is a comma-separated list of values, each of which can be
|
// 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
|
// 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
|
// However, this escaping is done in addition to the normal escaping which
|
||||||
// happens in zone files, meaning that these values must be
|
// 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.
|
// to the hinted IP address may be terminated and a new connection may be opened.
|
||||||
// Basic use pattern for creating an ipv4hint option:
|
// Basic use pattern for creating an ipv4hint option:
|
||||||
//
|
//
|
||||||
// h := new(dns.HTTPS)
|
// h := new(dns.HTTPS)
|
||||||
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
// h.Hdr = dns.RR_Header{Name: ".", Rrtype: dns.TypeHTTPS, Class: dns.ClassINET}
|
||||||
// e := new(dns.SVCBIPv4Hint)
|
// e := new(dns.SVCBIPv4Hint)
|
||||||
// e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()}
|
// e.Hint = []net.IP{net.IPv4(1,1,1,1).To4()}
|
||||||
//
|
//
|
||||||
// Or
|
// Or
|
||||||
//
|
//
|
||||||
// e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
|
// e.Hint = []net.IP{net.ParseIP("1.1.1.1").To4()}
|
||||||
// h.Value = append(h.Value, e)
|
// h.Value = append(h.Value, e)
|
||||||
type SVCBIPv4Hint struct {
|
type SVCBIPv4Hint struct {
|
||||||
Hint []net.IP
|
Hint []net.IP
|
||||||
}
|
}
|
||||||
|
|
1
tools.go
1
tools.go
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build tools
|
||||||
// +build tools
|
// +build tools
|
||||||
|
|
||||||
// We include our tool dependencies for `go generate` here to ensure they're
|
// We include our tool dependencies for `go generate` here to ensure they're
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
//+build ignore
|
//go:build ignore
|
||||||
|
// +build ignore
|
||||||
|
|
||||||
// types_generate.go is meant to run with go generate. It will use
|
// 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
|
// go/{importer,types} to track down all the RR struct types. Then for each type
|
||||||
|
|
1
udp.go
1
udp.go
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build !windows
|
||||||
// +build !windows
|
// +build !windows
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build linux && !appengine
|
||||||
// +build linux,!appengine
|
// +build linux,!appengine
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
//go:build windows
|
||||||
// +build windows
|
// +build windows
|
||||||
|
|
||||||
package dns
|
package dns
|
||||||
|
|
|
@ -92,7 +92,7 @@ func TestRemoveRRset(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPreReqAndRemovals(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.
|
// We should be able to add multiple prereqs and updates.
|
||||||
m := new(Msg)
|
m := new(Msg)
|
||||||
m.SetUpdate("example.org.")
|
m.SetUpdate("example.org.")
|
||||||
|
|
1
xfr.go
1
xfr.go
|
@ -44,7 +44,6 @@ func (t *Transfer) tsigProvider() TsigProvider {
|
||||||
// dnscon := &dns.Conn{Conn:con}
|
// dnscon := &dns.Conn{Conn:con}
|
||||||
// transfer = &dns.Transfer{Conn: dnscon}
|
// transfer = &dns.Transfer{Conn: dnscon}
|
||||||
// channel, err := transfer.In(message, master)
|
// channel, err := transfer.In(message, master)
|
||||||
//
|
|
||||||
func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
|
func (t *Transfer) In(q *Msg, a string) (env chan *Envelope, err error) {
|
||||||
switch q.Question[0].Qtype {
|
switch q.Question[0].Qtype {
|
||||||
case TypeAXFR, TypeIXFR:
|
case TypeAXFR, TypeIXFR:
|
||||||
|
|
Loading…
Reference in New Issue