Compare commits

...

16 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
Miek Gieben b3dfea0715 Release 1.1.50 2022-06-21 10:38:26 +02:00
Miek Gieben 69924a02cf
Make tsigGenerateProvider/TsigVerifyProvider public (#1382)
Make it public as TsigGenerateWithProvider and update the docs a little.
And TsigVerifyWithProvider also - tweak those docs also a little.

Signed-off-by: Miek Gieben <miek@miek.nl>
2022-06-21 10:37:36 +02:00
João Oliveirinha ff611cdc4b
Add back support for *net.UnixCon with seqpacket type (#1378)
This was broken by PR: https://github.com/miekg/dns/pull/1322
2022-06-08 14:03:24 +02:00
Miek Gieben eb4745b695
Add more detail to NSEC packing errors (#1374)
Add 'in the type bitmap' to make clear where in the RR the error occurs.
Also use 'NSEC(3)' - as this code is shared between NSEC and NSEC3, the
first error used NSECx.

Technically backwards incompatible, but checking strings in errors as
bad practice (although this lib lacks library types).

See #1373

Signed-off-by: Miek Gieben <miek@miek.nl>
2022-05-27 11:01:25 +02:00
Shane Kerr 7413c83334
Disallow names that start with '.' in IsDomainName() (#1376)
* Disallow names that start with '.' in IsDomainName()

* Also update packDomain()
2022-05-26 15:06:08 +02:00
35 changed files with 216 additions and 153 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

@ -24,7 +24,7 @@ func isPacketConn(c net.Conn) bool {
}
if ua, ok := c.LocalAddr().(*net.UnixAddr); ok {
return ua.Net == "unixgram"
return ua.Net == "unixgram" || ua.Net == "unixpacket"
}
return true
@ -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)
})
@ -280,7 +280,7 @@ func (co *Conn) ReadMsg() (*Msg, error) {
}
if t := m.IsTsig(); t != nil {
// Need to work on the original message p, as that was used to calculate the tsig.
err = tsigVerifyProvider(p, co.tsigProvider(), co.tsigRequestMAC, false)
err = TsigVerifyWithProvider(p, co.tsigProvider(), co.tsigRequestMAC, false)
}
return m, err
}
@ -358,7 +358,7 @@ func (co *Conn) WriteMsg(m *Msg) (err error) {
var out []byte
if t := m.IsTsig(); t != nil {
// Set tsigRequestMAC for the next read, although only used in zone transfers.
out, co.tsigRequestMAC, err = tsigGenerateProvider(m, co.tsigProvider(), co.tsigRequestMAC, false)
out, co.tsigRequestMAC, err = TsigGenerateWithProvider(m, co.tsigProvider(), co.tsigRequestMAC, false)
} else {
out, err = m.Pack()
}
@ -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

@ -68,6 +68,27 @@ func TestIsPacketConn(t *testing.T) {
t.Error("Unix datagram connection (wrapped type) should be a packet conn")
}
// Unix Seqpacket
shutChan, addrstr, err := RunLocalUnixSeqPacketServer(filepath.Join(t.TempDir(), "unixpacket.sock"))
if err != nil {
t.Fatalf("unable to run test server: %v", err)
}
defer func() {
shutChan <- &struct{}{}
}()
c, err = net.Dial("unixpacket", addrstr)
if err != nil {
t.Fatalf("failed to dial: %v", err)
}
defer c.Close()
if !isPacketConn(c) {
t.Error("Unix datagram connection should be a packet conn")
}
if !isPacketConn(struct{ *net.UnixConn }{c.(*net.UnixConn)}) {
t.Error("Unix datagram connection (wrapped type) should be a packet conn")
}
// Unix stream
s, addrstr, _, err = RunLocalUnixServer(filepath.Join(t.TempDir(), "unixstream.sock"))
if err != nil {

View File

@ -218,6 +218,11 @@ func IsDomainName(s string) (labels int, ok bool) {
wasDot = false
case '.':
if i == 0 && len(s) > 1 {
// leading dots are not legal except for the root zone
return labels, false
}
if wasDot {
// two dots back to back is not legal
return labels, false

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

@ -176,7 +176,10 @@ func TestIsDomainName(t *testing.T) {
lab int
}
names := map[string]*ret{
"..": {false, 1},
".": {true, 1},
"..": {false, 0},
"double-dot..test": {false, 1},
".leading-dot.test": {false, 0},
"@.": {true, 1},
"www.example.com": {true, 3},
"www.e%ample.com": {true, 3},

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

9
msg.go
View File

@ -265,6 +265,11 @@ loop:
wasDot = false
case '.':
if i == 0 && len(s) > 1 {
// leading dots are not legal except for the root zone
return len(msg), ErrRdata
}
if wasDot {
// two dots back to back is not legal
return len(msg), ErrRdata
@ -675,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

@ -476,7 +476,7 @@ func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
length, window, lastwindow := 0, 0, -1
for off < len(msg) {
if off+2 > len(msg) {
return nsec, len(msg), &Error{err: "overflow unpacking nsecx"}
return nsec, len(msg), &Error{err: "overflow unpacking NSEC(3)"}
}
window = int(msg[off])
length = int(msg[off+1])
@ -484,17 +484,17 @@ func unpackDataNsec(msg []byte, off int) ([]uint16, int, error) {
if window <= lastwindow {
// RFC 4034: Blocks are present in the NSEC RR RDATA in
// increasing numerical order.
return nsec, len(msg), &Error{err: "out of order NSEC block"}
return nsec, len(msg), &Error{err: "out of order NSEC(3) block in type bitmap"}
}
if length == 0 {
// RFC 4034: Blocks with no types present MUST NOT be included.
return nsec, len(msg), &Error{err: "empty NSEC block"}
return nsec, len(msg), &Error{err: "empty NSEC(3) block in type bitmap"}
}
if length > 32 {
return nsec, len(msg), &Error{err: "NSEC block too long"}
return nsec, len(msg), &Error{err: "NSEC(3) block too long in type bitmap"}
}
if off+length > len(msg) {
return nsec, len(msg), &Error{err: "overflowing NSEC block"}
return nsec, len(msg), &Error{err: "overflowing NSEC(3) block in type bitmap"}
}
// Walk the bytes in the window and extract the type bits

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.
@ -646,7 +646,7 @@ func (srv *Server) serveDNS(m []byte, w *response) {
w.tsigStatus = nil
if w.tsigProvider != nil {
if t := req.IsTsig(); t != nil {
w.tsigStatus = tsigVerifyProvider(m, w.tsigProvider, "", false)
w.tsigStatus = TsigVerifyWithProvider(m, w.tsigProvider, "", false)
w.tsigTimersOnly = false
w.tsigRequestMAC = t.MAC
}
@ -728,7 +728,7 @@ func (w *response) WriteMsg(m *Msg) (err error) {
var data []byte
if w.tsigProvider != nil { // if no provider, dont check for the tsig (which is a longer check)
if t := m.IsTsig(); t != nil {
data, w.tsigRequestMAC, err = tsigGenerateProvider(m, w.tsigProvider, w.tsigRequestMAC, w.tsigTimersOnly)
data, w.tsigRequestMAC, err = TsigGenerateWithProvider(m, w.tsigProvider, w.tsigRequestMAC, w.tsigTimersOnly)
if err != nil {
return err
}

View File

@ -159,6 +159,21 @@ func RunLocalUnixGramServer(laddr string, opts ...func(*Server)) (*Server, strin
return RunLocalServer(pc, nil, opts...)
}
func RunLocalUnixSeqPacketServer(laddr string) (chan interface{}, string, error) {
pc, err := net.Listen("unixpacket", laddr)
if err != nil {
return nil, "", err
}
shutdownChan := make(chan interface{})
go func() {
pc.Accept()
<-shutdownChan
}()
return shutdownChan, pc.Addr().String(), nil
}
func TestServing(t *testing.T) {
for _, tc := range []struct {
name string

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

26
tsig.go
View File

@ -158,18 +158,17 @@ type timerWireFmt struct {
}
// TsigGenerate fills out the TSIG record attached to the message.
// The message should contain
// a "stub" TSIG RR with the algorithm, key name (owner name of the RR),
// time fudge (defaults to 300 seconds) and the current time
// The TSIG MAC is saved in that Tsig RR.
// When TsigGenerate is called for the first time requestMAC is set to the empty string and
// timersOnly is false.
// If something goes wrong an error is returned, otherwise it is nil.
// The message should contain a "stub" TSIG RR with the algorithm, key name
// (owner name of the RR), time fudge (defaults to 300 seconds) and the current
// time The TSIG MAC is saved in that Tsig RR. When TsigGenerate is called for
// the first time requestMAC should be set to the empty string and timersOnly to
// false.
func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, string, error) {
return tsigGenerateProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
return TsigGenerateWithProvider(m, tsigHMACProvider(secret), requestMAC, timersOnly)
}
func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) {
// TsigGenerateWithProvider is similar to TsigGenerate, but allows for a custom TsigProvider.
func TsigGenerateWithProvider(m *Msg, provider TsigProvider, requestMAC string, timersOnly bool) ([]byte, string, error) {
if m.IsTsig() == nil {
panic("dns: TSIG not last RR in additional")
}
@ -216,14 +215,15 @@ func tsigGenerateProvider(m *Msg, provider TsigProvider, requestMAC string, time
return mbuf, t.MAC, nil
}
// TsigVerify verifies the TSIG on a message.
// If the signature does not validate err contains the
// error, otherwise it is nil.
// TsigVerify verifies the TSIG on a message. If the signature does not
// validate the returned error contains the cause. If the signature is OK, the
// error is nil.
func TsigVerify(msg []byte, secret, requestMAC string, timersOnly bool) error {
return tsigVerify(msg, tsigHMACProvider(secret), requestMAC, timersOnly, uint64(time.Now().Unix()))
}
func tsigVerifyProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
// TsigVerifyWithProvider is similar to TsigVerify, but allows for a custom TsigProvider.
func TsigVerifyWithProvider(msg []byte, provider TsigProvider, requestMAC string, timersOnly bool) error {
return tsigVerify(msg, provider, requestMAC, timersOnly, uint64(time.Now().Unix()))
}

View File

@ -354,7 +354,7 @@ func TestTsigGenerateProvider(t *testing.T) {
Extra: []RR{&tsig},
}
_, mac, err := tsigGenerateProvider(req, new(testProvider), "", false)
_, mac, err := TsigGenerateWithProvider(req, new(testProvider), "", false)
if err != table.err {
t.Fatalf("error doesn't match: expected '%s' but got '%s'", table.err, err)
}
@ -397,7 +397,7 @@ func TestTsigVerifyProvider(t *testing.T) {
}
provider := &testProvider{true}
msgData, _, err := tsigGenerateProvider(req, provider, "", false)
msgData, _, err := TsigGenerateWithProvider(req, provider, "", false)
if err != nil {
t.Error(err)
}

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.")

View File

@ -3,7 +3,7 @@ package dns
import "fmt"
// Version is current version of this library.
var Version = v{1, 1, 49}
var Version = v{1, 1, 50}
// v holds the version of this library.
type v struct {

5
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:
@ -237,7 +236,7 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
}
if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
// Need to work on the original message p, as that was used to calculate the tsig.
err = tsigVerifyProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly)
err = TsigVerifyWithProvider(p, tp, t.tsigRequestMAC, t.tsigTimersOnly)
t.tsigRequestMAC = ts.MAC
}
return m, err
@ -247,7 +246,7 @@ func (t *Transfer) ReadMsg() (*Msg, error) {
func (t *Transfer) WriteMsg(m *Msg) (err error) {
var out []byte
if ts, tp := m.IsTsig(), t.tsigProvider(); ts != nil && tp != nil {
out, t.tsigRequestMAC, err = tsigGenerateProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly)
out, t.tsigRequestMAC, err = TsigGenerateWithProvider(m, tp, t.tsigRequestMAC, t.tsigTimersOnly)
} else {
out, err = m.Pack()
}