summaryrefslogtreecommitdiffstats
path: root/vendor/github.com/miekg/dns
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/miekg/dns')
-rw-r--r--vendor/github.com/miekg/dns/.travis.yml3
-rw-r--r--vendor/github.com/miekg/dns/Gopkg.lock4
-rw-r--r--vendor/github.com/miekg/dns/README.md3
-rw-r--r--vendor/github.com/miekg/dns/client.go33
-rw-r--r--vendor/github.com/miekg/dns/dnssec.go30
-rw-r--r--vendor/github.com/miekg/dns/dnssec_keyscan.go17
-rw-r--r--vendor/github.com/miekg/dns/dnssec_privkey.go2
-rw-r--r--vendor/github.com/miekg/dns/duplicate.go25
-rw-r--r--vendor/github.com/miekg/dns/duplicate_generate.go158
-rw-r--r--vendor/github.com/miekg/dns/edns.go8
-rw-r--r--vendor/github.com/miekg/dns/generate.go14
-rw-r--r--vendor/github.com/miekg/dns/labels.go4
-rw-r--r--vendor/github.com/miekg/dns/listen_go111.go43
-rw-r--r--vendor/github.com/miekg/dns/listen_go_not111.go23
-rw-r--r--vendor/github.com/miekg/dns/msg.go16
-rw-r--r--vendor/github.com/miekg/dns/msg_helpers.go8
-rw-r--r--vendor/github.com/miekg/dns/sanitize.go1
-rw-r--r--vendor/github.com/miekg/dns/scan_rr.go12
-rw-r--r--vendor/github.com/miekg/dns/server.go302
-rw-r--r--vendor/github.com/miekg/dns/types.go20
-rw-r--r--vendor/github.com/miekg/dns/udp.go2
-rw-r--r--vendor/github.com/miekg/dns/udp_windows.go37
-rw-r--r--vendor/github.com/miekg/dns/version.go2
-rw-r--r--vendor/github.com/miekg/dns/zcompress.go3
-rw-r--r--vendor/github.com/miekg/dns/zduplicate.go943
-rw-r--r--vendor/github.com/miekg/dns/zmsg.go2
26 files changed, 1503 insertions, 212 deletions
diff --git a/vendor/github.com/miekg/dns/.travis.yml b/vendor/github.com/miekg/dns/.travis.yml
index 542dd68c0..13e312b4f 100644
--- a/vendor/github.com/miekg/dns/.travis.yml
+++ b/vendor/github.com/miekg/dns/.travis.yml
@@ -1,7 +1,8 @@
language: go
sudo: false
go:
- - 1.9.x
+ - 1.10.x
+ - 1.11.x
- tip
env:
diff --git a/vendor/github.com/miekg/dns/Gopkg.lock b/vendor/github.com/miekg/dns/Gopkg.lock
index 0c73a6444..4455c9836 100644
--- a/vendor/github.com/miekg/dns/Gopkg.lock
+++ b/vendor/github.com/miekg/dns/Gopkg.lock
@@ -5,13 +5,13 @@
branch = "master"
name = "golang.org/x/crypto"
packages = ["ed25519","ed25519/internal/edwards25519"]
- revision = "b080dc9a8c480b08e698fb1219160d598526310f"
+ revision = "b47b1587369238182299fe4dad77d05b8b461e06"
[[projects]]
branch = "master"
name = "golang.org/x/net"
packages = ["bpf","internal/iana","internal/socket","ipv4","ipv6"]
- revision = "894f8ed5849b15b810ae41e9590a0d05395bba27"
+ revision = "1e491301e022f8f977054da4c2d852decd59571f"
[solve-meta]
analyzer-name = "dep"
diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md
index 1ad23c751..77874642b 100644
--- a/vendor/github.com/miekg/dns/README.md
+++ b/vendor/github.com/miekg/dns/README.md
@@ -64,6 +64,9 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://github.com/oif/apex
* https://github.com/jedisct1/dnscrypt-proxy
* https://github.com/jedisct1/rpdns
+* https://github.com/xor-gate/sshfp
+* https://github.com/rs/dnstrace
+* https://blitiri.com.ar/p/dnss ([github mirror](https://github.com/albertito/dnss))
Send pull request if you want to be listed here.
diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go
index dd6b512af..7a319b02c 100644
--- a/vendor/github.com/miekg/dns/client.go
+++ b/vendor/github.com/miekg/dns/client.go
@@ -89,32 +89,22 @@ func (c *Client) Dial(address string) (conn *Conn, err error) {
// create a new dialer with the appropriate timeout
var d net.Dialer
if c.Dialer == nil {
- d = net.Dialer{Timeout:c.getTimeoutForRequest(c.dialTimeout())}
+ d = net.Dialer{Timeout: c.getTimeoutForRequest(c.dialTimeout())}
} else {
- d = net.Dialer(*c.Dialer)
- }
-
- network := "udp"
- useTLS := false
-
- switch c.Net {
- case "tcp-tls":
- network = "tcp"
- useTLS = true
- case "tcp4-tls":
- network = "tcp4"
- useTLS = true
- case "tcp6-tls":
- network = "tcp6"
- useTLS = true
- default:
- if c.Net != "" {
- network = c.Net
- }
+ d = *c.Dialer
+ }
+
+ network := c.Net
+ if network == "" {
+ network = "udp"
}
+ useTLS := strings.HasPrefix(network, "tcp") && strings.HasSuffix(network, "-tls")
+
conn = new(Conn)
if useTLS {
+ network = strings.TrimSuffix(network, "-tls")
+
conn.Conn, err = tls.DialWithDialer(&d, network, address, c.TLSConfig)
} else {
conn.Conn, err = d.Dial(network, address)
@@ -122,6 +112,7 @@ func (c *Client) Dial(address string) (conn *Conn, err error) {
if err != nil {
return nil, err
}
+
return conn, nil
}
diff --git a/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/miekg/dns/dnssec.go
index 7e6bac428..26b512e7d 100644
--- a/vendor/github.com/miekg/dns/dnssec.go
+++ b/vendor/github.com/miekg/dns/dnssec.go
@@ -173,7 +173,7 @@ func (k *DNSKEY) KeyTag() uint16 {
keytag += int(v) << 8
}
}
- keytag += (keytag >> 16) & 0xFFFF
+ keytag += keytag >> 16 & 0xFFFF
keytag &= 0xFFFF
}
return uint16(keytag)
@@ -512,8 +512,8 @@ func (rr *RRSIG) ValidityPeriod(t time.Time) bool {
}
modi := (int64(rr.Inception) - utc) / year68
mode := (int64(rr.Expiration) - utc) / year68
- ti := int64(rr.Inception) + (modi * year68)
- te := int64(rr.Expiration) + (mode * year68)
+ ti := int64(rr.Inception) + modi*year68
+ te := int64(rr.Expiration) + mode*year68
return ti <= utc && utc <= te
}
@@ -533,6 +533,11 @@ func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
return nil
}
+ if len(keybuf) < 1+1+64 {
+ // Exponent must be at least 1 byte and modulus at least 64
+ return nil
+ }
+
// RFC 2537/3110, section 2. RSA Public KEY Resource Records
// Length is in the 0th byte, unless its zero, then it
// it in bytes 1 and 2 and its a 16 bit number
@@ -542,13 +547,22 @@ func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
explen = uint16(keybuf[1])<<8 | uint16(keybuf[2])
keyoff = 3
}
- if explen > 4 {
- // Larger exponent than supported by the crypto package.
+
+ if explen > 4 || explen == 0 || keybuf[keyoff] == 0 {
+ // Exponent larger than supported by the crypto package,
+ // empty, or contains prohibited leading zero.
+ return nil
+ }
+
+ modoff := keyoff + int(explen)
+ modlen := len(keybuf) - modoff
+ if modlen < 64 || modlen > 512 || keybuf[modoff] == 0 {
+ // Modulus is too small, large, or contains prohibited leading zero.
return nil
}
+
pubkey := new(rsa.PublicKey)
- pubkey.N = big.NewInt(0)
expo := uint64(0)
for i := 0; i < int(explen); i++ {
expo <<= 8
@@ -560,7 +574,9 @@ func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
}
pubkey.E = int(expo)
- pubkey.N.SetBytes(keybuf[keyoff+int(explen):])
+ pubkey.N = big.NewInt(0)
+ pubkey.N.SetBytes(keybuf[modoff:])
+
return pubkey
}
diff --git a/vendor/github.com/miekg/dns/dnssec_keyscan.go b/vendor/github.com/miekg/dns/dnssec_keyscan.go
index e2d9d8f92..719198659 100644
--- a/vendor/github.com/miekg/dns/dnssec_keyscan.go
+++ b/vendor/github.com/miekg/dns/dnssec_keyscan.go
@@ -1,7 +1,6 @@
package dns
import (
- "bytes"
"crypto"
"crypto/dsa"
"crypto/ecdsa"
@@ -181,22 +180,10 @@ func readPrivateKeyED25519(m map[string]string) (ed25519.PrivateKey, error) {
if err != nil {
return nil, err
}
- if len(p1) != 32 {
+ if len(p1) != ed25519.SeedSize {
return nil, ErrPrivKey
}
- // RFC 8080 and Golang's x/crypto/ed25519 differ as to how the
- // private keys are represented. RFC 8080 specifies that private
- // keys be stored solely as the seed value (p1 above) while the
- // ed25519 package represents them as the seed value concatenated
- // to the public key, which is derived from the seed value.
- //
- // ed25519.GenerateKey reads exactly 32 bytes from the passed in
- // io.Reader and uses them as the seed. It also derives the
- // public key and produces a compatible private key.
- _, p, err = ed25519.GenerateKey(bytes.NewReader(p1))
- if err != nil {
- return nil, err
- }
+ p = ed25519.NewKeyFromSeed(p1)
case "created", "publish", "activate":
/* not used in Go (yet) */
}
diff --git a/vendor/github.com/miekg/dns/dnssec_privkey.go b/vendor/github.com/miekg/dns/dnssec_privkey.go
index 46f3215c8..0c65be17b 100644
--- a/vendor/github.com/miekg/dns/dnssec_privkey.go
+++ b/vendor/github.com/miekg/dns/dnssec_privkey.go
@@ -82,7 +82,7 @@ func (r *DNSKEY) PrivateKeyString(p crypto.PrivateKey) string {
"Public_value(y): " + pub + "\n"
case ed25519.PrivateKey:
- private := toBase64(p[:32])
+ private := toBase64(p.Seed())
return format +
"Algorithm: " + algorithm + "\n" +
"PrivateKey: " + private + "\n"
diff --git a/vendor/github.com/miekg/dns/duplicate.go b/vendor/github.com/miekg/dns/duplicate.go
new file mode 100644
index 000000000..6372e8a19
--- /dev/null
+++ b/vendor/github.com/miekg/dns/duplicate.go
@@ -0,0 +1,25 @@
+package dns
+
+//go:generate go run duplicate_generate.go
+
+// IsDuplicate checks of r1 and r2 are duplicates of each other, excluding the TTL.
+// So this means the header data is equal *and* the RDATA is the same. Return true
+// is so, otherwise false.
+// It's is a protocol violation to have identical RRs in a message.
+func IsDuplicate(r1, r2 RR) bool {
+ if r1.Header().Class != r2.Header().Class {
+ return false
+ }
+ if r1.Header().Rrtype != r2.Header().Rrtype {
+ return false
+ }
+ if !isDulicateName(r1.Header().Name, r2.Header().Name) {
+ return false
+ }
+ // ignore TTL
+
+ return isDuplicateRdata(r1, r2)
+}
+
+// isDulicateName checks if the domain names s1 and s2 are equal.
+func isDulicateName(s1, s2 string) bool { return equal(s1, s2) }
diff --git a/vendor/github.com/miekg/dns/duplicate_generate.go b/vendor/github.com/miekg/dns/duplicate_generate.go
new file mode 100644
index 000000000..83ac1cf77
--- /dev/null
+++ b/vendor/github.com/miekg/dns/duplicate_generate.go
@@ -0,0 +1,158 @@
+//+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
+// it will generate conversion tables (TypeToRR and TypeToString) and banal
+// methods (len, Header, copy) based on the struct tags. The generated source is
+// written to ztypes.go, and is meant to be checked into git.
+package main
+
+import (
+ "bytes"
+ "fmt"
+ "go/format"
+ "go/importer"
+ "go/types"
+ "log"
+ "os"
+)
+
+var packageHdr = `
+// Code generated by "go run duplicate_generate.go"; DO NOT EDIT.
+
+package dns
+
+`
+
+func getTypeStruct(t types.Type, scope *types.Scope) (*types.Struct, bool) {
+ st, ok := t.Underlying().(*types.Struct)
+ if !ok {
+ return nil, false
+ }
+ if st.Field(0).Type() == scope.Lookup("RR_Header").Type() {
+ return st, false
+ }
+ if st.Field(0).Anonymous() {
+ st, _ := getTypeStruct(st.Field(0).Type(), scope)
+ return st, true
+ }
+ return nil, false
+}
+
+func main() {
+ // Import and type-check the package
+ pkg, err := importer.Default().Import("github.com/miekg/dns")
+ fatalIfErr(err)
+ scope := pkg.Scope()
+
+ // Collect actual types (*X)
+ var namedTypes []string
+ for _, name := range scope.Names() {
+ o := scope.Lookup(name)
+ if o == nil || !o.Exported() {
+ continue
+ }
+
+ if st, _ := getTypeStruct(o.Type(), scope); st == nil {
+ continue
+ }
+
+ if name == "PrivateRR" || name == "RFC3597" {
+ continue
+ }
+ if name == "OPT" || name == "ANY" || name == "IXFR" || name == "AXFR" {
+ continue
+ }
+
+ namedTypes = append(namedTypes, o.Name())
+ }
+
+ b := &bytes.Buffer{}
+ b.WriteString(packageHdr)
+
+ // Generate the giant switch that calls the correct function for each type.
+ fmt.Fprint(b, "// isDuplicateRdata calls the rdata specific functions\n")
+ fmt.Fprint(b, "func isDuplicateRdata(r1, r2 RR) bool {\n")
+ fmt.Fprint(b, "switch r1.Header().Rrtype {\n")
+
+ for _, name := range namedTypes {
+
+ o := scope.Lookup(name)
+ _, isEmbedded := getTypeStruct(o.Type(), scope)
+ if isEmbedded {
+ continue
+ }
+ fmt.Fprintf(b, "case Type%s:\nreturn isDuplicate%s(r1.(*%s), r2.(*%s))\n", name, name, name, name)
+ }
+ fmt.Fprintf(b, "}\nreturn false\n}\n")
+
+ // Generate the duplicate check for each type.
+ fmt.Fprint(b, "// isDuplicate() functions\n\n")
+ for _, name := range namedTypes {
+
+ o := scope.Lookup(name)
+ st, isEmbedded := getTypeStruct(o.Type(), scope)
+ if isEmbedded {
+ continue
+ }
+ fmt.Fprintf(b, "func isDuplicate%s(r1, r2 *%s) bool {\n", name, name)
+ for i := 1; i < st.NumFields(); i++ {
+ field := st.Field(i).Name()
+ o2 := func(s string) { fmt.Fprintf(b, s+"\n", field, field) }
+ o3 := func(s string) { fmt.Fprintf(b, s+"\n", field, field, field) }
+
+ // For some reason, a and aaaa don't pop up as *types.Slice here (mostly like because the are
+ // *indirectly* defined as a slice in the net package).
+ if _, ok := st.Field(i).Type().(*types.Slice); ok || st.Tag(i) == `dns:"a"` || st.Tag(i) == `dns:"aaaa"` {
+ o2("if len(r1.%s) != len(r2.%s) {\nreturn false\n}")
+
+ if st.Tag(i) == `dns:"cdomain-name"` || st.Tag(i) == `dns:"domain-name"` {
+ o3(`for i := 0; i < len(r1.%s); i++ {
+ if !isDulicateName(r1.%s[i], r2.%s[i]) {
+ return false
+ }
+ }`)
+
+ continue
+ }
+
+ o3(`for i := 0; i < len(r1.%s); i++ {
+ if r1.%s[i] != r2.%s[i] {
+ return false
+ }
+ }`)
+
+ continue
+ }
+
+ switch st.Tag(i) {
+ case `dns:"-"`:
+ // ignored
+ case `dns:"cdomain-name"`, `dns:"domain-name"`:
+ o2("if !isDulicateName(r1.%s, r2.%s) {\nreturn false\n}")
+ default:
+ o2("if r1.%s != r2.%s {\nreturn false\n}")
+ }
+ }
+ fmt.Fprintf(b, "return true\n}\n\n")
+ }
+
+ // gofmt
+ res, err := format.Source(b.Bytes())
+ if err != nil {
+ b.WriteTo(os.Stderr)
+ log.Fatal(err)
+ }
+
+ // write result
+ f, err := os.Create("zduplicate.go")
+ fatalIfErr(err)
+ defer f.Close()
+ f.Write(res)
+}
+
+func fatalIfErr(err error) {
+ if err != nil {
+ log.Fatal(err)
+ }
+}
diff --git a/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/miekg/dns/edns.go
index 55059eb14..18d054139 100644
--- a/vendor/github.com/miekg/dns/edns.go
+++ b/vendor/github.com/miekg/dns/edns.go
@@ -92,17 +92,17 @@ func (rr *OPT) len() int {
// Version returns the EDNS version used. Only zero is defined.
func (rr *OPT) Version() uint8 {
- return uint8((rr.Hdr.Ttl & 0x00FF0000) >> 16)
+ return uint8(rr.Hdr.Ttl & 0x00FF0000 >> 16)
}
// SetVersion sets the version of EDNS. This is usually zero.
func (rr *OPT) SetVersion(v uint8) {
- rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | (uint32(v) << 16)
+ rr.Hdr.Ttl = rr.Hdr.Ttl&0xFF00FFFF | uint32(v)<<16
}
// ExtendedRcode returns the EDNS extended RCODE field (the upper 8 bits of the TTL).
func (rr *OPT) ExtendedRcode() int {
- return int((rr.Hdr.Ttl&0xFF000000)>>24) + 15
+ return int(rr.Hdr.Ttl&0xFF000000>>24) + 15
}
// SetExtendedRcode sets the EDNS extended RCODE field.
@@ -110,7 +110,7 @@ func (rr *OPT) SetExtendedRcode(v uint8) {
if v < RcodeBadVers { // Smaller than 16.. Use the 4 bits you have!
return
}
- rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | (uint32(v-15) << 24)
+ rr.Hdr.Ttl = rr.Hdr.Ttl&0x00FFFFFF | uint32(v-15)<<24
}
// UDPSize returns the UDP buffer size.
diff --git a/vendor/github.com/miekg/dns/generate.go b/vendor/github.com/miekg/dns/generate.go
index e4481a4b0..3a559793f 100644
--- a/vendor/github.com/miekg/dns/generate.go
+++ b/vendor/github.com/miekg/dns/generate.go
@@ -133,10 +133,20 @@ BuildRR:
// Convert a $GENERATE modifier 0,0,d to something Printf can deal with.
func modToPrintf(s string) (string, int, error) {
- xs := strings.SplitN(s, ",", 3)
- if len(xs) != 3 {
+ xs := strings.Split(s, ",")
+
+ // Modifier is { offset [ ,width [ ,base ] ] } - provide default
+ // values for optional width and type, if necessary.
+ switch len(xs) {
+ case 1:
+ xs = append(xs, "0", "d")
+ case 2:
+ xs = append(xs, "d")
+ case 3:
+ default:
return "", 0, errors.New("bad modifier in $GENERATE")
}
+
// xs[0] is offset, xs[1] is width, xs[2] is base
if xs[2] != "o" && xs[2] != "d" && xs[2] != "x" && xs[2] != "X" {
return "", 0, errors.New("bad base in $GENERATE")
diff --git a/vendor/github.com/miekg/dns/labels.go b/vendor/github.com/miekg/dns/labels.go
index 760b89e71..577fc59d2 100644
--- a/vendor/github.com/miekg/dns/labels.go
+++ b/vendor/github.com/miekg/dns/labels.go
@@ -178,10 +178,10 @@ func equal(a, b string) bool {
ai := a[i]
bi := b[i]
if ai >= 'A' && ai <= 'Z' {
- ai |= ('a' - 'A')
+ ai |= 'a' - 'A'
}
if bi >= 'A' && bi <= 'Z' {
- bi |= ('a' - 'A')
+ bi |= 'a' - 'A'
}
if ai != bi {
return false
diff --git a/vendor/github.com/miekg/dns/listen_go111.go b/vendor/github.com/miekg/dns/listen_go111.go
new file mode 100644
index 000000000..bd024c893
--- /dev/null
+++ b/vendor/github.com/miekg/dns/listen_go111.go
@@ -0,0 +1,43 @@
+// +build go1.11,!windows
+
+package dns
+
+import (
+ "context"
+ "net"
+ "syscall"
+
+ "golang.org/x/sys/unix"
+)
+
+const supportsReusePort = true
+
+func reuseportControl(network, address string, c syscall.RawConn) error {
+ var opErr error
+ err := c.Control(func(fd uintptr) {
+ opErr = unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_REUSEPORT, 1)
+ })
+ if err != nil {
+ return err
+ }
+
+ return opErr
+}
+
+func listenTCP(network, addr string, reuseport bool) (net.Listener, error) {
+ var lc net.ListenConfig
+ if reuseport {
+ lc.Control = reuseportControl
+ }
+
+ return lc.Listen(context.Background(), network, addr)
+}
+
+func listenUDP(network, addr string, reuseport bool) (net.PacketConn, error) {
+ var lc net.ListenConfig
+ if reuseport {
+ lc.Control = reuseportControl
+ }
+
+ return lc.ListenPacket(context.Background(), network, addr)
+}
diff --git a/vendor/github.com/miekg/dns/listen_go_not111.go b/vendor/github.com/miekg/dns/listen_go_not111.go
new file mode 100644
index 000000000..f1fc652c4
--- /dev/null
+++ b/vendor/github.com/miekg/dns/listen_go_not111.go
@@ -0,0 +1,23 @@
+// +build !go1.11 windows
+
+package dns
+
+import "net"
+
+const supportsReusePort = false
+
+func listenTCP(network, addr string, reuseport bool) (net.Listener, error) {
+ if reuseport {
+ // TODO(tmthrgd): return an error?
+ }
+
+ return net.Listen(network, addr)
+}
+
+func listenUDP(network, addr string, reuseport bool) (net.PacketConn, error) {
+ if reuseport {
+ // TODO(tmthrgd): return an error?
+ }
+
+ return net.ListenPacket(network, addr)
+}
diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go
index dcd3b6a5e..f8b847650 100644
--- a/vendor/github.com/miekg/dns/msg.go
+++ b/vendor/github.com/miekg/dns/msg.go
@@ -808,15 +808,15 @@ func (dns *Msg) Unpack(msg []byte) (err error) {
}
dns.Id = dh.Id
- dns.Response = (dh.Bits & _QR) != 0
+ dns.Response = dh.Bits&_QR != 0
dns.Opcode = int(dh.Bits>>11) & 0xF
- dns.Authoritative = (dh.Bits & _AA) != 0
- dns.Truncated = (dh.Bits & _TC) != 0
- dns.RecursionDesired = (dh.Bits & _RD) != 0
- dns.RecursionAvailable = (dh.Bits & _RA) != 0
- dns.Zero = (dh.Bits & _Z) != 0
- dns.AuthenticatedData = (dh.Bits & _AD) != 0
- dns.CheckingDisabled = (dh.Bits & _CD) != 0
+ dns.Authoritative = dh.Bits&_AA != 0
+ dns.Truncated = dh.Bits&_TC != 0
+ dns.RecursionDesired = dh.Bits&_RD != 0
+ dns.RecursionAvailable = dh.Bits&_RA != 0
+ dns.Zero = dh.Bits&_Z != 0
+ dns.AuthenticatedData = dh.Bits&_AD != 0
+ dns.CheckingDisabled = dh.Bits&_CD != 0
dns.Rcode = int(dh.Bits & 0xF)
// If we are at the end of the message we should return *just* the
diff --git a/vendor/github.com/miekg/dns/msg_helpers.go b/vendor/github.com/miekg/dns/msg_helpers.go
index 4a6e878de..ec8cd9a85 100644
--- a/vendor/github.com/miekg/dns/msg_helpers.go
+++ b/vendor/github.com/miekg/dns/msg_helpers.go
@@ -223,8 +223,8 @@ func unpackUint48(msg []byte, off int) (i uint64, off1 int, err error) {
return 0, len(msg), &Error{err: "overflow unpacking uint64 as uint48"}
}
// Used in TSIG where the last 48 bits are occupied, so for now, assume a uint48 (6 bytes)
- i = (uint64(uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 |
- uint64(msg[off+4])<<8 | uint64(msg[off+5])))
+ i = uint64(uint64(msg[off])<<40 | uint64(msg[off+1])<<32 | uint64(msg[off+2])<<24 | uint64(msg[off+3])<<16 |
+ uint64(msg[off+4])<<8 | uint64(msg[off+5]))
off += 6
return i, off, nil
}
@@ -363,7 +363,7 @@ func packStringHex(s string, msg []byte, off int) (int, error) {
if err != nil {
return len(msg), err
}
- if off+(len(h)) > len(msg) {
+ if off+len(h) > len(msg) {
return len(msg), &Error{err: "overflow packing hex"}
}
copy(msg[off:off+len(h)], h)
@@ -603,7 +603,7 @@ func packDataNsec(bitmap []uint16, msg []byte, off int) (int, error) {
// Setting the octets length
msg[off+1] = byte(length)
// Setting the bit value for the type in the right octet
- msg[off+1+int(length)] |= byte(1 << (7 - (t % 8)))
+ msg[off+1+int(length)] |= byte(1 << (7 - t%8))
lastwindow, lastlength = window, length
}
off += int(lastlength) + 2
diff --git a/vendor/github.com/miekg/dns/sanitize.go b/vendor/github.com/miekg/dns/sanitize.go
index c415bdd6c..cac15787a 100644
--- a/vendor/github.com/miekg/dns/sanitize.go
+++ b/vendor/github.com/miekg/dns/sanitize.go
@@ -5,6 +5,7 @@ package dns
// rrs.
// m is used to store the RRs temporary. If it is nil a new map will be allocated.
func Dedup(rrs []RR, m map[string]RR) []RR {
+
if m == nil {
m = make(map[string]RR)
}
diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go
index fb6f95d1d..67f884b0d 100644
--- a/vendor/github.com/miekg/dns/scan_rr.go
+++ b/vendor/github.com/miekg/dns/scan_rr.go
@@ -893,19 +893,19 @@ Altitude:
if !ok {
return nil, &ParseError{f, "bad LOC Size", l}, ""
}
- rr.Size = (e & 0x0f) | (m << 4 & 0xf0)
+ rr.Size = e&0x0f | m<<4&0xf0
case 1: // HorizPre
e, m, ok := stringToCm(l.token)
if !ok {
return nil, &ParseError{f, "bad LOC HorizPre", l}, ""
}
- rr.HorizPre = (e & 0x0f) | (m << 4 & 0xf0)
+ rr.HorizPre = e&0x0f | m<<4&0xf0
case 2: // VertPre
e, m, ok := stringToCm(l.token)
if !ok {
return nil, &ParseError{f, "bad LOC VertPre", l}, ""
}
- rr.VertPre = (e & 0x0f) | (m << 4 & 0xf0)
+ rr.VertPre = e&0x0f | m<<4&0xf0
}
count++
case zBlank:
@@ -1665,9 +1665,9 @@ func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return nil, &ParseError{f, "bad TA DigestType", l}, ""
}
rr.DigestType = uint8(i)
- s, e, c1 := endingToString(c, "bad TA Digest", f)
- if e != nil {
- return nil, e.(*ParseError), c1
+ s, err, c1 := endingToString(c, "bad TA Digest", f)
+ if err != nil {
+ return nil, err, c1
}
rr.Digest = s
return rr, nil, c1
diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go
index 2d98f1488..2901f8724 100644
--- a/vendor/github.com/miekg/dns/server.go
+++ b/vendor/github.com/miekg/dns/server.go
@@ -4,10 +4,13 @@ package dns
import (
"bytes"
+ "context"
"crypto/tls"
"encoding/binary"
+ "errors"
"io"
"net"
+ "strings"
"sync"
"sync/atomic"
"time"
@@ -16,11 +19,22 @@ import (
// Default maximum number of TCP queries before we close the socket.
const maxTCPQueries = 128
-// Interval for stop worker if no load
+// The maximum number of idle workers.
+//
+// This controls the maximum number of workers that are allowed to stay
+// idle waiting for incoming requests before being torn down.
+//
+// If this limit is reached, the server will just keep spawning new
+// workers (goroutines) for each incoming request. In this case, each
+// worker will only be used for a single request.
+const maxIdleWorkersCount = 10000
+
+// The maximum length of time a worker may idle for before being destroyed.
const idleWorkerTimeout = 10 * time.Second
-// Maximum number of workers
-const maxWorkersCount = 10000
+// aLongTimeAgo is a non-zero time, far in the past, used for
+// immediate cancelation of network operations.
+var aLongTimeAgo = time.Unix(1, 0)
// Handler is implemented by any value that implements ServeDNS.
type Handler interface {
@@ -49,6 +63,12 @@ type ResponseWriter interface {
Hijack()
}
+// A ConnectionStater interface is used by a DNS Handler to access TLS connection state
+// when available.
+type ConnectionStater interface {
+ ConnectionState() *tls.ConnectionState
+}
+
type response struct {
msg []byte
hijacked bool // connection has been hijacked by handler
@@ -60,6 +80,7 @@ type response struct {
tcp net.Conn // i/o connection if TCP was used
udpSession *SessionUDP // oob data to get egress interface right
writer Writer // writer to output the raw DNS bits
+ wg *sync.WaitGroup // for gracefull shutdown
}
// ServeMux is an DNS request multiplexer. It matches the
@@ -151,7 +172,7 @@ func (mux *ServeMux) match(q string, t uint16) Handler {
for i := 0; i < l; i++ {
b[i] = q[off+i]
if b[i] >= 'A' && b[i] <= 'Z' {
- b[i] |= ('a' - 'A')
+ b[i] |= 'a' - 'A'
}
}
if h, ok := mux.z[string(b[:l])]; ok { // causes garbage, might want to change the map key
@@ -305,14 +326,30 @@ type Server struct {
DecorateWriter DecorateWriter
// Maximum number of TCP queries before we close the socket. Default is maxTCPQueries (unlimited if -1).
MaxTCPQueries int
+ // Whether to set the SO_REUSEPORT socket option, allowing multiple listeners to be bound to a single address.
+ // It is only supported on go1.11+ and when using ListenAndServe.
+ ReusePort bool
// UDP packet or TCP connection queue
queue chan *response
// Workers count
workersCount int32
+
// Shutdown handling
- lock sync.RWMutex
- started bool
+ lock sync.RWMutex
+ started bool
+ shutdown chan struct{}
+ conns map[net.Conn]struct{}
+
+ // A pool for UDP message buffers.
+ udpPool sync.Pool
+}
+
+func (srv *Server) isStarted() bool {
+ srv.lock.RLock()
+ started := srv.started
+ srv.lock.RUnlock()
+ return started
}
func (srv *Server) worker(w *response) {
@@ -320,7 +357,7 @@ func (srv *Server) worker(w *response) {
for {
count := atomic.LoadInt32(&srv.workersCount)
- if count > maxWorkersCount {
+ if count > maxIdleWorkersCount {
return
}
if atomic.CompareAndSwapInt32(&srv.workersCount, count, count+1) {
@@ -360,10 +397,36 @@ func (srv *Server) spawnWorker(w *response) {
}
}
+func makeUDPBuffer(size int) func() interface{} {
+ return func() interface{} {
+ return make([]byte, size)
+ }
+}
+
+func (srv *Server) init() {
+ srv.queue = make(chan *response)
+
+ srv.shutdown = make(chan struct{})
+ srv.conns = make(map[net.Conn]struct{})
+
+ if srv.UDPSize == 0 {
+ srv.UDPSize = MinMsgSize
+ }
+
+ srv.udpPool.New = makeUDPBuffer(srv.UDPSize)
+}
+
+func unlockOnce(l sync.Locker) func() {
+ var once sync.Once
+ return func() { once.Do(l.Unlock) }
+}
+
// ListenAndServe starts a nameserver on the configured address in *Server.
func (srv *Server) ListenAndServe() error {
+ unlock := unlockOnce(&srv.lock)
srv.lock.Lock()
- defer srv.lock.Unlock()
+ defer unlock()
+
if srv.started {
return &Error{err: "server already started"}
}
@@ -372,63 +435,47 @@ func (srv *Server) ListenAndServe() error {
if addr == "" {
addr = ":domain"
}
- if srv.UDPSize == 0 {
- srv.UDPSize = MinMsgSize
- }
- srv.queue = make(chan *response)
+
+ srv.init()
defer close(srv.queue)
+
switch srv.Net {
case "tcp", "tcp4", "tcp6":
- a, err := net.ResolveTCPAddr(srv.Net, addr)
- if err != nil {
- return err
- }
- l, err := net.ListenTCP(srv.Net, a)
+ l, err := listenTCP(srv.Net, addr, srv.ReusePort)
if err != nil {
return err
}
srv.Listener = l
srv.started = true
- srv.lock.Unlock()
- err = srv.serveTCP(l)
- srv.lock.Lock() // to satisfy the defer at the top
- return err
+ unlock()
+ return srv.serveTCP(l)
case "tcp-tls", "tcp4-tls", "tcp6-tls":
- network := "tcp"
- if srv.Net == "tcp4-tls" {
- network = "tcp4"
- } else if srv.Net == "tcp6-tls" {
- network = "tcp6"
+ if srv.TLSConfig == nil || (len(srv.TLSConfig.Certificates) == 0 && srv.TLSConfig.GetCertificate == nil) {
+ return errors.New("dns: neither Certificates nor GetCertificate set in Config")
}
-
- l, err := tls.Listen(network, addr, srv.TLSConfig)
+ network := strings.TrimSuffix(srv.Net, "-tls")
+ l, err := listenTCP(network, addr, srv.ReusePort)
if err != nil {
return err
}
+ l = tls.NewListener(l, srv.TLSConfig)
srv.Listener = l
srv.started = true
- srv.lock.Unlock()
- err = srv.serveTCP(l)
- srv.lock.Lock() // to satisfy the defer at the top
- return err
+ unlock()
+ return srv.serveTCP(l)
case "udp", "udp4", "udp6":
- a, err := net.ResolveUDPAddr(srv.Net, addr)
- if err != nil {
- return err
- }
- l, err := net.ListenUDP(srv.Net, a)
+ l, err := listenUDP(srv.Net, addr, srv.ReusePort)
if err != nil {
return err
}
- if e := setUDPSocketOptions(l); e != nil {
+ u := l.(*net.UDPConn)
+ if e := setUDPSocketOptions(u); e != nil {
return e
}
srv.PacketConn = l
srv.started = true
- srv.lock.Unlock()
- err = srv.serveUDP(l)
- srv.lock.Lock() // to satisfy the defer at the top
- return err
+ unlock()
+ return srv.serveUDP(u)
}
return &Error{err: "bad network"}
}
@@ -436,20 +483,20 @@ func (srv *Server) ListenAndServe() error {
// ActivateAndServe starts a nameserver with the PacketConn or Listener
// configured in *Server. Its main use is to start a server from systemd.
func (srv *Server) ActivateAndServe() error {
+ unlock := unlockOnce(&srv.lock)
srv.lock.Lock()
- defer srv.lock.Unlock()
+ defer unlock()
+
if srv.started {
return &Error{err: "server already started"}
}
+ srv.init()
+ defer close(srv.queue)
+
pConn := srv.PacketConn
l := srv.Listener
- srv.queue = make(chan *response)
- defer close(srv.queue)
if pConn != nil {
- if srv.UDPSize == 0 {
- srv.UDPSize = MinMsgSize
- }
// Check PacketConn interface's type is valid and value
// is not nil
if t, ok := pConn.(*net.UDPConn); ok && t != nil {
@@ -457,18 +504,14 @@ func (srv *Server) ActivateAndServe() error {
return e
}
srv.started = true
- srv.lock.Unlock()
- e := srv.serveUDP(t)
- srv.lock.Lock() // to satisfy the defer at the top
- return e
+ unlock()
+ return srv.serveUDP(t)
}
}
if l != nil {
srv.started = true
- srv.lock.Unlock()
- e := srv.serveTCP(l)
- srv.lock.Lock() // to satisfy the defer at the top
- return e
+ unlock()
+ return srv.serveTCP(l)
}
return &Error{err: "bad listeners"}
}
@@ -476,23 +519,58 @@ func (srv *Server) ActivateAndServe() error {
// Shutdown shuts down a server. After a call to Shutdown, ListenAndServe and
// ActivateAndServe will return.
func (srv *Server) Shutdown() error {
+ return srv.ShutdownContext(context.Background())
+}
+
+// ShutdownContext shuts down a server. After a call to ShutdownContext,
+// ListenAndServe and ActivateAndServe will return.
+//
+// A context.Context may be passed to limit how long to wait for connections
+// to terminate.
+func (srv *Server) ShutdownContext(ctx context.Context) error {
srv.lock.Lock()
- if !srv.started {
- srv.lock.Unlock()
- return &Error{err: "server not started"}
- }
+ started := srv.started
srv.started = false
srv.lock.Unlock()
+ if !started {
+ return &Error{err: "server not started"}
+ }
+
if srv.PacketConn != nil {
- srv.PacketConn.Close()
+ srv.PacketConn.SetReadDeadline(aLongTimeAgo) // Unblock reads
}
+
if srv.Listener != nil {
srv.Listener.Close()
}
- return nil
+
+ srv.lock.Lock()
+ for rw := range srv.conns {
+ rw.SetReadDeadline(aLongTimeAgo) // Unblock reads
+ }
+ srv.lock.Unlock()
+
+ if testShutdownNotify != nil {
+ testShutdownNotify.Broadcast()
+ }
+
+ var ctxErr error
+ select {
+ case <-srv.shutdown:
+ case <-ctx.Done():
+ ctxErr = ctx.Err()
+ }
+
+ if srv.PacketConn != nil {
+ srv.PacketConn.Close()
+ }
+
+ return ctxErr
}
+var testShutdownNotify *sync.Cond
+
// getReadTimeout is a helper func to use system timeout if server did not intend to change it.
func (srv *Server) getReadTimeout() time.Duration {
rtimeout := dnsTimeout
@@ -510,22 +588,36 @@ func (srv *Server) serveTCP(l net.Listener) error {
srv.NotifyStartedFunc()
}
- for {
+ var wg sync.WaitGroup
+ defer func() {
+ wg.Wait()
+ close(srv.shutdown)
+ }()
+
+ for srv.isStarted() {
rw, err := l.Accept()
- srv.lock.RLock()
- if !srv.started {
- srv.lock.RUnlock()
- return nil
- }
- srv.lock.RUnlock()
if err != nil {
+ if !srv.isStarted() {
+ return nil
+ }
if neterr, ok := err.(net.Error); ok && neterr.Temporary() {
continue
}
return err
}
- srv.spawnWorker(&response{tsigSecret: srv.TsigSecret, tcp: rw})
+ srv.lock.Lock()
+ // Track the connection to allow unblocking reads on shutdown.
+ srv.conns[rw] = struct{}{}
+ srv.lock.Unlock()
+ wg.Add(1)
+ srv.spawnWorker(&response{
+ tsigSecret: srv.TsigSecret,
+ tcp: rw,
+ wg: &wg,
+ })
}
+
+ return nil
}
// serveUDP starts a UDP listener for the server.
@@ -541,27 +633,42 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
reader = srv.DecorateReader(reader)
}
+ var wg sync.WaitGroup
+ defer func() {
+ wg.Wait()
+ close(srv.shutdown)
+ }()
+
rtimeout := srv.getReadTimeout()
// deadline is not used here
- for {
+ for srv.isStarted() {
m, s, err := reader.ReadUDP(l, rtimeout)
- srv.lock.RLock()
- if !srv.started {
- srv.lock.RUnlock()
- return nil
- }
- srv.lock.RUnlock()
if err != nil {
+ if !srv.isStarted() {
+ return nil
+ }
if netErr, ok := err.(net.Error); ok && netErr.Temporary() {
continue
}
return err
}
if len(m) < headerSize {
+ if cap(m) == srv.UDPSize {
+ srv.udpPool.Put(m[:srv.UDPSize])
+ }
continue
}
- srv.spawnWorker(&response{msg: m, tsigSecret: srv.TsigSecret, udp: l, udpSession: s})
+ wg.Add(1)
+ srv.spawnWorker(&response{
+ msg: m,
+ tsigSecret: srv.TsigSecret,
+ udp: l,
+ udpSession: s,
+ wg: &wg,
+ })
}
+
+ return nil
}
func (srv *Server) serve(w *response) {
@@ -574,20 +681,28 @@ func (srv *Server) serve(w *response) {
if w.udp != nil {
// serve UDP
srv.serveDNS(w)
- return
- }
- reader := Reader(&defaultReader{srv})
- if srv.DecorateReader != nil {
- reader = srv.DecorateReader(reader)
+ w.wg.Done()
+ return
}
defer func() {
if !w.hijacked {
w.Close()
}
+
+ srv.lock.Lock()
+ delete(srv.conns, w.tcp)
+ srv.lock.Unlock()
+
+ w.wg.Done()
}()
+ reader := Reader(&defaultReader{srv})
+ if srv.DecorateReader != nil {
+ reader = srv.DecorateReader(reader)
+ }
+
idleTimeout := tcpIdleTimeout
if srv.IdleTimeout != nil {
idleTimeout = srv.IdleTimeout()
@@ -600,7 +715,7 @@ func (srv *Server) serve(w *response) {
limit = maxTCPQueries
}
- for q := 0; q < limit || limit == -1; q++ {
+ for q := 0; (q < limit || limit == -1) && srv.isStarted(); q++ {
var err error
w.msg, err = reader.ReadTCP(w.tcp, timeout)
if err != nil {
@@ -623,6 +738,10 @@ func (srv *Server) serve(w *response) {
func (srv *Server) serveDNS(w *response) {
req := new(Msg)
err := req.Unpack(w.msg)
+ if w.udp != nil && cap(w.msg) == srv.UDPSize {
+ srv.udpPool.Put(w.msg[:srv.UDPSize])
+ }
+ w.msg = nil
if err != nil { // Send a FormatError back
x := new(Msg)
x.SetRcodeFormatError(req)
@@ -691,9 +810,10 @@ func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error)
func (srv *Server) readUDP(conn *net.UDPConn, timeout time.Duration) ([]byte, *SessionUDP, error) {
conn.SetReadDeadline(time.Now().Add(timeout))
- m := make([]byte, srv.UDPSize)
+ m := srv.udpPool.Get().([]byte)
n, s, err := ReadFromSessionUDP(conn, m)
if err != nil {
+ srv.udpPool.Put(m)
return nil, nil, err
}
m = m[:n]
@@ -780,3 +900,15 @@ func (w *response) Close() error {
}
return nil
}
+
+// ConnectionState() implements the ConnectionStater.ConnectionState() interface.
+func (w *response) ConnectionState() *tls.ConnectionState {
+ type tlsConnectionStater interface {
+ ConnectionState() tls.ConnectionState
+ }
+ if v, ok := w.tcp.(tlsConnectionStater); ok {
+ t := v.ConnectionState()
+ return &t
+ }
+ return nil
+}
diff --git a/vendor/github.com/miekg/dns/types.go b/vendor/github.com/miekg/dns/types.go
index a779ca8ab..a64f4d7d8 100644
--- a/vendor/github.com/miekg/dns/types.go
+++ b/vendor/github.com/miekg/dns/types.go
@@ -330,7 +330,7 @@ func (rr *MX) String() string {
type AFSDB struct {
Hdr RR_Header
Subtype uint16
- Hostname string `dns:"cdomain-name"`
+ Hostname string `dns:"domain-name"`
}
func (rr *AFSDB) String() string {
@@ -728,7 +728,7 @@ func (rr *LOC) String() string {
lat = lat % LOC_DEGREES
m := lat / LOC_HOURS
lat = lat % LOC_HOURS
- s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float64(lat) / 1000), ns)
+ s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, float64(lat)/1000, ns)
lon := rr.Longitude
ew := "E"
@@ -742,7 +742,7 @@ func (rr *LOC) String() string {
lon = lon % LOC_DEGREES
m = lon / LOC_HOURS
lon = lon % LOC_HOURS
- s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, (float64(lon) / 1000), ew)
+ s += fmt.Sprintf("%02d %02d %0.3f %s ", h, m, float64(lon)/1000, ew)
var alt = float64(rr.Altitude) / 100
alt -= LOC_ALTITUDEBASE
@@ -752,9 +752,9 @@ func (rr *LOC) String() string {
s += fmt.Sprintf("%.0fm ", alt)
}
- s += cmToM((rr.Size&0xf0)>>4, rr.Size&0x0f) + "m "
- s += cmToM((rr.HorizPre&0xf0)>>4, rr.HorizPre&0x0f) + "m "
- s += cmToM((rr.VertPre&0xf0)>>4, rr.VertPre&0x0f) + "m"
+ s += cmToM(rr.Size&0xf0>>4, rr.Size&0x0f) + "m "
+ s += cmToM(rr.HorizPre&0xf0>>4, rr.HorizPre&0x0f) + "m "
+ s += cmToM(rr.VertPre&0xf0>>4, rr.VertPre&0x0f) + "m"
return s
}
@@ -1306,11 +1306,11 @@ func (rr *CSYNC) len() int {
// string representation used when printing the record.
// It takes serial arithmetic (RFC 1982) into account.
func TimeToString(t uint32) string {
- mod := ((int64(t) - time.Now().Unix()) / year68) - 1
+ mod := (int64(t)-time.Now().Unix())/year68 - 1
if mod < 0 {
mod = 0
}
- ti := time.Unix(int64(t)-(mod*year68), 0).UTC()
+ ti := time.Unix(int64(t)-mod*year68, 0).UTC()
return ti.Format("20060102150405")
}
@@ -1322,11 +1322,11 @@ func StringToTime(s string) (uint32, error) {
if err != nil {
return 0, err
}
- mod := (t.Unix() / year68) - 1
+ mod := t.Unix()/year68 - 1
if mod < 0 {
mod = 0
}
- return uint32(t.Unix() - (mod * year68)), nil
+ return uint32(t.Unix() - mod*year68), nil
}
// saltToString converts a NSECX salt to uppercase and returns "-" when it is empty.
diff --git a/vendor/github.com/miekg/dns/udp.go b/vendor/github.com/miekg/dns/udp.go
index a4826ee2f..82ead6939 100644
--- a/vendor/github.com/miekg/dns/udp.go
+++ b/vendor/github.com/miekg/dns/udp.go
@@ -1,5 +1,3 @@
-// +build !windows
-
package dns
import (
diff --git a/vendor/github.com/miekg/dns/udp_windows.go b/vendor/github.com/miekg/dns/udp_windows.go
deleted file mode 100644
index 6778c3c6c..000000000
--- a/vendor/github.com/miekg/dns/udp_windows.go
+++ /dev/null
@@ -1,37 +0,0 @@
-// +build windows
-
-package dns
-
-import "net"
-
-// SessionUDP holds the remote address
-type SessionUDP struct {
- raddr *net.UDPAddr
-}
-
-// RemoteAddr returns the remote network address.
-func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr }
-
-// ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
-// net.UDPAddr.
-// TODO(fastest963): Once go1.10 is released, use ReadMsgUDP.
-func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {
- n, raddr, err := conn.ReadFrom(b)
- if err != nil {
- return n, nil, err
- }
- session := &SessionUDP{raddr.(*net.UDPAddr)}
- return n, session, err
-}
-
-// WriteToSessionUDP acts just like net.UDPConn.WriteTo(), but uses a *SessionUDP instead of a net.Addr.
-// TODO(fastest963): Once go1.10 is released, use WriteMsgUDP.
-func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) {
- n, err := conn.WriteTo(b, session.raddr)
- return n, err
-}
-
-// TODO(fastest963): Once go1.10 is released and we can use *MsgUDP methods
-// use the standard method in udp.go for these.
-func setUDPSocketOptions(*net.UDPConn) error { return nil }
-func parseDstFromOOB([]byte, net.IP) net.IP { return nil }
diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go
index dcc84e4a7..ade7586dc 100644
--- a/vendor/github.com/miekg/dns/version.go
+++ b/vendor/github.com/miekg/dns/version.go
@@ -3,7 +3,7 @@ package dns
import "fmt"
// Version is current version of this library.
-var Version = V{1, 0, 8}
+var Version = V{1, 0, 10}
// V holds the version of this library.
type V struct {
diff --git a/vendor/github.com/miekg/dns/zcompress.go b/vendor/github.com/miekg/dns/zcompress.go
index a2c09dd48..6391a3501 100644
--- a/vendor/github.com/miekg/dns/zcompress.go
+++ b/vendor/github.com/miekg/dns/zcompress.go
@@ -109,9 +109,6 @@ func compressionLenHelperType(c map[string]int, r RR, initLen int) int {
func compressionLenSearchType(c map[string]int, r RR) (int, bool, int) {
switch x := r.(type) {
- case *AFSDB:
- k1, ok1, sz1 := compressionLenSearch(c, x.Hostname)
- return k1, ok1, sz1
case *CNAME:
k1, ok1, sz1 := compressionLenSearch(c, x.Target)
return k1, ok1, sz1
diff --git a/vendor/github.com/miekg/dns/zduplicate.go b/vendor/github.com/miekg/dns/zduplicate.go
new file mode 100644
index 000000000..ba9863b23
--- /dev/null
+++ b/vendor/github.com/miekg/dns/zduplicate.go
@@ -0,0 +1,943 @@
+// Code generated by "go run duplicate_generate.go"; DO NOT EDIT.
+
+package dns
+
+// isDuplicateRdata calls the rdata specific functions
+func isDuplicateRdata(r1, r2 RR) bool {
+ switch r1.Header().Rrtype {
+ case TypeA:
+ return isDuplicateA(r1.(*A), r2.(*A))
+ case TypeAAAA:
+ return isDuplicateAAAA(r1.(*AAAA), r2.(*AAAA))
+ case TypeAFSDB:
+ return isDuplicateAFSDB(r1.(*AFSDB), r2.(*AFSDB))
+ case TypeAVC:
+ return isDuplicateAVC(r1.(*AVC), r2.(*AVC))
+ case TypeCAA:
+ return isDuplicateCAA(r1.(*CAA), r2.(*CAA))
+ case TypeCERT:
+ return isDuplicateCERT(r1.(*CERT), r2.(*CERT))
+ case TypeCNAME:
+ return isDuplicateCNAME(r1.(*CNAME), r2.(*CNAME))
+ case TypeCSYNC:
+ return isDuplicateCSYNC(r1.(*CSYNC), r2.(*CSYNC))
+ case TypeDHCID:
+ return isDuplicateDHCID(r1.(*DHCID), r2.(*DHCID))
+ case TypeDNAME:
+ return isDuplicateDNAME(r1.(*DNAME), r2.(*DNAME))
+ case TypeDNSKEY:
+ return isDuplicateDNSKEY(r1.(*DNSKEY), r2.(*DNSKEY))
+ case TypeDS:
+ return isDuplicateDS(r1.(*DS), r2.(*DS))
+ case TypeEID:
+ return isDuplicateEID(r1.(*EID), r2.(*EID))
+ case TypeEUI48:
+ return isDuplicateEUI48(r1.(*EUI48), r2.(*EUI48))
+ case TypeEUI64:
+ return isDuplicateEUI64(r1.(*EUI64), r2.(*EUI64))
+ case TypeGID:
+ return isDuplicateGID(r1.(*GID), r2.(*GID))
+ case TypeGPOS:
+ return isDuplicateGPOS(r1.(*GPOS), r2.(*GPOS))
+ case TypeHINFO:
+ return isDuplicateHINFO(r1.(*HINFO), r2.(*HINFO))
+ case TypeHIP:
+ return isDuplicateHIP(r1.(*HIP), r2.(*HIP))
+ case TypeKX:
+ return isDuplicateKX(r1.(*KX), r2.(*KX))
+ case TypeL32:
+ return isDuplicateL32(r1.(*L32), r2.(*L32))
+ case TypeL64:
+ return isDuplicateL64(r1.(*L64), r2.(*L64))
+ case TypeLOC:
+ return isDuplicateLOC(r1.(*LOC), r2.(*LOC))
+ case TypeLP:
+ return isDuplicateLP(r1.(*LP), r2.(*LP))
+ case TypeMB:
+ return isDuplicateMB(r1.(*MB), r2.(*MB))
+ case TypeMD:
+ return isDuplicateMD(r1.(*MD), r2.(*MD))
+ case TypeMF:
+ return isDuplicateMF(r1.(*MF), r2.(*MF))
+ case TypeMG:
+ return isDuplicateMG(r1.(*MG), r2.(*MG))
+ case TypeMINFO:
+ return isDuplicateMINFO(r1.(*MINFO), r2.(*MINFO))
+ case TypeMR:
+ return isDuplicateMR(r1.(*MR), r2.(*MR))
+ case TypeMX:
+ return isDuplicateMX(r1.(*MX), r2.(*MX))
+ case TypeNAPTR:
+ return isDuplicateNAPTR(r1.(*NAPTR), r2.(*NAPTR))
+ case TypeNID:
+ return isDuplicateNID(r1.(*NID), r2.(*NID))
+ case TypeNIMLOC:
+ return isDuplicateNIMLOC(r1.(*NIMLOC), r2.(*NIMLOC))
+ case TypeNINFO:
+ return isDuplicateNINFO(r1.(*NINFO), r2.(*NINFO))
+ case TypeNS:
+ return isDuplicateNS(r1.(*NS), r2.(*NS))
+ case TypeNSAPPTR:
+ return isDuplicateNSAPPTR(r1.(*NSAPPTR), r2.(*NSAPPTR))
+ case TypeNSEC:
+ return isDuplicateNSEC(r1.(*NSEC), r2.(*NSEC))
+ case TypeNSEC3:
+ return isDuplicateNSEC3(r1.(*NSEC3), r2.(*NSEC3))
+ case TypeNSEC3PARAM:
+ return isDuplicateNSEC3PARAM(r1.(*NSEC3PARAM), r2.(*NSEC3PARAM))
+ case TypeOPENPGPKEY:
+ return isDuplicateOPENPGPKEY(r1.(*OPENPGPKEY), r2.(*OPENPGPKEY))
+ case TypePTR:
+ return isDuplicatePTR(r1.(*PTR), r2.(*PTR))
+ case TypePX:
+ return isDuplicatePX(r1.(*PX), r2.(*PX))
+ case TypeRKEY:
+ return isDuplicateRKEY(r1.(*RKEY), r2.(*RKEY))
+ case TypeRP:
+ return isDuplicateRP(r1.(*RP), r2.(*RP))
+ case TypeRRSIG:
+ return isDuplicateRRSIG(r1.(*RRSIG), r2.(*RRSIG))
+ case TypeRT:
+ return isDuplicateRT(r1.(*RT), r2.(*RT))
+ case TypeSMIMEA:
+ return isDuplicateSMIMEA(r1.(*SMIMEA), r2.(*SMIMEA))
+ case TypeSOA:
+ return isDuplicateSOA(r1.(*SOA), r2.(*SOA))
+ case TypeSPF:
+ return isDuplicateSPF(r1.(*SPF), r2.(*SPF))
+ case TypeSRV:
+ return isDuplicateSRV(r1.(*SRV), r2.(*SRV))
+ case TypeSSHFP:
+ return isDuplicateSSHFP(r1.(*SSHFP), r2.(*SSHFP))
+ case TypeTA:
+ return isDuplicateTA(r1.(*TA), r2.(*TA))
+ case TypeTALINK:
+ return isDuplicateTALINK(r1.(*TALINK), r2.(*TALINK))
+ case TypeTKEY:
+ return isDuplicateTKEY(r1.(*TKEY), r2.(*TKEY))
+ case TypeTLSA:
+ return isDuplicateTLSA(r1.(*TLSA), r2.(*TLSA))
+ case TypeTSIG:
+ return isDuplicateTSIG(r1.(*TSIG), r2.(*TSIG))
+ case TypeTXT:
+ return isDuplicateTXT(r1.(*TXT), r2.(*TXT))
+ case TypeUID:
+ return isDuplicateUID(r1.(*UID), r2.(*UID))
+ case TypeUINFO:
+ return isDuplicateUINFO(r1.(*UINFO), r2.(*UINFO))
+ case TypeURI:
+ return isDuplicateURI(r1.(*URI), r2.(*URI))
+ case TypeX25:
+ return isDuplicateX25(r1.(*X25), r2.(*X25))
+ }
+ return false
+}
+
+// isDuplicate() functions
+
+func isDuplicateA(r1, r2 *A) bool {
+ if len(r1.A) != len(r2.A) {
+ return false
+ }
+ for i := 0; i < len(r1.A); i++ {
+ if r1.A[i] != r2.A[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateAAAA(r1, r2 *AAAA) bool {
+ if len(r1.AAAA) != len(r2.AAAA) {
+ return false
+ }
+ for i := 0; i < len(r1.AAAA); i++ {
+ if r1.AAAA[i] != r2.AAAA[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateAFSDB(r1, r2 *AFSDB) bool {
+ if r1.Subtype != r2.Subtype {
+ return false
+ }
+ if !isDulicateName(r1.Hostname, r2.Hostname) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateAVC(r1, r2 *AVC) bool {
+ if len(r1.Txt) != len(r2.Txt) {
+ return false
+ }
+ for i := 0; i < len(r1.Txt); i++ {
+ if r1.Txt[i] != r2.Txt[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateCAA(r1, r2 *CAA) bool {
+ if r1.Flag != r2.Flag {
+ return false
+ }
+ if r1.Tag != r2.Tag {
+ return false
+ }
+ if r1.Value != r2.Value {
+ return false
+ }
+ return true
+}
+
+func isDuplicateCERT(r1, r2 *CERT) bool {
+ if r1.Type != r2.Type {
+ return false
+ }
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.Certificate != r2.Certificate {
+ return false
+ }
+ return true
+}
+
+func isDuplicateCNAME(r1, r2 *CNAME) bool {
+ if !isDulicateName(r1.Target, r2.Target) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateCSYNC(r1, r2 *CSYNC) bool {
+ if r1.Serial != r2.Serial {
+ return false
+ }
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if len(r1.TypeBitMap) != len(r2.TypeBitMap) {
+ return false
+ }
+ for i := 0; i < len(r1.TypeBitMap); i++ {
+ if r1.TypeBitMap[i] != r2.TypeBitMap[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateDHCID(r1, r2 *DHCID) bool {
+ if r1.Digest != r2.Digest {
+ return false
+ }
+ return true
+}
+
+func isDuplicateDNAME(r1, r2 *DNAME) bool {
+ if !isDulicateName(r1.Target, r2.Target) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateDNSKEY(r1, r2 *DNSKEY) bool {
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Protocol != r2.Protocol {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ return true
+}
+
+func isDuplicateDS(r1, r2 *DS) bool {
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.DigestType != r2.DigestType {
+ return false
+ }
+ if r1.Digest != r2.Digest {
+ return false
+ }
+ return true
+}
+
+func isDuplicateEID(r1, r2 *EID) bool {
+ if r1.Endpoint != r2.Endpoint {
+ return false
+ }
+ return true
+}
+
+func isDuplicateEUI48(r1, r2 *EUI48) bool {
+ if r1.Address != r2.Address {
+ return false
+ }
+ return true
+}
+
+func isDuplicateEUI64(r1, r2 *EUI64) bool {
+ if r1.Address != r2.Address {
+ return false
+ }
+ return true
+}
+
+func isDuplicateGID(r1, r2 *GID) bool {
+ if r1.Gid != r2.Gid {
+ return false
+ }
+ return true
+}
+
+func isDuplicateGPOS(r1, r2 *GPOS) bool {
+ if r1.Longitude != r2.Longitude {
+ return false
+ }
+ if r1.Latitude != r2.Latitude {
+ return false
+ }
+ if r1.Altitude != r2.Altitude {
+ return false
+ }
+ return true
+}
+
+func isDuplicateHINFO(r1, r2 *HINFO) bool {
+ if r1.Cpu != r2.Cpu {
+ return false
+ }
+ if r1.Os != r2.Os {
+ return false
+ }
+ return true
+}
+
+func isDuplicateHIP(r1, r2 *HIP) bool {
+ if r1.HitLength != r2.HitLength {
+ return false
+ }
+ if r1.PublicKeyAlgorithm != r2.PublicKeyAlgorithm {
+ return false
+ }
+ if r1.PublicKeyLength != r2.PublicKeyLength {
+ return false
+ }
+ if r1.Hit != r2.Hit {
+ return false
+ }
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ if len(r1.RendezvousServers) != len(r2.RendezvousServers) {
+ return false
+ }
+ for i := 0; i < len(r1.RendezvousServers); i++ {
+ if !isDulicateName(r1.RendezvousServers[i], r2.RendezvousServers[i]) {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateKX(r1, r2 *KX) bool {
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDulicateName(r1.Exchanger, r2.Exchanger) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateL32(r1, r2 *L32) bool {
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if len(r1.Locator32) != len(r2.Locator32) {
+ return false
+ }
+ for i := 0; i < len(r1.Locator32); i++ {
+ if r1.Locator32[i] != r2.Locator32[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateL64(r1, r2 *L64) bool {
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if r1.Locator64 != r2.Locator64 {
+ return false
+ }
+ return true
+}
+
+func isDuplicateLOC(r1, r2 *LOC) bool {
+ if r1.Version != r2.Version {
+ return false
+ }
+ if r1.Size != r2.Size {
+ return false
+ }
+ if r1.HorizPre != r2.HorizPre {
+ return false
+ }
+ if r1.VertPre != r2.VertPre {
+ return false
+ }
+ if r1.Latitude != r2.Latitude {
+ return false
+ }
+ if r1.Longitude != r2.Longitude {
+ return false
+ }
+ if r1.Altitude != r2.Altitude {
+ return false
+ }
+ return true
+}
+
+func isDuplicateLP(r1, r2 *LP) bool {
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDulicateName(r1.Fqdn, r2.Fqdn) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateMB(r1, r2 *MB) bool {
+ if !isDulicateName(r1.Mb, r2.Mb) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateMD(r1, r2 *MD) bool {
+ if !isDulicateName(r1.Md, r2.Md) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateMF(r1, r2 *MF) bool {
+ if !isDulicateName(r1.Mf, r2.Mf) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateMG(r1, r2 *MG) bool {
+ if !isDulicateName(r1.Mg, r2.Mg) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateMINFO(r1, r2 *MINFO) bool {
+ if !isDulicateName(r1.Rmail, r2.Rmail) {
+ return false
+ }
+ if !isDulicateName(r1.Email, r2.Email) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateMR(r1, r2 *MR) bool {
+ if !isDulicateName(r1.Mr, r2.Mr) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateMX(r1, r2 *MX) bool {
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDulicateName(r1.Mx, r2.Mx) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateNAPTR(r1, r2 *NAPTR) bool {
+ if r1.Order != r2.Order {
+ return false
+ }
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Service != r2.Service {
+ return false
+ }
+ if r1.Regexp != r2.Regexp {
+ return false
+ }
+ if !isDulicateName(r1.Replacement, r2.Replacement) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateNID(r1, r2 *NID) bool {
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if r1.NodeID != r2.NodeID {
+ return false
+ }
+ return true
+}
+
+func isDuplicateNIMLOC(r1, r2 *NIMLOC) bool {
+ if r1.Locator != r2.Locator {
+ return false
+ }
+ return true
+}
+
+func isDuplicateNINFO(r1, r2 *NINFO) bool {
+ if len(r1.ZSData) != len(r2.ZSData) {
+ return false
+ }
+ for i := 0; i < len(r1.ZSData); i++ {
+ if r1.ZSData[i] != r2.ZSData[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateNS(r1, r2 *NS) bool {
+ if !isDulicateName(r1.Ns, r2.Ns) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateNSAPPTR(r1, r2 *NSAPPTR) bool {
+ if !isDulicateName(r1.Ptr, r2.Ptr) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateNSEC(r1, r2 *NSEC) bool {
+ if !isDulicateName(r1.NextDomain, r2.NextDomain) {
+ return false
+ }
+ if len(r1.TypeBitMap) != len(r2.TypeBitMap) {
+ return false
+ }
+ for i := 0; i < len(r1.TypeBitMap); i++ {
+ if r1.TypeBitMap[i] != r2.TypeBitMap[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateNSEC3(r1, r2 *NSEC3) bool {
+ if r1.Hash != r2.Hash {
+ return false
+ }
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Iterations != r2.Iterations {
+ return false
+ }
+ if r1.SaltLength != r2.SaltLength {
+ return false
+ }
+ if r1.Salt != r2.Salt {
+ return false
+ }
+ if r1.HashLength != r2.HashLength {
+ return false
+ }
+ if r1.NextDomain != r2.NextDomain {
+ return false
+ }
+ if len(r1.TypeBitMap) != len(r2.TypeBitMap) {
+ return false
+ }
+ for i := 0; i < len(r1.TypeBitMap); i++ {
+ if r1.TypeBitMap[i] != r2.TypeBitMap[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateNSEC3PARAM(r1, r2 *NSEC3PARAM) bool {
+ if r1.Hash != r2.Hash {
+ return false
+ }
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Iterations != r2.Iterations {
+ return false
+ }
+ if r1.SaltLength != r2.SaltLength {
+ return false
+ }
+ if r1.Salt != r2.Salt {
+ return false
+ }
+ return true
+}
+
+func isDuplicateOPENPGPKEY(r1, r2 *OPENPGPKEY) bool {
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ return true
+}
+
+func isDuplicatePTR(r1, r2 *PTR) bool {
+ if !isDulicateName(r1.Ptr, r2.Ptr) {
+ return false
+ }
+ return true
+}
+
+func isDuplicatePX(r1, r2 *PX) bool {
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDulicateName(r1.Map822, r2.Map822) {
+ return false
+ }
+ if !isDulicateName(r1.Mapx400, r2.Mapx400) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateRKEY(r1, r2 *RKEY) bool {
+ if r1.Flags != r2.Flags {
+ return false
+ }
+ if r1.Protocol != r2.Protocol {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.PublicKey != r2.PublicKey {
+ return false
+ }
+ return true
+}
+
+func isDuplicateRP(r1, r2 *RP) bool {
+ if !isDulicateName(r1.Mbox, r2.Mbox) {
+ return false
+ }
+ if !isDulicateName(r1.Txt, r2.Txt) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateRRSIG(r1, r2 *RRSIG) bool {
+ if r1.TypeCovered != r2.TypeCovered {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.Labels != r2.Labels {
+ return false
+ }
+ if r1.OrigTtl != r2.OrigTtl {
+ return false
+ }
+ if r1.Expiration != r2.Expiration {
+ return false
+ }
+ if r1.Inception != r2.Inception {
+ return false
+ }
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if !isDulicateName(r1.SignerName, r2.SignerName) {
+ return false
+ }
+ if r1.Signature != r2.Signature {
+ return false
+ }
+ return true
+}
+
+func isDuplicateRT(r1, r2 *RT) bool {
+ if r1.Preference != r2.Preference {
+ return false
+ }
+ if !isDulicateName(r1.Host, r2.Host) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateSMIMEA(r1, r2 *SMIMEA) bool {
+ if r1.Usage != r2.Usage {
+ return false
+ }
+ if r1.Selector != r2.Selector {
+ return false
+ }
+ if r1.MatchingType != r2.MatchingType {
+ return false
+ }
+ if r1.Certificate != r2.Certificate {
+ return false
+ }
+ return true
+}
+
+func isDuplicateSOA(r1, r2 *SOA) bool {
+ if !isDulicateName(r1.Ns, r2.Ns) {
+ return false
+ }
+ if !isDulicateName(r1.Mbox, r2.Mbox) {
+ return false
+ }
+ if r1.Serial != r2.Serial {
+ return false
+ }
+ if r1.Refresh != r2.Refresh {
+ return false
+ }
+ if r1.Retry != r2.Retry {
+ return false
+ }
+ if r1.Expire != r2.Expire {
+ return false
+ }
+ if r1.Minttl != r2.Minttl {
+ return false
+ }
+ return true
+}
+
+func isDuplicateSPF(r1, r2 *SPF) bool {
+ if len(r1.Txt) != len(r2.Txt) {
+ return false
+ }
+ for i := 0; i < len(r1.Txt); i++ {
+ if r1.Txt[i] != r2.Txt[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateSRV(r1, r2 *SRV) bool {
+ if r1.Priority != r2.Priority {
+ return false
+ }
+ if r1.Weight != r2.Weight {
+ return false
+ }
+ if r1.Port != r2.Port {
+ return false
+ }
+ if !isDulicateName(r1.Target, r2.Target) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateSSHFP(r1, r2 *SSHFP) bool {
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.Type != r2.Type {
+ return false
+ }
+ if r1.FingerPrint != r2.FingerPrint {
+ return false
+ }
+ return true
+}
+
+func isDuplicateTA(r1, r2 *TA) bool {
+ if r1.KeyTag != r2.KeyTag {
+ return false
+ }
+ if r1.Algorithm != r2.Algorithm {
+ return false
+ }
+ if r1.DigestType != r2.DigestType {
+ return false
+ }
+ if r1.Digest != r2.Digest {
+ return false
+ }
+ return true
+}
+
+func isDuplicateTALINK(r1, r2 *TALINK) bool {
+ if !isDulicateName(r1.PreviousName, r2.PreviousName) {
+ return false
+ }
+ if !isDulicateName(r1.NextName, r2.NextName) {
+ return false
+ }
+ return true
+}
+
+func isDuplicateTKEY(r1, r2 *TKEY) bool {
+ if !isDulicateName(r1.Algorithm, r2.Algorithm) {
+ return false
+ }
+ if r1.Inception != r2.Inception {
+ return false
+ }
+ if r1.Expiration != r2.Expiration {
+ return false
+ }
+ if r1.Mode != r2.Mode {
+ return false
+ }
+ if r1.Error != r2.Error {
+ return false
+ }
+ if r1.KeySize != r2.KeySize {
+ return false
+ }
+ if r1.Key != r2.Key {
+ return false
+ }
+ if r1.OtherLen != r2.OtherLen {
+ return false
+ }
+ if r1.OtherData != r2.OtherData {
+ return false
+ }
+ return true
+}
+
+func isDuplicateTLSA(r1, r2 *TLSA) bool {
+ if r1.Usage != r2.Usage {
+ return false
+ }
+ if r1.Selector != r2.Selector {
+ return false
+ }
+ if r1.MatchingType != r2.MatchingType {
+ return false
+ }
+ if r1.Certificate != r2.Certificate {
+ return false
+ }
+ return true
+}
+
+func isDuplicateTSIG(r1, r2 *TSIG) bool {
+ if !isDulicateName(r1.Algorithm, r2.Algorithm) {
+ return false
+ }
+ if r1.TimeSigned != r2.TimeSigned {
+ return false
+ }
+ if r1.Fudge != r2.Fudge {
+ return false
+ }
+ if r1.MACSize != r2.MACSize {
+ return false
+ }
+ if r1.MAC != r2.MAC {
+ return false
+ }
+ if r1.OrigId != r2.OrigId {
+ return false
+ }
+ if r1.Error != r2.Error {
+ return false
+ }
+ if r1.OtherLen != r2.OtherLen {
+ return false
+ }
+ if r1.OtherData != r2.OtherData {
+ return false
+ }
+ return true
+}
+
+func isDuplicateTXT(r1, r2 *TXT) bool {
+ if len(r1.Txt) != len(r2.Txt) {
+ return false
+ }
+ for i := 0; i < len(r1.Txt); i++ {
+ if r1.Txt[i] != r2.Txt[i] {
+ return false
+ }
+ }
+ return true
+}
+
+func isDuplicateUID(r1, r2 *UID) bool {
+ if r1.Uid != r2.Uid {
+ return false
+ }
+ return true
+}
+
+func isDuplicateUINFO(r1, r2 *UINFO) bool {
+ if r1.Uinfo != r2.Uinfo {
+ return false
+ }
+ return true
+}
+
+func isDuplicateURI(r1, r2 *URI) bool {
+ if r1.Priority != r2.Priority {
+ return false
+ }
+ if r1.Weight != r2.Weight {
+ return false
+ }
+ if r1.Target != r2.Target {
+ return false
+ }
+ return true
+}
+
+func isDuplicateX25(r1, r2 *X25) bool {
+ if r1.PSDNAddress != r2.PSDNAddress {
+ return false
+ }
+ return true
+}
diff --git a/vendor/github.com/miekg/dns/zmsg.go b/vendor/github.com/miekg/dns/zmsg.go
index 0d1f6f4da..1a68f74da 100644
--- a/vendor/github.com/miekg/dns/zmsg.go
+++ b/vendor/github.com/miekg/dns/zmsg.go
@@ -42,7 +42,7 @@ func (rr *AFSDB) pack(msg []byte, off int, compression map[string]int, compress
if err != nil {
return off, err
}
- off, err = PackDomainName(rr.Hostname, msg, off, compression, compress)
+ off, err = PackDomainName(rr.Hostname, msg, off, compression, false)
if err != nil {
return off, err
}