From e7ce10d4e563c5a36b17330ce3135db167d9d4fc Mon Sep 17 00:00:00 2001 From: James Hartig Date: Mon, 13 Feb 2017 15:40:45 -0500 Subject: [PATCH 1/2] vendoring: Update github.com/miekg/dns This is needed to get the NameList function to get query names --- vendor/github.com/miekg/dns/README.md | 5 +- vendor/github.com/miekg/dns/client.go | 14 ++- vendor/github.com/miekg/dns/clientconfig.go | 32 ++++++ vendor/github.com/miekg/dns/dane.go | 9 +- vendor/github.com/miekg/dns/defaults.go | 4 +- vendor/github.com/miekg/dns/dnssec.go | 11 +- vendor/github.com/miekg/dns/dnssec_keygen.go | 16 +-- vendor/github.com/miekg/dns/edns.go | 83 +++++++++++--- vendor/github.com/miekg/dns/msg.go | 82 +++++++------- vendor/github.com/miekg/dns/msg_generate.go | 4 +- vendor/github.com/miekg/dns/msg_helpers.go | 2 - vendor/github.com/miekg/dns/nsecx.go | 11 +- vendor/github.com/miekg/dns/scan_rr.go | 112 +++++++++---------- vendor/github.com/miekg/dns/server.go | 6 +- vendor/github.com/miekg/dns/sig0.go | 5 +- vendor/github.com/miekg/dns/tsig.go | 3 +- vendor/github.com/miekg/dns/types.go | 19 +--- vendor/github.com/miekg/dns/udp.go | 26 +---- vendor/github.com/miekg/dns/udp_linux.go | 34 +++++- vendor/github.com/miekg/dns/udp_other.go | 17 --- vendor/github.com/miekg/dns/udp_plan9.go | 34 ------ vendor/github.com/miekg/dns/udp_windows.go | 9 +- vendor/github.com/miekg/dns/zmsg.go | 34 +++--- vendor/vendor.json | 6 +- 24 files changed, 301 insertions(+), 277 deletions(-) delete mode 100644 vendor/github.com/miekg/dns/udp_other.go delete mode 100644 vendor/github.com/miekg/dns/udp_plan9.go diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md index 0e3356cb9..0c1f1b6a9 100644 --- a/vendor/github.com/miekg/dns/README.md +++ b/vendor/github.com/miekg/dns/README.md @@ -1,4 +1,5 @@ -[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns) [![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns) +[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns) +[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns) # Alternative (more granular) approach to a DNS library @@ -12,7 +13,7 @@ can build servers and resolvers with it. We try to keep the "master" branch as sane as possible and at the bleeding edge of standards, avoiding breaking changes wherever reasonable. We support the last -two versions of Go, currently: 1.5 and 1.6. +two versions of Go, currently: 1.6 and 1.7. # Goals diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go index 0db7f7bf6..8b09e189e 100644 --- a/vendor/github.com/miekg/dns/client.go +++ b/vendor/github.com/miekg/dns/client.go @@ -300,6 +300,18 @@ func tcpMsgLen(t io.Reader) (int, error) { if err != nil { return 0, err } + + // As seen with my local router/switch, retursn 1 byte on the above read, + // resulting a a ShortRead. Just write it out (instead of loop) and read the + // other byte. + if n == 1 { + n1, err := t.Read(p[1:]) + if err != nil { + return 0, err + } + n += n1 + } + if n != 2 { return 0, ErrShortRead } @@ -400,7 +412,7 @@ func (co *Conn) Write(p []byte) (n int, err error) { n, err := io.Copy(w, bytes.NewReader(p)) return int(n), err } - n, err = co.Conn.(*net.UDPConn).Write(p) + n, err = co.Conn.Write(p) return n, err } diff --git a/vendor/github.com/miekg/dns/clientconfig.go b/vendor/github.com/miekg/dns/clientconfig.go index cfa9ad0b2..0a1f5a92c 100644 --- a/vendor/github.com/miekg/dns/clientconfig.go +++ b/vendor/github.com/miekg/dns/clientconfig.go @@ -97,3 +97,35 @@ func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) { } return c, nil } + +// NameList returns all of the names that should be queried based on the +// config. It is based off of go's net/dns name building, but it does not +// check the length of the resulting names. +func (c *ClientConfig) NameList(name string) []string { + // if this domain is already fully qualified, no append needed. + if IsFqdn(name) { + return []string{name} + } + + // Check to see if the name has more labels than Ndots. Do this before making + // the domain fully qualified. + hasNdots := CountLabel(name) > c.Ndots + // Make the domain fully qualified. + name = Fqdn(name) + + // Make a list of names based off search. + names := []string{} + + // If name has enough dots, try that first. + if hasNdots { + names = append(names, name) + } + for _, s := range c.Search { + names = append(names, Fqdn(name+s)) + } + // If we didn't have enough dots, try after suffixes. + if !hasNdots { + names = append(names, name) + } + return names +} diff --git a/vendor/github.com/miekg/dns/dane.go b/vendor/github.com/miekg/dns/dane.go index cdaa833ff..8c4a14ef1 100644 --- a/vendor/github.com/miekg/dns/dane.go +++ b/vendor/github.com/miekg/dns/dane.go @@ -6,7 +6,6 @@ import ( "crypto/x509" "encoding/hex" "errors" - "io" ) // CertificateToDANE converts a certificate to a hex string as used in the TLSA or SMIMEA records. @@ -23,20 +22,20 @@ func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (st h := sha256.New() switch selector { case 0: - io.WriteString(h, string(cert.Raw)) + h.Write(cert.Raw) return hex.EncodeToString(h.Sum(nil)), nil case 1: - io.WriteString(h, string(cert.RawSubjectPublicKeyInfo)) + h.Write(cert.RawSubjectPublicKeyInfo) return hex.EncodeToString(h.Sum(nil)), nil } case 2: h := sha512.New() switch selector { case 0: - io.WriteString(h, string(cert.Raw)) + h.Write(cert.Raw) return hex.EncodeToString(h.Sum(nil)), nil case 1: - io.WriteString(h, string(cert.RawSubjectPublicKeyInfo)) + h.Write(cert.RawSubjectPublicKeyInfo) return hex.EncodeToString(h.Sum(nil)), nil } } diff --git a/vendor/github.com/miekg/dns/defaults.go b/vendor/github.com/miekg/dns/defaults.go index cf456165f..3308ec838 100644 --- a/vendor/github.com/miekg/dns/defaults.go +++ b/vendor/github.com/miekg/dns/defaults.go @@ -102,11 +102,11 @@ func (dns *Msg) SetAxfr(z string) *Msg { // SetTsig appends a TSIG RR to the message. // This is only a skeleton TSIG RR that is added as the last RR in the // additional section. The Tsig is calculated when the message is being send. -func (dns *Msg) SetTsig(z, algo string, fudge, timesigned int64) *Msg { +func (dns *Msg) SetTsig(z, algo string, fudge uint16, timesigned int64) *Msg { t := new(TSIG) t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0} t.Algorithm = algo - t.Fudge = 300 + t.Fudge = fudge t.TimeSigned = uint64(timesigned) t.OrigId = dns.Id dns.Extra = append(dns.Extra, t) diff --git a/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/miekg/dns/dnssec.go index f5f3fbdd8..9e196859c 100644 --- a/vendor/github.com/miekg/dns/dnssec.go +++ b/vendor/github.com/miekg/dns/dnssec.go @@ -208,9 +208,6 @@ func (k *DNSKEY) ToDS(h uint8) *DS { // "|" denotes concatenation // DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. - // digest buffer - digest := append(owner, wire...) // another copy - var hash crypto.Hash switch h { case SHA1: @@ -226,7 +223,8 @@ func (k *DNSKEY) ToDS(h uint8) *DS { } s := hash.New() - s.Write(digest) + s.Write(owner) + s.Write(wire) ds.Digest = hex.EncodeToString(s.Sum(nil)) return ds } @@ -297,7 +295,6 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error { if err != nil { return err } - signdata = append(signdata, wire...) hash, ok := AlgorithmToHash[rr.Algorithm] if !ok { @@ -306,6 +303,7 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error { h := hash.New() h.Write(signdata) + h.Write(wire) signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm) if err != nil { @@ -415,7 +413,6 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { if err != nil { return err } - signeddata = append(signeddata, wire...) sigbuf := rr.sigBuf() // Get the binary signature data if rr.Algorithm == PRIVATEDNS { // PRIVATEOID @@ -438,6 +435,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { h := hash.New() h.Write(signeddata) + h.Write(wire) return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf) case ECDSAP256SHA256, ECDSAP384SHA384: @@ -452,6 +450,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error { h := hash.New() h.Write(signeddata) + h.Write(wire) if ecdsa.Verify(pubkey, h.Sum(nil), r, s) { return nil } diff --git a/vendor/github.com/miekg/dns/dnssec_keygen.go b/vendor/github.com/miekg/dns/dnssec_keygen.go index 229a07937..5e4b7741a 100644 --- a/vendor/github.com/miekg/dns/dnssec_keygen.go +++ b/vendor/github.com/miekg/dns/dnssec_keygen.go @@ -121,17 +121,17 @@ func (k *DNSKEY) setPublicKeyDSA(_Q, _P, _G, _Y *big.Int) bool { // RFC 3110: Section 2. RSA Public KEY Resource Records func exponentToBuf(_E int) []byte { var buf []byte - i := big.NewInt(int64(_E)) - if len(i.Bytes()) < 256 { - buf = make([]byte, 1) - buf[0] = uint8(len(i.Bytes())) + i := big.NewInt(int64(_E)).Bytes() + if len(i) < 256 { + buf = make([]byte, 1, 1+len(i)) + buf[0] = uint8(len(i)) } else { - buf = make([]byte, 3) + buf = make([]byte, 3, 3+len(i)) buf[0] = 0 - buf[1] = uint8(len(i.Bytes()) >> 8) - buf[2] = uint8(len(i.Bytes())) + buf[1] = uint8(len(i) >> 8) + buf[2] = uint8(len(i)) } - buf = append(buf, i.Bytes()...) + buf = append(buf, i...) return buf } diff --git a/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/miekg/dns/edns.go index 0550aaa39..465b85f37 100644 --- a/vendor/github.com/miekg/dns/edns.go +++ b/vendor/github.com/miekg/dns/edns.go @@ -4,25 +4,27 @@ import ( "encoding/binary" "encoding/hex" "errors" + "fmt" "net" "strconv" ) // EDNS0 Option codes. const ( - EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 - EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt - EDNS0NSID = 0x3 // nsid (RFC5001) - EDNS0DAU = 0x5 // DNSSEC Algorithm Understood - EDNS0DHU = 0x6 // DS Hash Understood - EDNS0N3U = 0x7 // NSEC3 Hash Understood - EDNS0SUBNET = 0x8 // client-subnet (RFC6891) - EDNS0EXPIRE = 0x9 // EDNS0 expire - EDNS0COOKIE = 0xa // EDNS0 Cookie - EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET - EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891) - EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891) - _DO = 1 << 15 // dnssec ok + EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 + EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt + EDNS0NSID = 0x3 // nsid (RFC5001) + EDNS0DAU = 0x5 // DNSSEC Algorithm Understood + EDNS0DHU = 0x6 // DS Hash Understood + EDNS0N3U = 0x7 // NSEC3 Hash Understood + EDNS0SUBNET = 0x8 // client-subnet (RFC6891) + EDNS0EXPIRE = 0x9 // EDNS0 expire + EDNS0COOKIE = 0xa // EDNS0 Cookie + EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (RFC7828) + EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET + EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891) + EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891) + _DO = 1 << 15 // dnssec ok ) // OPT is the EDNS0 RR appended to messages to convey extra (meta) information. @@ -195,7 +197,7 @@ func (e *EDNS0_NSID) String() string { return string(e.Nsid) } // e := new(dns.EDNS0_SUBNET) // e.Code = dns.EDNS0SUBNET // e.Family = 1 // 1 for IPv4 source address, 2 for IPv6 -// e.NetMask = 32 // 32 for IPV4, 128 for IPv6 +// e.SourceNetMask = 32 // 32 for IPV4, 128 for IPv6 // e.SourceScope = 0 // e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4 // // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6 @@ -540,3 +542,56 @@ func (e *EDNS0_LOCAL) unpack(b []byte) error { } return nil } + +type EDNS0_TCP_KEEPALIVE struct { + Code uint16 // Always EDNSTCPKEEPALIVE + Length uint16 // the value 0 if the TIMEOUT is omitted, the value 2 if it is present; + Timeout uint16 // an idle timeout value for the TCP connection, specified in units of 100 milliseconds, encoded in network byte order. +} + +func (e *EDNS0_TCP_KEEPALIVE) Option() uint16 { + return EDNS0TCPKEEPALIVE +} + +func (e *EDNS0_TCP_KEEPALIVE) pack() ([]byte, error) { + if e.Timeout != 0 && e.Length != 2 { + return nil, errors.New("dns: timeout specified but length is not 2") + } + if e.Timeout == 0 && e.Length != 0 { + return nil, errors.New("dns: timeout not specified but length is not 0") + } + b := make([]byte, 4+e.Length) + binary.BigEndian.PutUint16(b[0:], e.Code) + binary.BigEndian.PutUint16(b[2:], e.Length) + if e.Length == 2 { + binary.BigEndian.PutUint16(b[4:], e.Timeout) + } + return b, nil +} + +func (e *EDNS0_TCP_KEEPALIVE) unpack(b []byte) error { + if len(b) < 4 { + return ErrBuf + } + e.Length = binary.BigEndian.Uint16(b[2:4]) + if e.Length != 0 && e.Length != 2 { + return errors.New("dns: length mismatch, want 0/2 but got " + strconv.FormatUint(uint64(e.Length), 10)) + } + if e.Length == 2 { + if len(b) < 6 { + return ErrBuf + } + e.Timeout = binary.BigEndian.Uint16(b[4:6]) + } + return nil +} + +func (e *EDNS0_TCP_KEEPALIVE) String() (s string) { + s = "use tcp keep-alive" + if e.Length == 0 { + s += ", timeout omitted" + } else { + s += fmt.Sprintf(", timeout %dms", e.Timeout*100) + } + return +} diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go index a9acd1e9f..c74e724fd 100644 --- a/vendor/github.com/miekg/dns/msg.go +++ b/vendor/github.com/miekg/dns/msg.go @@ -16,22 +16,9 @@ import ( "math/big" "math/rand" "strconv" + "sync" ) -func init() { - // Initialize default math/rand source using crypto/rand to provide better - // security without the performance trade-off. - buf := make([]byte, 8) - _, err := crand.Read(buf) - if err != nil { - // Failed to read from cryptographic source, fallback to default initial - // seed (1) by returning early - return - } - seed := binary.BigEndian.Uint64(buf) - rand.Seed(int64(seed)) -} - const maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer var ( @@ -66,11 +53,45 @@ var ( // dns.Id = func() uint16 { return 3 } var Id func() uint16 = id +var ( + idLock sync.Mutex + idRand *rand.Rand +) + // id returns a 16 bits random number to be used as a // message id. The random provided should be good enough. func id() uint16 { - id32 := rand.Uint32() - return uint16(id32) + idLock.Lock() + + if idRand == nil { + // This (partially) works around + // https://github.com/golang/go/issues/11833 by only + // seeding idRand upon the first call to id. + + var seed int64 + var buf [8]byte + + if _, err := crand.Read(buf[:]); err == nil { + seed = int64(binary.LittleEndian.Uint64(buf[:])) + } else { + seed = rand.Int63() + } + + idRand = rand.New(rand.NewSource(seed)) + } + + // The call to idRand.Uint32 must be within the + // mutex lock because *rand.Rand is not safe for + // concurrent use. + // + // There is no added performance overhead to calling + // idRand.Uint32 inside a mutex lock over just + // calling rand.Uint32 as the global math/rand rng + // is internally protected by a sync.Mutex. + id := uint16(idRand.Uint32()) + + idLock.Unlock() + return id } // MsgHdr is a a manually-unpacked version of (id, bits). @@ -203,12 +224,6 @@ func packDomainName(s string, msg []byte, off int, compression map[string]int, c bs[j] = bs[j+2] } ls -= 2 - } else if bs[i] == 't' { - bs[i] = '\t' - } else if bs[i] == 'r' { - bs[i] = '\r' - } else if bs[i] == 'n' { - bs[i] = '\n' } escapedDot = bs[i] == '.' bsFresh = false @@ -335,10 +350,6 @@ Loop: fallthrough case '"', '\\': s = append(s, '\\', b) - case '\t': - s = append(s, '\\', 't') - case '\r': - s = append(s, '\\', 'r') default: if b < 32 || b >= 127 { // unprintable use \DDD var buf [3]byte @@ -431,12 +442,6 @@ func packTxtString(s string, msg []byte, offset int, tmp []byte) (int, error) { if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) { msg[offset] = dddToByte(bs[i:]) i += 2 - } else if bs[i] == 't' { - msg[offset] = '\t' - } else if bs[i] == 'r' { - msg[offset] = '\r' - } else if bs[i] == 'n' { - msg[offset] = '\n' } else { msg[offset] = bs[i] } @@ -508,12 +513,6 @@ func unpackTxtString(msg []byte, offset int) (string, int, error) { switch b { case '"', '\\': s = append(s, '\\', b) - case '\t': - s = append(s, `\t`...) - case '\r': - s = append(s, `\r`...) - case '\n': - s = append(s, `\n`...) default: if b < 32 || b > 127 { // unprintable var buf [3]byte @@ -781,9 +780,6 @@ func (dns *Msg) Unpack(msg []byte) (err error) { if dh, off, err = unpackMsgHdr(msg, off); err != nil { return err } - if off == len(msg) { - return ErrTruncated - } dns.Id = dh.Id dns.Response = (dh.Bits & _QR) != 0 @@ -797,6 +793,10 @@ func (dns *Msg) Unpack(msg []byte) (err error) { dns.CheckingDisabled = (dh.Bits & _CD) != 0 dns.Rcode = int(dh.Bits & 0xF) + if off == len(msg) { + return ErrTruncated + } + // Optimistically use the count given to us in the header dns.Question = make([]Question, 0, int(dh.Qdcount)) diff --git a/vendor/github.com/miekg/dns/msg_generate.go b/vendor/github.com/miekg/dns/msg_generate.go index 35786f22c..c29447a10 100644 --- a/vendor/github.com/miekg/dns/msg_generate.go +++ b/vendor/github.com/miekg/dns/msg_generate.go @@ -117,9 +117,9 @@ return off, err switch { case st.Tag(i) == `dns:"-"`: // ignored case st.Tag(i) == `dns:"cdomain-name"`: - fallthrough - case st.Tag(i) == `dns:"domain-name"`: o("off, err = PackDomainName(rr.%s, msg, off, compression, compress)\n") + case st.Tag(i) == `dns:"domain-name"`: + o("off, err = PackDomainName(rr.%s, msg, off, compression, false)\n") case st.Tag(i) == `dns:"a"`: o("off, err = packDataA(rr.%s, msg, off)\n") case st.Tag(i) == `dns:"aaaa"`: diff --git a/vendor/github.com/miekg/dns/msg_helpers.go b/vendor/github.com/miekg/dns/msg_helpers.go index e7a9500cc..494c05377 100644 --- a/vendor/github.com/miekg/dns/msg_helpers.go +++ b/vendor/github.com/miekg/dns/msg_helpers.go @@ -263,8 +263,6 @@ func unpackString(msg []byte, off int) (string, int, error) { switch b { case '"', '\\': s = append(s, '\\', b) - case '\t', '\r', '\n': - s = append(s, b) default: if b < 32 || b > 127 { // unprintable var buf [3]byte diff --git a/vendor/github.com/miekg/dns/nsecx.go b/vendor/github.com/miekg/dns/nsecx.go index 6f10f3e65..51ce7f8b1 100644 --- a/vendor/github.com/miekg/dns/nsecx.go +++ b/vendor/github.com/miekg/dns/nsecx.go @@ -3,7 +3,6 @@ package dns import ( "crypto/sha1" "hash" - "io" "strings" ) @@ -36,15 +35,15 @@ func HashName(label string, ha uint8, iter uint16, salt string) string { } // k = 0 - name = append(name, wire...) - io.WriteString(s, string(name)) + s.Write(name) + s.Write(wire) nsec3 := s.Sum(nil) // k > 0 for k := uint16(0); k < iter; k++ { s.Reset() - nsec3 = append(nsec3, wire...) - io.WriteString(s, string(nsec3)) - nsec3 = s.Sum(nil) + s.Write(nsec3) + s.Write(wire) + nsec3 = s.Sum(nsec3[:0]) } return toBase32(nsec3) } diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go index 675fc80d8..8d6a1bf24 100644 --- a/vendor/github.com/miekg/dns/scan_rr.go +++ b/vendor/github.com/miekg/dns/scan_rr.go @@ -64,74 +64,63 @@ func endingToString(c chan lex, errstr, f string) (string, *ParseError, string) return s, nil, l.comment } -// A remainder of the rdata with embedded spaces, return the parsed string slice (sans the spaces) -// or an error +// A remainder of the rdata with embedded spaces, split on unquoted whitespace +// and return the parsed string slice or an error func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) { // Get the remaining data until we see a zNewline - quote := false l := <-c - var s []string if l.err { - return s, &ParseError{f, errstr, l}, "" + return nil, &ParseError{f, errstr, l}, "" } - switch l.value == zQuote { - case true: // A number of quoted string - s = make([]string, 0) - empty := true - for l.value != zNewline && l.value != zEOF { - if l.err { - return nil, &ParseError{f, errstr, l}, "" - } - switch l.value { - case zString: - empty = false - if len(l.token) > 255 { - // split up tokens that are larger than 255 into 255-chunks - sx := []string{} - p, i := 0, 255 - for { - if i <= len(l.token) { - sx = append(sx, l.token[p:i]) - } else { - sx = append(sx, l.token[p:]) - break - } - p, i = p+255, i+255 - } - s = append(s, sx...) - break - } - - s = append(s, l.token) - case zBlank: - if quote { - // zBlank can only be seen in between txt parts. - return nil, &ParseError{f, errstr, l}, "" - } - case zQuote: - if empty && quote { - s = append(s, "") - } - quote = !quote - empty = true - default: - return nil, &ParseError{f, errstr, l}, "" - } - l = <-c - } - if quote { + // Build the slice + s := make([]string, 0) + quote := false + empty := false + for l.value != zNewline && l.value != zEOF { + if l.err { return nil, &ParseError{f, errstr, l}, "" } - case false: // Unquoted text record - s = make([]string, 1) - for l.value != zNewline && l.value != zEOF { - if l.err { - return s, &ParseError{f, errstr, l}, "" + switch l.value { + case zString: + empty = false + if len(l.token) > 255 { + // split up tokens that are larger than 255 into 255-chunks + sx := []string{} + p, i := 0, 255 + for { + if i <= len(l.token) { + sx = append(sx, l.token[p:i]) + } else { + sx = append(sx, l.token[p:]) + break + + } + p, i = p+255, i+255 + } + s = append(s, sx...) + break } - s[0] += l.token - l = <-c + + s = append(s, l.token) + case zBlank: + if quote { + // zBlank can only be seen in between txt parts. + return nil, &ParseError{f, errstr, l}, "" + } + case zQuote: + if empty && quote { + s = append(s, "") + } + quote = !quote + empty = true + default: + return nil, &ParseError{f, errstr, l}, "" } + l = <-c + } + if quote { + return nil, &ParseError{f, errstr, l}, "" } return s, nil, l.comment } @@ -2027,9 +2016,12 @@ func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { rr.Hdr = h s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f) if e != nil { - return nil, e, "" + return nil, e, c1 } - rr.Uinfo = s[0] // silently discard anything above + if ln := len(s); ln == 0 { + return rr, nil, c1 + } + rr.Uinfo = s[0] // silently discard anything after the first character-string return rr, nil, c1 } diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go index c34801aef..0ca6e008c 100644 --- a/vendor/github.com/miekg/dns/server.go +++ b/vendor/github.com/miekg/dns/server.go @@ -339,7 +339,7 @@ func (srv *Server) ListenAndServe() error { network := "tcp" if srv.Net == "tcp4-tls" { network = "tcp4" - } else if srv.Net == "tcp6" { + } else if srv.Net == "tcp6-tls" { network = "tcp6" } @@ -389,7 +389,9 @@ func (srv *Server) ActivateAndServe() error { if srv.UDPSize == 0 { srv.UDPSize = MinMsgSize } - if t, ok := pConn.(*net.UDPConn); ok { + // Check PacketConn interface's type is valid and value + // is not nil + if t, ok := pConn.(*net.UDPConn); ok && t != nil { if e := setUDPSocketOptions(t); e != nil { return e } diff --git a/vendor/github.com/miekg/dns/sig0.go b/vendor/github.com/miekg/dns/sig0.go index 2dce06af8..f31e9e684 100644 --- a/vendor/github.com/miekg/dns/sig0.go +++ b/vendor/github.com/miekg/dns/sig0.go @@ -60,16 +60,15 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) { } rr.Signature = toBase64(signature) - sig := string(signature) - buf = append(buf, sig...) + buf = append(buf, signature...) if len(buf) > int(^uint16(0)) { return nil, ErrBuf } // Adjust sig data length rdoff := len(mbuf) + 1 + 2 + 2 + 4 rdlen := binary.BigEndian.Uint16(buf[rdoff:]) - rdlen += uint16(len(sig)) + rdlen += uint16(len(signature)) binary.BigEndian.PutUint16(buf[rdoff:], rdlen) // Adjust additional count adc := binary.BigEndian.Uint16(buf[10:]) diff --git a/vendor/github.com/miekg/dns/tsig.go b/vendor/github.com/miekg/dns/tsig.go index 78365e1c5..24013096b 100644 --- a/vendor/github.com/miekg/dns/tsig.go +++ b/vendor/github.com/miekg/dns/tsig.go @@ -9,7 +9,6 @@ import ( "encoding/binary" "encoding/hex" "hash" - "io" "strconv" "strings" "time" @@ -124,7 +123,7 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s default: return nil, "", ErrKeyAlg } - io.WriteString(h, string(buf)) + h.Write(buf) t.MAC = hex.EncodeToString(h.Sum(nil)) t.MACSize = uint16(len(t.MAC) / 2) // Size is half! diff --git a/vendor/github.com/miekg/dns/types.go b/vendor/github.com/miekg/dns/types.go index f63a18b33..c8b3191e5 100644 --- a/vendor/github.com/miekg/dns/types.go +++ b/vendor/github.com/miekg/dns/types.go @@ -480,12 +480,6 @@ func appendDomainNameByte(s []byte, b byte) []byte { func appendTXTStringByte(s []byte, b byte) []byte { switch b { - case '\t': - return append(s, '\\', 't') - case '\r': - return append(s, '\\', 'r') - case '\n': - return append(s, '\\', 'n') case '"', '\\': return append(s, '\\', b) } @@ -525,17 +519,8 @@ func nextByte(b []byte, offset int) (byte, int) { return dddToByte(b[offset+1:]), 4 } } - // not \ddd, maybe a control char - switch b[offset+1] { - case 't': - return '\t', 2 - case 'r': - return '\r', 2 - case 'n': - return '\n', 2 - default: - return b[offset+1], 2 - } + // not \ddd, just an RFC 1035 "quoted" character + return b[offset+1], 2 } type SPF struct { diff --git a/vendor/github.com/miekg/dns/udp.go b/vendor/github.com/miekg/dns/udp.go index c79c6c883..af111b9a8 100644 --- a/vendor/github.com/miekg/dns/udp.go +++ b/vendor/github.com/miekg/dns/udp.go @@ -1,10 +1,9 @@ -// +build !windows,!plan9 +// +build !windows package dns import ( "net" - "syscall" ) // SessionUDP holds the remote address and the associated @@ -17,29 +16,6 @@ type SessionUDP struct { // RemoteAddr returns the remote network address. func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } -// setUDPSocketOptions sets the UDP socket options. -// This function is implemented on a per platform basis. See udp_*.go for more details -func setUDPSocketOptions(conn *net.UDPConn) error { - sa, err := getUDPSocketName(conn) - if err != nil { - return err - } - switch sa.(type) { - case *syscall.SockaddrInet6: - v6only, err := getUDPSocketOptions6Only(conn) - if err != nil { - return err - } - setUDPSocketOptions6(conn) - if !v6only { - setUDPSocketOptions4(conn) - } - case *syscall.SockaddrInet4: - setUDPSocketOptions4(conn) - } - return nil -} - // ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a // net.UDPAddr. func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { diff --git a/vendor/github.com/miekg/dns/udp_linux.go b/vendor/github.com/miekg/dns/udp_linux.go index c62d21881..033df4239 100644 --- a/vendor/github.com/miekg/dns/udp_linux.go +++ b/vendor/github.com/miekg/dns/udp_linux.go @@ -1,4 +1,4 @@ -// +build linux +// +build linux,!appengine package dns @@ -15,6 +15,29 @@ import ( "syscall" ) +// setUDPSocketOptions sets the UDP socket options. +// This function is implemented on a per platform basis. See udp_*.go for more details +func setUDPSocketOptions(conn *net.UDPConn) error { + sa, err := getUDPSocketName(conn) + if err != nil { + return err + } + switch sa.(type) { + case *syscall.SockaddrInet6: + v6only, err := getUDPSocketOptions6Only(conn) + if err != nil { + return err + } + setUDPSocketOptions6(conn) + if !v6only { + setUDPSocketOptions4(conn) + } + case *syscall.SockaddrInet4: + setUDPSocketOptions4(conn) + } + return nil +} + // setUDPSocketOptions4 prepares the v4 socket for sessions. func setUDPSocketOptions4(conn *net.UDPConn) error { file, err := conn.File() @@ -22,14 +45,17 @@ func setUDPSocketOptions4(conn *net.UDPConn) error { return err } if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IP, syscall.IP_PKTINFO, 1); err != nil { + file.Close() return err } // Calling File() above results in the connection becoming blocking, we must fix that. // See https://github.com/miekg/dns/issues/279 err = syscall.SetNonblock(int(file.Fd()), true) if err != nil { + file.Close() return err } + file.Close() return nil } @@ -40,12 +66,15 @@ func setUDPSocketOptions6(conn *net.UDPConn) error { return err } if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1); err != nil { + file.Close() return err } err = syscall.SetNonblock(int(file.Fd()), true) if err != nil { + file.Close() return err } + file.Close() return nil } @@ -59,8 +88,10 @@ func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { // dual stack. See http://stackoverflow.com/questions/1618240/how-to-support-both-ipv4-and-ipv6-connections v6only, err := syscall.GetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY) if err != nil { + file.Close() return false, err } + file.Close() return v6only == 1, nil } @@ -69,5 +100,6 @@ func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) { if err != nil { return nil, err } + defer file.Close() return syscall.Getsockname(int(file.Fd())) } diff --git a/vendor/github.com/miekg/dns/udp_other.go b/vendor/github.com/miekg/dns/udp_other.go deleted file mode 100644 index d40732441..000000000 --- a/vendor/github.com/miekg/dns/udp_other.go +++ /dev/null @@ -1,17 +0,0 @@ -// +build !linux,!plan9 - -package dns - -import ( - "net" - "syscall" -) - -// These do nothing. See udp_linux.go for an example of how to implement this. - -// We tried to adhire to some kind of naming scheme. - -func setUDPSocketOptions4(conn *net.UDPConn) error { return nil } -func setUDPSocketOptions6(conn *net.UDPConn) error { return nil } -func getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil } -func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) { return nil, nil } diff --git a/vendor/github.com/miekg/dns/udp_plan9.go b/vendor/github.com/miekg/dns/udp_plan9.go deleted file mode 100644 index b794deeba..000000000 --- a/vendor/github.com/miekg/dns/udp_plan9.go +++ /dev/null @@ -1,34 +0,0 @@ -package dns - -import ( - "net" -) - -func setUDPSocketOptions(conn *net.UDPConn) error { return nil } - -// SessionUDP holds the remote address and the associated -// out-of-band data. -type SessionUDP struct { - raddr *net.UDPAddr - context []byte -} - -// 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. -func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { - oob := make([]byte, 40) - n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob) - if err != nil { - return n, nil, err - } - return n, &SessionUDP{raddr, oob[:oobn]}, err -} - -// WriteToSessionUDP acts just like net.UDPConn.WritetTo(), but uses a *SessionUDP instead of a net.Addr. -func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, error) { - n, _, err := conn.WriteMsgUDP(b, session.context, session.raddr) - return n, err -} diff --git a/vendor/github.com/miekg/dns/udp_windows.go b/vendor/github.com/miekg/dns/udp_windows.go index 2ce4b3300..51e532ac2 100644 --- a/vendor/github.com/miekg/dns/udp_windows.go +++ b/vendor/github.com/miekg/dns/udp_windows.go @@ -8,6 +8,8 @@ type SessionUDP struct { raddr *net.UDPAddr } +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. func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { @@ -25,10 +27,3 @@ func WriteToSessionUDP(conn *net.UDPConn, b []byte, session *SessionUDP) (int, e return n, err } -func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } - -// setUDPSocketOptions sets the UDP socket options. -// This function is implemented on a per platform basis. See udp_*.go for more details -func setUDPSocketOptions(conn *net.UDPConn) error { - return nil -} diff --git a/vendor/github.com/miekg/dns/zmsg.go b/vendor/github.com/miekg/dns/zmsg.go index c561370e7..94627e35e 100644 --- a/vendor/github.com/miekg/dns/zmsg.go +++ b/vendor/github.com/miekg/dns/zmsg.go @@ -221,7 +221,7 @@ func (rr *DNAME) pack(msg []byte, off int, compression map[string]int, compress return off, err } headerEnd := off - off, err = PackDomainName(rr.Target, msg, off, compression, compress) + off, err = PackDomainName(rr.Target, msg, off, compression, false) if err != nil { return off, err } @@ -447,7 +447,7 @@ func (rr *KX) pack(msg []byte, off int, compression map[string]int, compress boo if err != nil { return off, err } - off, err = PackDomainName(rr.Exchanger, msg, off, compression, compress) + off, err = PackDomainName(rr.Exchanger, msg, off, compression, false) if err != nil { return off, err } @@ -539,7 +539,7 @@ func (rr *LP) pack(msg []byte, off int, compression map[string]int, compress boo if err != nil { return off, err } - off, err = PackDomainName(rr.Fqdn, msg, off, compression, compress) + off, err = PackDomainName(rr.Fqdn, msg, off, compression, false) if err != nil { return off, err } @@ -679,7 +679,7 @@ func (rr *NAPTR) pack(msg []byte, off int, compression map[string]int, compress if err != nil { return off, err } - off, err = PackDomainName(rr.Replacement, msg, off, compression, compress) + off, err = PackDomainName(rr.Replacement, msg, off, compression, false) if err != nil { return off, err } @@ -753,7 +753,7 @@ func (rr *NSAPPTR) pack(msg []byte, off int, compression map[string]int, compres return off, err } headerEnd := off - off, err = PackDomainName(rr.Ptr, msg, off, compression, compress) + off, err = PackDomainName(rr.Ptr, msg, off, compression, false) if err != nil { return off, err } @@ -767,7 +767,7 @@ func (rr *NSEC) pack(msg []byte, off int, compression map[string]int, compress b return off, err } headerEnd := off - off, err = PackDomainName(rr.NextDomain, msg, off, compression, compress) + off, err = PackDomainName(rr.NextDomain, msg, off, compression, false) if err != nil { return off, err } @@ -905,11 +905,11 @@ func (rr *PX) pack(msg []byte, off int, compression map[string]int, compress boo if err != nil { return off, err } - off, err = PackDomainName(rr.Map822, msg, off, compression, compress) + off, err = PackDomainName(rr.Map822, msg, off, compression, false) if err != nil { return off, err } - off, err = PackDomainName(rr.Mapx400, msg, off, compression, compress) + off, err = PackDomainName(rr.Mapx400, msg, off, compression, false) if err != nil { return off, err } @@ -963,11 +963,11 @@ func (rr *RP) pack(msg []byte, off int, compression map[string]int, compress boo return off, err } headerEnd := off - off, err = PackDomainName(rr.Mbox, msg, off, compression, compress) + off, err = PackDomainName(rr.Mbox, msg, off, compression, false) if err != nil { return off, err } - off, err = PackDomainName(rr.Txt, msg, off, compression, compress) + off, err = PackDomainName(rr.Txt, msg, off, compression, false) if err != nil { return off, err } @@ -1009,7 +1009,7 @@ func (rr *RRSIG) pack(msg []byte, off int, compression map[string]int, compress if err != nil { return off, err } - off, err = PackDomainName(rr.SignerName, msg, off, compression, compress) + off, err = PackDomainName(rr.SignerName, msg, off, compression, false) if err != nil { return off, err } @@ -1073,7 +1073,7 @@ func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bo if err != nil { return off, err } - off, err = PackDomainName(rr.SignerName, msg, off, compression, compress) + off, err = PackDomainName(rr.SignerName, msg, off, compression, false) if err != nil { return off, err } @@ -1181,7 +1181,7 @@ func (rr *SRV) pack(msg []byte, off int, compression map[string]int, compress bo if err != nil { return off, err } - off, err = PackDomainName(rr.Target, msg, off, compression, compress) + off, err = PackDomainName(rr.Target, msg, off, compression, false) if err != nil { return off, err } @@ -1243,11 +1243,11 @@ func (rr *TALINK) pack(msg []byte, off int, compression map[string]int, compress return off, err } headerEnd := off - off, err = PackDomainName(rr.PreviousName, msg, off, compression, compress) + off, err = PackDomainName(rr.PreviousName, msg, off, compression, false) if err != nil { return off, err } - off, err = PackDomainName(rr.NextName, msg, off, compression, compress) + off, err = PackDomainName(rr.NextName, msg, off, compression, false) if err != nil { return off, err } @@ -1261,7 +1261,7 @@ func (rr *TKEY) pack(msg []byte, off int, compression map[string]int, compress b return off, err } headerEnd := off - off, err = PackDomainName(rr.Algorithm, msg, off, compression, compress) + off, err = PackDomainName(rr.Algorithm, msg, off, compression, false) if err != nil { return off, err } @@ -1333,7 +1333,7 @@ func (rr *TSIG) pack(msg []byte, off int, compression map[string]int, compress b return off, err } headerEnd := off - off, err = PackDomainName(rr.Algorithm, msg, off, compression, compress) + off, err = PackDomainName(rr.Algorithm, msg, off, compression, false) if err != nil { return off, err } diff --git a/vendor/vendor.json b/vendor/vendor.json index 631073955..2de3d820a 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -508,10 +508,10 @@ "revisionTime": "2015-04-06T19:39:34+02:00" }, { - "checksumSHA1": "Wahi4g/9XiHhSLAJ+8jskg71PCU=", + "checksumSHA1": "wJxkqZ80Ux6+klKr1+3erSZjVnQ=", "path": "github.com/miekg/dns", - "revision": "58f52c57ce9df13460ac68200cef30a008b9c468", - "revisionTime": "2016-10-18T06:08:08Z" + "revision": "672033dedc09500ca4d340760d0b80b9c0b198bd", + "revisionTime": "2017-02-13T20:16:50Z" }, { "checksumSHA1": "3YJklSuzSE1Rt8A+2dhiWSmf/fw=", From 865f28bb153434dc12ebe695a57ff39a9e3cfe44 Mon Sep 17 00:00:00 2001 From: James Hartig Date: Mon, 13 Feb 2017 15:48:51 -0500 Subject: [PATCH 2/2] discovery: Instead of looping over conf.Search, use NameList() --- discovery/dns/dns.go | 19 ++++--------------- 1 file changed, 4 insertions(+), 15 deletions(-) diff --git a/discovery/dns/dns.go b/discovery/dns/dns.go index ca9ed56fc..9890de4ae 100644 --- a/discovery/dns/dns.go +++ b/discovery/dns/dns.go @@ -179,13 +179,12 @@ func lookupAll(name string, qtype uint16) (*dns.Msg, error) { for _, server := range conf.Servers { servAddr := net.JoinHostPort(server, conf.Port) - for _, suffix := range conf.Search { - response, err = lookup(name, qtype, client, servAddr, suffix, false) + for _, lname := range conf.NameList(name) { + response, err = lookup(lname, qtype, client, servAddr, false) if err != nil { log. With("server", server). With("name", name). - With("suffix", suffix). With("reason", err). Warn("DNS resolution failed.") continue @@ -194,22 +193,12 @@ func lookupAll(name string, qtype uint16) (*dns.Msg, error) { return response, nil } } - response, err = lookup(name, qtype, client, servAddr, "", false) - if err == nil { - return response, nil - } - log. - With("server", server). - With("name", name). - With("reason", err). - Warn("DNS resolution failed.") } return response, fmt.Errorf("could not resolve %s: no server responded", name) } -func lookup(name string, queryType uint16, client *dns.Client, servAddr string, suffix string, edns bool) (*dns.Msg, error) { +func lookup(lname string, queryType uint16, client *dns.Client, servAddr string, edns bool) (*dns.Msg, error) { msg := &dns.Msg{} - lname := strings.Join([]string{name, suffix}, ".") msg.SetQuestion(dns.Fqdn(lname), queryType) if edns { @@ -224,7 +213,7 @@ func lookup(name string, queryType uint16, client *dns.Client, servAddr string, if edns { // Truncated even though EDNS is used client.Net = "tcp" } - return lookup(name, queryType, client, servAddr, suffix, !edns) + return lookup(lname, queryType, client, servAddr, !edns) } if err != nil { return nil, err