From 00dfe2e6da8cf684f11e9a5d7ce7d96bf3986ee1 Mon Sep 17 00:00:00 2001 From: Tom Limoncelli Date: Thu, 13 Jul 2017 18:36:33 -0400 Subject: [PATCH] Upgrade github.com/miekg --- vendor/github.com/miekg/dns/README.md | 10 +- vendor/github.com/miekg/dns/client.go | 28 +- vendor/github.com/miekg/dns/clientconfig.go | 32 +++ .../github.com/miekg/dns/compress_generate.go | 184 +++++++++++++ vendor/github.com/miekg/dns/dane.go | 43 +++ vendor/github.com/miekg/dns/defaults.go | 4 +- vendor/github.com/miekg/dns/dnssec.go | 21 +- vendor/github.com/miekg/dns/dnssec_keygen.go | 16 +- vendor/github.com/miekg/dns/dnssec_keyscan.go | 4 +- vendor/github.com/miekg/dns/doc.go | 2 +- vendor/github.com/miekg/dns/edns.go | 101 +++++-- vendor/github.com/miekg/dns/msg.go | 206 ++++---------- vendor/github.com/miekg/dns/msg_generate.go | 17 +- vendor/github.com/miekg/dns/msg_helpers.go | 7 +- vendor/github.com/miekg/dns/nsecx.go | 11 +- vendor/github.com/miekg/dns/reverse.go | 4 +- vendor/github.com/miekg/dns/scan.go | 15 +- vendor/github.com/miekg/dns/scan_rr.go | 258 ++++++++++-------- vendor/github.com/miekg/dns/server.go | 8 +- vendor/github.com/miekg/dns/sig0.go | 5 +- vendor/github.com/miekg/dns/smimea.go | 47 ++++ vendor/github.com/miekg/dns/tlsa.go | 39 --- vendor/github.com/miekg/dns/tsig.go | 3 +- vendor/github.com/miekg/dns/types.go | 66 +++-- vendor/github.com/miekg/dns/types_generate.go | 2 +- 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 | 6 +- vendor/github.com/miekg/dns/udp_plan9.go | 34 --- vendor/github.com/miekg/dns/udp_windows.go | 9 +- vendor/github.com/miekg/dns/zcompress.go | 119 ++++++++ vendor/github.com/miekg/dns/zmsg.go | 119 ++++++-- vendor/github.com/miekg/dns/ztypes.go | 66 +++-- vendor/vendor.json | 6 +- 34 files changed, 1030 insertions(+), 522 deletions(-) create mode 100644 vendor/github.com/miekg/dns/compress_generate.go create mode 100644 vendor/github.com/miekg/dns/dane.go create mode 100644 vendor/github.com/miekg/dns/smimea.go delete mode 100644 vendor/github.com/miekg/dns/udp_plan9.go create mode 100644 vendor/github.com/miekg/dns/zcompress.go diff --git a/vendor/github.com/miekg/dns/README.md b/vendor/github.com/miekg/dns/README.md index 83b4183eb..2acc7f1ff 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) # 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 @@ -24,6 +25,7 @@ two versions of Go, currently: 1.5 and 1.6. A not-so-up-to-date-list-that-may-be-actually-current: +* https://github.com/coredns/coredns * https://cloudflare.com * https://github.com/abh/geodns * http://www.statdns.com/ @@ -50,6 +52,11 @@ A not-so-up-to-date-list-that-may-be-actually-current: * https://dnslookup.org * https://github.com/looterz/grimd * https://github.com/phamhongviet/serf-dns +* https://github.com/mehrdadrad/mylg +* https://github.com/bamarni/dockness +* https://github.com/fffaraz/microdns +* http://quilt.io +* https://github.com/ipdcode/hades (JD.COM) Send pull request if you want to be listed here. @@ -138,6 +145,7 @@ Example programs can be found in the `github.com/miekg/exdns` repository. * 6975 - Algorithm Understanding in DNSSEC * 7043 - EUI48/EUI64 records * 7314 - DNS (EDNS) EXPIRE Option +* 7828 - edns-tcp-keepalive EDNS0 Option * 7553 - URI record * 7858 - DNS over TLS: Initiation and Performance Considerations (draft) * 7873 - Domain Name System (DNS) Cookies (draft-ietf-dnsop-cookies) diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go index 1302e4e04..301dab9c1 100644 --- a/vendor/github.com/miekg/dns/client.go +++ b/vendor/github.com/miekg/dns/client.go @@ -39,7 +39,7 @@ type Client struct { } // Exchange performs a synchronous UDP query. It sends the message m to the address -// contained in a and waits for an reply. Exchange does not retry a failed query, nor +// contained in a and waits for a reply. Exchange does not retry a failed query, nor // will it fall back to TCP in case of truncation. // See client.Exchange for more information on setting larger buffer sizes. func Exchange(m *Msg, a string) (r *Msg, err error) { @@ -93,8 +93,8 @@ func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) { return r, err } -// Exchange performs an synchronous query. It sends the message m to the address -// contained in a and waits for an reply. Basic use pattern with a *dns.Client: +// Exchange performs a synchronous query. It sends the message m to the address +// contained in a and waits for a reply. Basic use pattern with a *dns.Client: // // c := new(dns.Client) // in, rtt, err := c.Exchange(message, "127.0.0.1:53") @@ -103,7 +103,7 @@ func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) { // case of truncation. // It is up to the caller to create a message that allows for larger responses to be // returned. Specifically this means adding an EDNS0 OPT RR that will advertise a larger -// buffer, see SetEdns0. Messsages without an OPT RR will fallback to the historic limit +// buffer, see SetEdns0. Messages without an OPT RR will fallback to the historic limit // of 512 bytes. func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) { if !c.SingleInflight { @@ -121,12 +121,12 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) { return c.exchange(m, a) }) + if r != nil && shared { + r = r.Copy() + } if err != nil { return r, rtt, err } - if shared { - return r.Copy(), rtt, nil - } return r, rtt, nil } @@ -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/compress_generate.go b/vendor/github.com/miekg/dns/compress_generate.go new file mode 100644 index 000000000..1a301e9f3 --- /dev/null +++ b/vendor/github.com/miekg/dns/compress_generate.go @@ -0,0 +1,184 @@ +//+build ignore + +// compression_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 look to see if there are (compressible) names, if so it will add that +// type to compressionLenHelperType and comressionLenSearchType which "fake" the +// compression so that Len() is fast. +package main + +import ( + "bytes" + "fmt" + "go/format" + "go/importer" + "go/types" + "log" + "os" +) + +var packageHdr = ` +// *** DO NOT MODIFY *** +// AUTOGENERATED BY go generate from compress_generate.go + +package dns + +` + +// getTypeStruct will take a type and the package scope, and return the +// (innermost) struct if the type is considered a RR type (currently defined as +// those structs beginning with a RR_Header, could be redefined as implementing +// the RR interface). The bool return value indicates if embedded structs were +// resolved. +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() + + domainTypes := map[string]bool{} // Types that have a domain name in them (either comressible or not). + cdomainTypes := map[string]bool{} // Types that have a compressible domain name in them (subset of domainType) + for _, name := range scope.Names() { + o := scope.Lookup(name) + if o == nil || !o.Exported() { + continue + } + st, _ := getTypeStruct(o.Type(), scope) + if st == nil { + continue + } + if name == "PrivateRR" { + continue + } + + if scope.Lookup("Type"+o.Name()) == nil && o.Name() != "RFC3597" { + log.Fatalf("Constant Type%s does not exist.", o.Name()) + } + + for i := 1; i < st.NumFields(); i++ { + if _, ok := st.Field(i).Type().(*types.Slice); ok { + if st.Tag(i) == `dns:"domain-name"` { + domainTypes[o.Name()] = true + } + if st.Tag(i) == `dns:"cdomain-name"` { + cdomainTypes[o.Name()] = true + domainTypes[o.Name()] = true + } + continue + } + + switch { + case st.Tag(i) == `dns:"domain-name"`: + domainTypes[o.Name()] = true + case st.Tag(i) == `dns:"cdomain-name"`: + cdomainTypes[o.Name()] = true + domainTypes[o.Name()] = true + } + } + } + + b := &bytes.Buffer{} + b.WriteString(packageHdr) + + // compressionLenHelperType - all types that have domain-name/cdomain-name can be used for compressing names + + fmt.Fprint(b, "func compressionLenHelperType(c map[string]int, r RR) {\n") + fmt.Fprint(b, "switch x := r.(type) {\n") + for name, _ := range domainTypes { + o := scope.Lookup(name) + st, _ := getTypeStruct(o.Type(), scope) + + fmt.Fprintf(b, "case *%s:\n", name) + for i := 1; i < st.NumFields(); i++ { + out := func(s string) { fmt.Fprintf(b, "compressionLenHelper(c, x.%s)\n", st.Field(i).Name()) } + + if _, ok := st.Field(i).Type().(*types.Slice); ok { + switch st.Tag(i) { + case `dns:"domain-name"`: + fallthrough + case `dns:"cdomain-name"`: + // For HIP we need to slice over the elements in this slice. + fmt.Fprintf(b, `for i := range x.%s { + compressionLenHelper(c, x.%s[i]) + } +`, st.Field(i).Name(), st.Field(i).Name()) + } + continue + } + + switch { + case st.Tag(i) == `dns:"cdomain-name"`: + fallthrough + case st.Tag(i) == `dns:"domain-name"`: + out(st.Field(i).Name()) + } + } + } + fmt.Fprintln(b, "}\n}\n\n") + + // compressionLenSearchType - search cdomain-tags types for compressible names. + + fmt.Fprint(b, "func compressionLenSearchType(c map[string]int, r RR) (int, bool) {\n") + fmt.Fprint(b, "switch x := r.(type) {\n") + for name, _ := range cdomainTypes { + o := scope.Lookup(name) + st, _ := getTypeStruct(o.Type(), scope) + + fmt.Fprintf(b, "case *%s:\n", name) + j := 1 + for i := 1; i < st.NumFields(); i++ { + out := func(s string, j int) { + fmt.Fprintf(b, "k%d, ok%d := compressionLenSearch(c, x.%s)\n", j, j, st.Field(i).Name()) + } + + // There are no slice types with names that can be compressed. + + switch { + case st.Tag(i) == `dns:"cdomain-name"`: + out(st.Field(i).Name(), j) + j++ + } + } + k := "k1" + ok := "ok1" + for i := 2; i < j; i++ { + k += fmt.Sprintf(" + k%d", i) + ok += fmt.Sprintf(" && ok%d", i) + } + fmt.Fprintf(b, "return %s, %s\n", k, ok) + } + fmt.Fprintln(b, "}\nreturn 0, false\n}\n\n") + + // gofmt + res, err := format.Source(b.Bytes()) + if err != nil { + b.WriteTo(os.Stderr) + log.Fatal(err) + } + + f, err := os.Create("zcompress.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/dane.go b/vendor/github.com/miekg/dns/dane.go new file mode 100644 index 000000000..8c4a14ef1 --- /dev/null +++ b/vendor/github.com/miekg/dns/dane.go @@ -0,0 +1,43 @@ +package dns + +import ( + "crypto/sha256" + "crypto/sha512" + "crypto/x509" + "encoding/hex" + "errors" +) + +// CertificateToDANE converts a certificate to a hex string as used in the TLSA or SMIMEA records. +func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) { + switch matchingType { + case 0: + switch selector { + case 0: + return hex.EncodeToString(cert.Raw), nil + case 1: + return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil + } + case 1: + h := sha256.New() + switch selector { + case 0: + h.Write(cert.Raw) + return hex.EncodeToString(h.Sum(nil)), nil + case 1: + h.Write(cert.RawSubjectPublicKeyInfo) + return hex.EncodeToString(h.Sum(nil)), nil + } + case 2: + h := sha512.New() + switch selector { + case 0: + h.Write(cert.Raw) + return hex.EncodeToString(h.Sum(nil)), nil + case 1: + h.Write(cert.RawSubjectPublicKeyInfo) + return hex.EncodeToString(h.Sum(nil)), nil + } + } + return "", errors.New("dns: bad MatchingType or Selector") +} 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..07262011e 100644 --- a/vendor/github.com/miekg/dns/dnssec.go +++ b/vendor/github.com/miekg/dns/dnssec.go @@ -43,7 +43,7 @@ const ( PRIVATEOID uint8 = 254 ) -// Map for algorithm names. +// AlgorithmToString is a map of algorithm IDs to algorithm names. var AlgorithmToString = map[uint8]string{ RSAMD5: "RSAMD5", DH: "DH", @@ -61,10 +61,10 @@ var AlgorithmToString = map[uint8]string{ PRIVATEOID: "PRIVATEOID", } -// Map of algorithm strings. +// StringToAlgorithm is the reverse of AlgorithmToString. var StringToAlgorithm = reverseInt8(AlgorithmToString) -// Map of algorithm crypto hashes. +// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's. var AlgorithmToHash = map[uint8]crypto.Hash{ RSAMD5: crypto.MD5, // Deprecated in RFC 6725 RSASHA1: crypto.SHA1, @@ -85,7 +85,7 @@ const ( SHA512 // Experimental ) -// Map for hash names. +// HashToString is a map of hash IDs to names. var HashToString = map[uint8]string{ SHA1: "SHA1", SHA256: "SHA256", @@ -94,7 +94,7 @@ var HashToString = map[uint8]string{ SHA512: "SHA512", } -// Map of hash strings. +// StringToHash is a map of names to hash IDs. var StringToHash = reverseInt8(HashToString) // DNSKEY flag values. @@ -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/dnssec_keyscan.go b/vendor/github.com/miekg/dns/dnssec_keyscan.go index c0b54dc76..4f8d830b8 100644 --- a/vendor/github.com/miekg/dns/dnssec_keyscan.go +++ b/vendor/github.com/miekg/dns/dnssec_keyscan.go @@ -14,7 +14,7 @@ import ( // NewPrivateKey returns a PrivateKey by parsing the string s. // s should be in the same form of the BIND private key files. func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) { - if s[len(s)-1] != '\n' { // We need a closing newline + if s == "" || s[len(s)-1] != '\n' { // We need a closing newline return k.ReadPrivateKey(strings.NewReader(s+"\n"), "") } return k.ReadPrivateKey(strings.NewReader(s), "") @@ -36,7 +36,7 @@ func (k *DNSKEY) ReadPrivateKey(q io.Reader, file string) (crypto.PrivateKey, er return nil, ErrPrivKey } // TODO(mg): check if the pubkey matches the private key - algo, err := strconv.Atoi(strings.SplitN(m["algorithm"], " ", 2)[0]) + algo, err := strconv.ParseUint(strings.SplitN(m["algorithm"], " ", 2)[0], 10, 8) if err != nil { return nil, ErrPrivKey } diff --git a/vendor/github.com/miekg/dns/doc.go b/vendor/github.com/miekg/dns/doc.go index f3555e433..e38753d7d 100644 --- a/vendor/github.com/miekg/dns/doc.go +++ b/vendor/github.com/miekg/dns/doc.go @@ -203,7 +203,7 @@ RFC 6895 sets aside a range of type codes for private use. This range is 65,280 - 65,534 (0xFF00 - 0xFFFE). When experimenting with new Resource Records these can be used, before requesting an official type code from IANA. -see http://miek.nl/posts/2014/Sep/21/Private%20RRs%20and%20IDN%20in%20Go%20DNS/ for more +see http://miek.nl/2014/September/21/idn-and-private-rr-in-go-dns/ for more information. EDNS0 diff --git a/vendor/github.com/miekg/dns/edns.go b/vendor/github.com/miekg/dns/edns.go index 7a58aa9b1..dbff3714c 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. @@ -128,8 +130,18 @@ func (rr *OPT) Do() bool { } // SetDo sets the DO (DNSSEC OK) bit. -func (rr *OPT) SetDo() { - rr.Hdr.Ttl |= _DO +// If we pass an argument, set the DO bit to that value. +// It is possible to pass 2 or more arguments. Any arguments after the 1st is silently ignored. +func (rr *OPT) SetDo(do ...bool) { + if len(do) == 1 { + if do[0] { + rr.Hdr.Ttl |= _DO + } else { + rr.Hdr.Ttl &^= _DO + } + } else { + rr.Hdr.Ttl |= _DO + } } // EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it. @@ -145,7 +157,7 @@ type EDNS0 interface { String() string } -// The nsid EDNS0 option is used to retrieve a nameserver +// EDNS0_NSID option is used to retrieve a nameserver // identifier. When sending a request Nsid must be set to the empty string // The identifier is an opaque string encoded as hex. // Basic use pattern for creating an nsid option: @@ -185,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 @@ -289,7 +301,7 @@ func (e *EDNS0_SUBNET) String() (s string) { return } -// The Cookie EDNS0 option +// The EDNS0_COOKIE option is used to add a DNS Cookie to a message. // // o := new(dns.OPT) // o.Hdr.Name = "." @@ -530,3 +542,56 @@ func (e *EDNS0_LOCAL) unpack(b []byte) error { } return nil } + +// EDNS0_TCP_KEEPALIVE is an EDNS0 option that instructs the server to keep +// the TCP connection alive. See RFC 7828. +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 ec2f7ab7b..57262a10c 100644 --- a/vendor/github.com/miekg/dns/msg.go +++ b/vendor/github.com/miekg/dns/msg.go @@ -9,6 +9,7 @@ package dns //go:generate go run msg_generate.go +//go:generate go run compress_generate.go import ( crand "crypto/rand" @@ -16,22 +17,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 ( @@ -58,7 +46,7 @@ var ( ErrTruncated error = &Error{err: "failed to unpack truncated message"} // ErrTruncated indicates that we failed to unpack a truncated message. We unpacked as much as we had so Msg can still be used, if desired. ) -// Id, by default, returns a 16 bits random number to be used as a +// Id by default, returns a 16 bits random number to be used as a // message id. The random provided should be good enough. This being a // variable the function can be reassigned to a custom function. // For instance, to make it return a static value: @@ -66,11 +54,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 +225,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 @@ -247,7 +263,9 @@ func packDomainName(s string, msg []byte, off int, compression map[string]int, c bsFresh = true } // Don't try to compress '.' - if compress && roBs[begin:] != "." { + // We should only compress when compress it true, but we should also still pick + // up names that can be used for *future* compression(s). + if compression != nil && roBs[begin:] != "." { if p, ok := compression[roBs[begin:]]; !ok { // Only offsets smaller than this can be used. if offset < maxCompressionOffset { @@ -335,10 +353,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 +445,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 +516,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 @@ -732,12 +734,10 @@ func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) { // We need the uncompressed length here, because we first pack it and then compress it. msg = buf - compress := dns.Compress - dns.Compress = false - if packLen := dns.Len() + 1; len(msg) < packLen { + uncompressedLen := compressedLen(dns, false) + if packLen := uncompressedLen + 1; len(msg) < packLen { msg = make([]byte, packLen) } - dns.Compress = compress // Pack it in: header and then the pieces. off := 0 @@ -781,9 +781,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 +794,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)) @@ -889,16 +890,18 @@ func (dns *Msg) String() string { // If dns.Compress is true compression it is taken into account. Len() // is provided to be a faster way to get the size of the resulting packet, // than packing it, measuring the size and discarding the buffer. -func (dns *Msg) Len() int { +func (dns *Msg) Len() int { return compressedLen(dns, dns.Compress) } + +// compressedLen returns the message length when in compressed wire format +// when compress is true, otherwise the uncompressed length is returned. +func compressedLen(dns *Msg, compress bool) int { // We always return one more than needed. l := 12 // Message header is always 12 bytes - var compression map[string]int - if dns.Compress { - compression = make(map[string]int) - } + compression := map[string]int{} + for i := 0; i < len(dns.Question); i++ { l += dns.Question[i].len() - if dns.Compress { + if compress { compressionLenHelper(compression, dns.Question[i].Name) } } @@ -907,7 +910,7 @@ func (dns *Msg) Len() int { continue } l += dns.Answer[i].len() - if dns.Compress { + if compress { k, ok := compressionLenSearch(compression, dns.Answer[i].Header().Name) if ok { l += 1 - k @@ -925,7 +928,7 @@ func (dns *Msg) Len() int { continue } l += dns.Ns[i].len() - if dns.Compress { + if compress { k, ok := compressionLenSearch(compression, dns.Ns[i].Header().Name) if ok { l += 1 - k @@ -943,7 +946,7 @@ func (dns *Msg) Len() int { continue } l += dns.Extra[i].len() - if dns.Compress { + if compress { k, ok := compressionLenSearch(compression, dns.Extra[i].Header().Name) if ok { l += 1 - k @@ -991,97 +994,6 @@ func compressionLenSearch(c map[string]int, s string) (int, bool) { return 0, false } -// TODO(miek): should add all types, because the all can be *used* for compression. Autogenerate from msg_generate and put in zmsg.go -func compressionLenHelperType(c map[string]int, r RR) { - switch x := r.(type) { - case *NS: - compressionLenHelper(c, x.Ns) - case *MX: - compressionLenHelper(c, x.Mx) - case *CNAME: - compressionLenHelper(c, x.Target) - case *PTR: - compressionLenHelper(c, x.Ptr) - case *SOA: - compressionLenHelper(c, x.Ns) - compressionLenHelper(c, x.Mbox) - case *MB: - compressionLenHelper(c, x.Mb) - case *MG: - compressionLenHelper(c, x.Mg) - case *MR: - compressionLenHelper(c, x.Mr) - case *MF: - compressionLenHelper(c, x.Mf) - case *MD: - compressionLenHelper(c, x.Md) - case *RT: - compressionLenHelper(c, x.Host) - case *RP: - compressionLenHelper(c, x.Mbox) - compressionLenHelper(c, x.Txt) - case *MINFO: - compressionLenHelper(c, x.Rmail) - compressionLenHelper(c, x.Email) - case *AFSDB: - compressionLenHelper(c, x.Hostname) - case *SRV: - compressionLenHelper(c, x.Target) - case *NAPTR: - compressionLenHelper(c, x.Replacement) - case *RRSIG: - compressionLenHelper(c, x.SignerName) - case *NSEC: - compressionLenHelper(c, x.NextDomain) - // HIP? - } -} - -// Only search on compressing these types. -func compressionLenSearchType(c map[string]int, r RR) (int, bool) { - switch x := r.(type) { - case *NS: - return compressionLenSearch(c, x.Ns) - case *MX: - return compressionLenSearch(c, x.Mx) - case *CNAME: - return compressionLenSearch(c, x.Target) - case *DNAME: - return compressionLenSearch(c, x.Target) - case *PTR: - return compressionLenSearch(c, x.Ptr) - case *SOA: - k, ok := compressionLenSearch(c, x.Ns) - k1, ok1 := compressionLenSearch(c, x.Mbox) - if !ok && !ok1 { - return 0, false - } - return k + k1, true - case *MB: - return compressionLenSearch(c, x.Mb) - case *MG: - return compressionLenSearch(c, x.Mg) - case *MR: - return compressionLenSearch(c, x.Mr) - case *MF: - return compressionLenSearch(c, x.Mf) - case *MD: - return compressionLenSearch(c, x.Md) - case *RT: - return compressionLenSearch(c, x.Host) - case *MINFO: - k, ok := compressionLenSearch(c, x.Rmail) - k1, ok1 := compressionLenSearch(c, x.Email) - if !ok && !ok1 { - return 0, false - } - return k + k1, true - case *AFSDB: - return compressionLenSearch(c, x.Hostname) - } - return 0, false -} - // Copy returns a new RR which is a deep-copy of r. func Copy(r RR) RR { r1 := r.copy(); return r1 } diff --git a/vendor/github.com/miekg/dns/msg_generate.go b/vendor/github.com/miekg/dns/msg_generate.go index 35786f22c..4d9f81d43 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"`: @@ -139,8 +139,17 @@ return off, err case st.Tag(i) == `dns:"base64"`: o("off, err = packStringBase64(rr.%s, msg, off)\n") - case strings.HasPrefix(st.Tag(i), `dns:"size-hex:SaltLength`): // Hack to fix empty salt length for NSEC3 - o("if rr.%s == \"-\" { /* do nothing, empty salt */ }\n") + case strings.HasPrefix(st.Tag(i), `dns:"size-hex:SaltLength`): + // directly write instead of using o() so we get the error check in the correct place + field := st.Field(i).Name() + fmt.Fprintf(b, `// Only pack salt if value is not "-", i.e. empty +if rr.%s != "-" { + off, err = packStringHex(rr.%s, msg, off) + if err != nil { + return off, err + } +} +`, field, field) continue case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex fallthrough diff --git a/vendor/github.com/miekg/dns/msg_helpers.go b/vendor/github.com/miekg/dns/msg_helpers.go index e7a9500cc..615274ab0 100644 --- a/vendor/github.com/miekg/dns/msg_helpers.go +++ b/vendor/github.com/miekg/dns/msg_helpers.go @@ -142,6 +142,11 @@ func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []b } func fromBase32(s []byte) (buf []byte, err error) { + for i, b := range s { + if b >= 'a' && b <= 'z' { + s[i] = b - 32 + } + } buflen := base32.HexEncoding.DecodedLen(len(s)) buf = make([]byte, buflen) n, err := base32.HexEncoding.Decode(buf, s) @@ -263,8 +268,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/reverse.go b/vendor/github.com/miekg/dns/reverse.go index 099dac948..f6e7a47a6 100644 --- a/vendor/github.com/miekg/dns/reverse.go +++ b/vendor/github.com/miekg/dns/reverse.go @@ -6,10 +6,10 @@ var StringToType = reverseInt16(TypeToString) // StringToClass is the reverse of ClassToString, needed for string parsing. var StringToClass = reverseInt16(ClassToString) -// Map of opcodes strings. +// StringToOpcode is a map of opcodes to strings. var StringToOpcode = reverseInt(OpcodeToString) -// Map of rcodes strings. +// StringToRcode is a map of rcodes to strings. var StringToRcode = reverseInt(RcodeToString) // Reverse a map diff --git a/vendor/github.com/miekg/dns/scan.go b/vendor/github.com/miekg/dns/scan.go index 0e83797fb..de0db32f8 100644 --- a/vendor/github.com/miekg/dns/scan.go +++ b/vendor/github.com/miekg/dns/scan.go @@ -627,6 +627,7 @@ func zlexer(s *scan, c chan lex) { if stri > 0 { l.value = zString l.token = string(str[:stri]) + l.tokenUpper = strings.ToUpper(l.token) l.length = stri debug.Printf("[4 %+v]", l.token) c <- l @@ -663,6 +664,7 @@ func zlexer(s *scan, c chan lex) { owner = true l.value = zNewline l.token = "\n" + l.tokenUpper = l.token l.length = 1 l.comment = string(com[:comi]) debug.Printf("[3 %+v %+v]", l.token, l.comment) @@ -696,6 +698,7 @@ func zlexer(s *scan, c chan lex) { } l.value = zNewline l.token = "\n" + l.tokenUpper = l.token l.length = 1 debug.Printf("[1 %+v]", l.token) c <- l @@ -740,6 +743,7 @@ func zlexer(s *scan, c chan lex) { if stri != 0 { l.value = zString l.token = string(str[:stri]) + l.tokenUpper = strings.ToUpper(l.token) l.length = stri debug.Printf("[%+v]", l.token) @@ -750,6 +754,7 @@ func zlexer(s *scan, c chan lex) { // send quote itself as separate token l.value = zQuote l.token = "\"" + l.tokenUpper = l.token l.length = 1 c <- l quote = !quote @@ -775,6 +780,7 @@ func zlexer(s *scan, c chan lex) { brace-- if brace < 0 { l.token = "extra closing brace" + l.tokenUpper = l.token l.err = true debug.Printf("[%+v]", l.token) c <- l @@ -799,6 +805,7 @@ func zlexer(s *scan, c chan lex) { if stri > 0 { // Send remainder l.token = string(str[:stri]) + l.tokenUpper = strings.ToUpper(l.token) l.length = stri l.value = zString debug.Printf("[%+v]", l.token) @@ -812,8 +819,8 @@ func classToInt(token string) (uint16, bool) { if len(token) < offset+1 { return 0, false } - class, ok := strconv.Atoi(token[offset:]) - if ok != nil || class > maxUint16 { + class, err := strconv.ParseUint(token[offset:], 10, 16) + if err != nil { return 0, false } return uint16(class), true @@ -825,8 +832,8 @@ func typeToInt(token string) (uint16, bool) { if len(token) < offset+1 { return 0, false } - typ, ok := strconv.Atoi(token[offset:]) - if ok != nil || typ > maxUint16 { + typ, err := strconv.ParseUint(token[offset:], 10, 16) + if err != nil { return 0, false } return uint16(typ), true diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go index e521dc063..f4c0d3767 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 } @@ -458,7 +447,7 @@ func setMX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad MX Pref", l}, "" } @@ -487,7 +476,7 @@ func setRT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil { return nil, &ParseError{f, "bad RT Preference", l}, "" } @@ -517,7 +506,7 @@ func setAFSDB(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad AFSDB Subtype", l}, "" } @@ -562,7 +551,7 @@ func setKX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad KX Pref", l}, "" } @@ -676,7 +665,7 @@ func setSOA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.err { return nil, &ParseError{f, "bad SOA zone parameter", l}, "" } - if j, e := strconv.Atoi(l.token); e != nil { + if j, e := strconv.ParseUint(l.token, 10, 32); e != nil { if i == 0 { // Serial should be a number return nil, &ParseError{f, "bad SOA zone parameter", l}, "" @@ -716,21 +705,21 @@ func setSRV(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad SRV Priority", l}, "" } rr.Priority = uint16(i) <-c // zBlank l = <-c // zString - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad SRV Weight", l}, "" } rr.Weight = uint16(i) <-c // zBlank l = <-c // zString - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad SRV Port", l}, "" } @@ -760,14 +749,14 @@ func setNAPTR(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad NAPTR Order", l}, "" } rr.Order = uint16(i) <-c // zBlank l = <-c // zString - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad NAPTR Preference", l}, "" } @@ -896,7 +885,7 @@ func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 32) if e != nil || l.err { return nil, &ParseError{f, "bad LOC Latitude", l}, "" } @@ -908,7 +897,7 @@ func setLOC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok { goto East } - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 32) if e != nil || l.err { return nil, &ParseError{f, "bad LOC Latitude minutes", l}, "" } @@ -934,7 +923,7 @@ East: // East <-c // zBlank l = <-c - if i, e := strconv.Atoi(l.token); e != nil || l.err { + if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { return nil, &ParseError{f, "bad LOC Longitude", l}, "" } else { rr.Longitude = 1000 * 60 * 60 * uint32(i) @@ -945,7 +934,7 @@ East: if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { goto Altitude } - if i, e := strconv.Atoi(l.token); e != nil || l.err { + if i, e := strconv.ParseUint(l.token, 10, 32); e != nil || l.err { return nil, &ParseError{f, "bad LOC Longitude minutes", l}, "" } else { rr.Longitude += 1000 * 60 * uint32(i) @@ -1027,7 +1016,7 @@ func setHIP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, l.comment } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad HIP PublicKeyAlgorithm", l}, "" } @@ -1088,14 +1077,14 @@ func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { } if v, ok := StringToCertType[l.token]; ok { rr.Type = v - } else if i, e := strconv.Atoi(l.token); e != nil { + } else if i, e := strconv.ParseUint(l.token, 10, 16); e != nil { return nil, &ParseError{f, "bad CERT Type", l}, "" } else { rr.Type = uint16(i) } <-c // zBlank l = <-c // zString - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad CERT KeyTag", l}, "" } @@ -1104,7 +1093,7 @@ func setCERT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { l = <-c // zString if v, ok := StringToAlgorithm[l.token]; ok { rr.Algorithm = v - } else if i, e := strconv.Atoi(l.token); e != nil { + } else if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { return nil, &ParseError{f, "bad CERT Algorithm", l}, "" } else { rr.Algorithm = uint8(i) @@ -1159,21 +1148,21 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { } <-c // zBlank l = <-c - i, err := strconv.Atoi(l.token) + i, err := strconv.ParseUint(l.token, 10, 8) if err != nil || l.err { return nil, &ParseError{f, "bad RRSIG Algorithm", l}, "" } rr.Algorithm = uint8(i) <-c // zBlank l = <-c - i, err = strconv.Atoi(l.token) + i, err = strconv.ParseUint(l.token, 10, 8) if err != nil || l.err { return nil, &ParseError{f, "bad RRSIG Labels", l}, "" } rr.Labels = uint8(i) <-c // zBlank l = <-c - i, err = strconv.Atoi(l.token) + i, err = strconv.ParseUint(l.token, 10, 32) if err != nil || l.err { return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, "" } @@ -1204,7 +1193,7 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { } <-c // zBlank l = <-c - i, err = strconv.Atoi(l.token) + i, err = strconv.ParseUint(l.token, 10, 16) if err != nil || l.err { return nil, &ParseError{f, "bad RRSIG KeyTag", l}, "" } @@ -1285,21 +1274,21 @@ func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, l.comment } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad NSEC3 Hash", l}, "" } rr.Hash = uint8(i) <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad NSEC3 Flags", l}, "" } rr.Flags = uint8(i) <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad NSEC3 Iterations", l}, "" } @@ -1353,21 +1342,21 @@ func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, strin if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, "" } rr.Hash = uint8(i) <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, "" } rr.Flags = uint8(i) <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, "" } @@ -1451,14 +1440,14 @@ func setSSHFP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad SSHFP Algorithm", l}, "" } rr.Algorithm = uint8(i) <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad SSHFP Type", l}, "" } @@ -1480,21 +1469,21 @@ func setDNSKEYs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, str if l.length == 0 { return rr, nil, l.comment } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad " + typ + " Flags", l}, "" } rr.Flags = uint16(i) <-c // zBlank l = <-c // zString - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad " + typ + " Protocol", l}, "" } rr.Protocol = uint8(i) <-c // zBlank l = <-c // zString - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" } @@ -1536,21 +1525,21 @@ func setRKEY(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, l.comment } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad RKEY Flags", l}, "" } rr.Flags = uint16(i) <-c // zBlank l = <-c // zString - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad RKEY Protocol", l}, "" } rr.Protocol = uint8(i) <-c // zBlank l = <-c // zString - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad RKEY Algorithm", l}, "" } @@ -1621,14 +1610,14 @@ func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) if l.length == 0 { return rr, nil, l.comment } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, "" } rr.KeyTag = uint16(i) <-c // zBlank l = <-c - if i, e := strconv.Atoi(l.token); e != nil { + if i, e = strconv.ParseUint(l.token, 10, 8); e != nil { i, ok := StringToAlgorithm[l.tokenUpper] if !ok || l.err { return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" @@ -1639,7 +1628,7 @@ func setDSs(h RR_Header, c chan lex, o, f, typ string) (RR, *ParseError, string) } <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad " + typ + " DigestType", l}, "" } @@ -1680,14 +1669,14 @@ func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, l.comment } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad TA KeyTag", l}, "" } rr.KeyTag = uint16(i) <-c // zBlank l = <-c - if i, e := strconv.Atoi(l.token); e != nil { + if i, e := strconv.ParseUint(l.token, 10, 8); e != nil { i, ok := StringToAlgorithm[l.tokenUpper] if !ok || l.err { return nil, &ParseError{f, "bad TA Algorithm", l}, "" @@ -1698,7 +1687,7 @@ func setTA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { } <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad TA DigestType", l}, "" } @@ -1718,21 +1707,21 @@ func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, l.comment } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad TLSA Usage", l}, "" } rr.Usage = uint8(i) <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad TLSA Selector", l}, "" } rr.Selector = uint8(i) <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 8) if e != nil || l.err { return nil, &ParseError{f, "bad TLSA MatchingType", l}, "" } @@ -1746,6 +1735,41 @@ func setTLSA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { return rr, nil, c1 } +func setSMIMEA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { + rr := new(SMIMEA) + rr.Hdr = h + l := <-c + if l.length == 0 { + return rr, nil, l.comment + } + i, e := strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return nil, &ParseError{f, "bad SMIMEA Usage", l}, "" + } + rr.Usage = uint8(i) + <-c // zBlank + l = <-c + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return nil, &ParseError{f, "bad SMIMEA Selector", l}, "" + } + rr.Selector = uint8(i) + <-c // zBlank + l = <-c + i, e = strconv.ParseUint(l.token, 10, 8) + if e != nil || l.err { + return nil, &ParseError{f, "bad SMIMEA MatchingType", l}, "" + } + rr.MatchingType = uint8(i) + // So this needs be e2 (i.e. different than e), because...??t + s, e2, c1 := endingToString(c, "bad SMIMEA Certificate", f) + if e2 != nil { + return nil, e2, c1 + } + rr.Certificate = s + return rr, nil, c1 +} + func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { rr := new(RFC3597) rr.Hdr = h @@ -1818,14 +1842,14 @@ func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad URI Priority", l}, "" } rr.Priority = uint16(i) <-c // zBlank l = <-c - i, e = strconv.Atoi(l.token) + i, e = strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad URI Weight", l}, "" } @@ -1864,7 +1888,7 @@ func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad NID Preference", l}, "" } @@ -1887,7 +1911,7 @@ func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad L32 Preference", l}, "" } @@ -1909,7 +1933,7 @@ func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad LP Preference", l}, "" } @@ -1942,7 +1966,7 @@ func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad L64 Preference", l}, "" } @@ -1964,7 +1988,7 @@ func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 32) if e != nil || l.err { return nil, &ParseError{f, "bad UID Uid", l}, "" } @@ -1979,7 +2003,7 @@ func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 32) if e != nil || l.err { return nil, &ParseError{f, "bad GID Gid", l}, "" } @@ -1992,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 } @@ -2006,7 +2033,7 @@ func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, "" } - i, e := strconv.Atoi(l.token) + i, e := strconv.ParseUint(l.token, 10, 16) if e != nil || l.err { return nil, &ParseError{f, "bad PX Preference", l}, "" } @@ -2052,7 +2079,7 @@ func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { if l.length == 0 { return rr, nil, l.comment } - i, err := strconv.Atoi(l.token) + i, err := strconv.ParseUint(l.token, 10, 8) if err != nil || l.err { return nil, &ParseError{f, "bad CAA Flag", l}, "" } @@ -2128,6 +2155,7 @@ var typeToparserFunc = map[uint16]parserFunc{ TypeRP: {setRP, false}, TypeRRSIG: {setRRSIG, true}, TypeRT: {setRT, false}, + TypeSMIMEA: {setSMIMEA, true}, TypeSOA: {setSOA, false}, TypeSPF: {setSPF, true}, TypeSRV: {setSRV, false}, diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go index 2b4bff49f..0ca6e008c 100644 --- a/vendor/github.com/miekg/dns/server.go +++ b/vendor/github.com/miekg/dns/server.go @@ -147,7 +147,7 @@ func (mux *ServeMux) match(q string, t uint16) Handler { b[i] |= ('a' - 'A') } } - if h, ok := mux.z[string(b[:l])]; ok { // 'causes garbage, might want to change the map key + if h, ok := mux.z[string(b[:l])]; ok { // causes garbage, might want to change the map key if t != TypeDS { return h } @@ -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/smimea.go b/vendor/github.com/miekg/dns/smimea.go new file mode 100644 index 000000000..4e7ded4b3 --- /dev/null +++ b/vendor/github.com/miekg/dns/smimea.go @@ -0,0 +1,47 @@ +package dns + +import ( + "crypto/sha256" + "crypto/x509" + "encoding/hex" +) + +// Sign creates a SMIMEA record from an SSL certificate. +func (r *SMIMEA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { + r.Hdr.Rrtype = TypeSMIMEA + r.Usage = uint8(usage) + r.Selector = uint8(selector) + r.MatchingType = uint8(matchingType) + + r.Certificate, err = CertificateToDANE(r.Selector, r.MatchingType, cert) + if err != nil { + return err + } + return nil +} + +// Verify verifies a SMIMEA record against an SSL certificate. If it is OK +// a nil error is returned. +func (r *SMIMEA) Verify(cert *x509.Certificate) error { + c, err := CertificateToDANE(r.Selector, r.MatchingType, cert) + if err != nil { + return err // Not also ErrSig? + } + if r.Certificate == c { + return nil + } + return ErrSig // ErrSig, really? +} + +// SMIMEAName returns the ownername of a SMIMEA resource record as per the +// format specified in RFC 'draft-ietf-dane-smime-12' Section 2 and 3 +func SMIMEAName(email, domain string) (string, error) { + hasher := sha256.New() + hasher.Write([]byte(email)) + + // RFC Section 3: "The local-part is hashed using the SHA2-256 + // algorithm with the hash truncated to 28 octets and + // represented in its hexadecimal representation to become the + // left-most label in the prepared domain name" + return hex.EncodeToString(hasher.Sum(nil)[:28]) + "." + "_smimecert." + domain, nil +} diff --git a/vendor/github.com/miekg/dns/tlsa.go b/vendor/github.com/miekg/dns/tlsa.go index 34fe6615a..431e2fb5a 100644 --- a/vendor/github.com/miekg/dns/tlsa.go +++ b/vendor/github.com/miekg/dns/tlsa.go @@ -1,50 +1,11 @@ package dns import ( - "crypto/sha256" - "crypto/sha512" "crypto/x509" - "encoding/hex" - "errors" - "io" "net" "strconv" ) -// CertificateToDANE converts a certificate to a hex string as used in the TLSA record. -func CertificateToDANE(selector, matchingType uint8, cert *x509.Certificate) (string, error) { - switch matchingType { - case 0: - switch selector { - case 0: - return hex.EncodeToString(cert.Raw), nil - case 1: - return hex.EncodeToString(cert.RawSubjectPublicKeyInfo), nil - } - case 1: - h := sha256.New() - switch selector { - case 0: - io.WriteString(h, string(cert.Raw)) - return hex.EncodeToString(h.Sum(nil)), nil - case 1: - io.WriteString(h, string(cert.RawSubjectPublicKeyInfo)) - return hex.EncodeToString(h.Sum(nil)), nil - } - case 2: - h := sha512.New() - switch selector { - case 0: - io.WriteString(h, string(cert.Raw)) - return hex.EncodeToString(h.Sum(nil)), nil - case 1: - io.WriteString(h, string(cert.RawSubjectPublicKeyInfo)) - return hex.EncodeToString(h.Sum(nil)), nil - } - } - return "", errors.New("dns: bad TLSA MatchingType or TLSA Selector") -} - // Sign creates a TLSA record from an SSL certificate. func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { r.Hdr.Rrtype = TypeTLSA 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 5059d1a79..c17251cb6 100644 --- a/vendor/github.com/miekg/dns/types.go +++ b/vendor/github.com/miekg/dns/types.go @@ -70,6 +70,7 @@ const ( TypeNSEC3 uint16 = 50 TypeNSEC3PARAM uint16 = 51 TypeTLSA uint16 = 52 + TypeSMIMEA uint16 = 53 TypeHIP uint16 = 55 TypeNINFO uint16 = 56 TypeRKEY uint16 = 57 @@ -143,7 +144,7 @@ const ( OpcodeUpdate = 5 ) -// Headers is the wire format for the DNS packet header. +// Header is the wire format for the DNS packet header. type Header struct { Id uint16 Bits uint16 @@ -479,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) } @@ -524,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 { @@ -1047,6 +1033,28 @@ func (rr *TLSA) String() string { " " + rr.Certificate } +type SMIMEA struct { + Hdr RR_Header + Usage uint8 + Selector uint8 + MatchingType uint8 + Certificate string `dns:"hex"` +} + +func (rr *SMIMEA) String() string { + s := rr.Hdr.String() + + strconv.Itoa(int(rr.Usage)) + + " " + strconv.Itoa(int(rr.Selector)) + + " " + strconv.Itoa(int(rr.MatchingType)) + + // Every Nth char needs a space on this output. If we output + // this as one giant line, we can't read it can in because in some cases + // the cert length overflows scan.maxTok (2048). + sx := splitN(rr.Certificate, 1024) // conservative value here + s += " " + strings.Join(sx, " ") + return s +} + type HIP struct { Hdr RR_Header HitLength uint8 @@ -1247,3 +1255,25 @@ func copyIP(ip net.IP) net.IP { copy(p, ip) return p } + +// SplitN splits a string into N sized string chunks. +// This might become an exported function once. +func splitN(s string, n int) []string { + if len(s) < n { + return []string{s} + } + sx := []string{} + p, i := 0, n + for { + if i <= len(s) { + sx = append(sx, s[p:i]) + } else { + sx = append(sx, s[p:]) + break + + } + p, i = p+n, i+n + } + + return sx +} diff --git a/vendor/github.com/miekg/dns/types_generate.go b/vendor/github.com/miekg/dns/types_generate.go index bf80da329..dd1310942 100644 --- a/vendor/github.com/miekg/dns/types_generate.go +++ b/vendor/github.com/miekg/dns/types_generate.go @@ -197,7 +197,7 @@ func main() { case st.Tag(i) == "": switch st.Field(i).Type().(*types.Basic).Kind() { case types.Uint8: - o("l += 1 // %s\n") + o("l++ // %s\n") case types.Uint16: o("l += 2 // %s\n") case types.Uint32: 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 index d40732441..488a282b2 100644 --- a/vendor/github.com/miekg/dns/udp_other.go +++ b/vendor/github.com/miekg/dns/udp_other.go @@ -1,17 +1,15 @@ -// +build !linux,!plan9 +// +build !linux appengine 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 setUDPSocketOptions(conn *net.UDPConn) error { return nil } 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/zcompress.go b/vendor/github.com/miekg/dns/zcompress.go new file mode 100644 index 000000000..86a31a916 --- /dev/null +++ b/vendor/github.com/miekg/dns/zcompress.go @@ -0,0 +1,119 @@ +// *** DO NOT MODIFY *** +// AUTOGENERATED BY go generate from compress_generate.go + +package dns + +func compressionLenHelperType(c map[string]int, r RR) { + switch x := r.(type) { + case *KX: + compressionLenHelper(c, x.Exchanger) + case *MX: + compressionLenHelper(c, x.Mx) + case *NSEC: + compressionLenHelper(c, x.NextDomain) + case *DNAME: + compressionLenHelper(c, x.Target) + case *HIP: + for i := range x.RendezvousServers { + compressionLenHelper(c, x.RendezvousServers[i]) + } + case *CNAME: + compressionLenHelper(c, x.Target) + case *MR: + compressionLenHelper(c, x.Mr) + case *PX: + compressionLenHelper(c, x.Map822) + compressionLenHelper(c, x.Mapx400) + case *SIG: + compressionLenHelper(c, x.SignerName) + case *SRV: + compressionLenHelper(c, x.Target) + case *TALINK: + compressionLenHelper(c, x.PreviousName) + compressionLenHelper(c, x.NextName) + case *LP: + compressionLenHelper(c, x.Fqdn) + case *NAPTR: + compressionLenHelper(c, x.Replacement) + case *NS: + compressionLenHelper(c, x.Ns) + case *RP: + compressionLenHelper(c, x.Mbox) + compressionLenHelper(c, x.Txt) + case *RRSIG: + compressionLenHelper(c, x.SignerName) + case *TKEY: + compressionLenHelper(c, x.Algorithm) + case *TSIG: + compressionLenHelper(c, x.Algorithm) + case *AFSDB: + compressionLenHelper(c, x.Hostname) + case *MF: + compressionLenHelper(c, x.Mf) + case *RT: + compressionLenHelper(c, x.Host) + case *MINFO: + compressionLenHelper(c, x.Rmail) + compressionLenHelper(c, x.Email) + case *PTR: + compressionLenHelper(c, x.Ptr) + case *SOA: + compressionLenHelper(c, x.Ns) + compressionLenHelper(c, x.Mbox) + case *MD: + compressionLenHelper(c, x.Md) + case *NSAPPTR: + compressionLenHelper(c, x.Ptr) + case *MG: + compressionLenHelper(c, x.Mg) + case *MB: + compressionLenHelper(c, x.Mb) + } +} + +func compressionLenSearchType(c map[string]int, r RR) (int, bool) { + switch x := r.(type) { + case *MF: + k1, ok1 := compressionLenSearch(c, x.Mf) + return k1, ok1 + case *MG: + k1, ok1 := compressionLenSearch(c, x.Mg) + return k1, ok1 + case *MINFO: + k1, ok1 := compressionLenSearch(c, x.Rmail) + k2, ok2 := compressionLenSearch(c, x.Email) + return k1 + k2, ok1 && ok2 + case *MR: + k1, ok1 := compressionLenSearch(c, x.Mr) + return k1, ok1 + case *PTR: + k1, ok1 := compressionLenSearch(c, x.Ptr) + return k1, ok1 + case *AFSDB: + k1, ok1 := compressionLenSearch(c, x.Hostname) + return k1, ok1 + case *CNAME: + k1, ok1 := compressionLenSearch(c, x.Target) + return k1, ok1 + case *MD: + k1, ok1 := compressionLenSearch(c, x.Md) + return k1, ok1 + case *RT: + k1, ok1 := compressionLenSearch(c, x.Host) + return k1, ok1 + case *SOA: + k1, ok1 := compressionLenSearch(c, x.Ns) + k2, ok2 := compressionLenSearch(c, x.Mbox) + return k1 + k2, ok1 && ok2 + case *MB: + k1, ok1 := compressionLenSearch(c, x.Mb) + return k1, ok1 + case *MX: + k1, ok1 := compressionLenSearch(c, x.Mx) + return k1, ok1 + case *NS: + k1, ok1 := compressionLenSearch(c, x.Ns) + return k1, ok1 + } + return 0, false +} diff --git a/vendor/github.com/miekg/dns/zmsg.go b/vendor/github.com/miekg/dns/zmsg.go index 346d3102d..9b98e1bb2 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 } @@ -801,10 +801,12 @@ func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress if err != nil { return off, err } - if rr.Salt == "-" { /* do nothing, empty salt */ - } - if err != nil { - return off, err + // Only pack salt if value is not "-", i.e. empty + if rr.Salt != "-" { + off, err = packStringHex(rr.Salt, msg, off) + if err != nil { + return off, err + } } off, err = packUint8(rr.HashLength, msg, off) if err != nil { @@ -844,10 +846,12 @@ func (rr *NSEC3PARAM) pack(msg []byte, off int, compression map[string]int, comp if err != nil { return off, err } - if rr.Salt == "-" { /* do nothing, empty salt */ - } - if err != nil { - return off, err + // Only pack salt if value is not "-", i.e. empty + if rr.Salt != "-" { + off, err = packStringHex(rr.Salt, msg, off) + if err != nil { + return off, err + } } rr.Header().Rdlength = uint16(off - headerEnd) return off, nil @@ -905,11 +909,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 +967,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 +1013,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 +1077,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 } @@ -1085,6 +1089,32 @@ func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bo return off, nil } +func (rr *SMIMEA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { + off, err := rr.Hdr.pack(msg, off, compression, compress) + if err != nil { + return off, err + } + headerEnd := off + off, err = packUint8(rr.Usage, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.Selector, msg, off) + if err != nil { + return off, err + } + off, err = packUint8(rr.MatchingType, msg, off) + if err != nil { + return off, err + } + off, err = packStringHex(rr.Certificate, msg, off) + if err != nil { + return off, err + } + rr.Header().Rdlength = uint16(off - headerEnd) + return off, nil +} + func (rr *SOA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { off, err := rr.Hdr.pack(msg, off, compression, compress) if err != nil { @@ -1155,7 +1185,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 } @@ -1217,11 +1247,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 } @@ -1235,7 +1265,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 } @@ -1307,7 +1337,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 } @@ -2907,6 +2937,44 @@ func unpackSIG(h RR_Header, msg []byte, off int) (RR, int, error) { return rr, off, err } +func unpackSMIMEA(h RR_Header, msg []byte, off int) (RR, int, error) { + rr := new(SMIMEA) + rr.Hdr = h + if noRdata(h) { + return rr, off, nil + } + var err error + rdStart := off + _ = rdStart + + rr.Usage, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Selector, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.MatchingType, off, err = unpackUint8(msg, off) + if err != nil { + return rr, off, err + } + if off == len(msg) { + return rr, off, nil + } + rr.Certificate, off, err = unpackStringHex(msg, off, rdStart+int(rr.Hdr.Rdlength)) + if err != nil { + return rr, off, err + } + return rr, off, err +} + func unpackSOA(h RR_Header, msg []byte, off int) (RR, int, error) { rr := new(SOA) rr.Hdr = h @@ -3447,6 +3515,7 @@ var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){ TypeRRSIG: unpackRRSIG, TypeRT: unpackRT, TypeSIG: unpackSIG, + TypeSMIMEA: unpackSMIMEA, TypeSOA: unpackSOA, TypeSPF: unpackSPF, TypeSRV: unpackSRV, diff --git a/vendor/github.com/miekg/dns/ztypes.go b/vendor/github.com/miekg/dns/ztypes.go index a4ecbb0cc..311b8243b 100644 --- a/vendor/github.com/miekg/dns/ztypes.go +++ b/vendor/github.com/miekg/dns/ztypes.go @@ -62,6 +62,7 @@ var TypeToRR = map[uint16]func() RR{ TypeRRSIG: func() RR { return new(RRSIG) }, TypeRT: func() RR { return new(RT) }, TypeSIG: func() RR { return new(SIG) }, + TypeSMIMEA: func() RR { return new(SMIMEA) }, TypeSOA: func() RR { return new(SOA) }, TypeSPF: func() RR { return new(SPF) }, TypeSRV: func() RR { return new(SRV) }, @@ -141,6 +142,7 @@ var TypeToString = map[uint16]string{ TypeRT: "RT", TypeReserved: "Reserved", TypeSIG: "SIG", + TypeSMIMEA: "SMIMEA", TypeSOA: "SOA", TypeSPF: "SPF", TypeSRV: "SRV", @@ -213,6 +215,7 @@ func (rr *RP) Header() *RR_Header { return &rr.Hdr } func (rr *RRSIG) Header() *RR_Header { return &rr.Hdr } func (rr *RT) Header() *RR_Header { return &rr.Hdr } func (rr *SIG) Header() *RR_Header { return &rr.Hdr } +func (rr *SMIMEA) Header() *RR_Header { return &rr.Hdr } func (rr *SOA) Header() *RR_Header { return &rr.Hdr } func (rr *SPF) Header() *RR_Header { return &rr.Hdr } func (rr *SRV) Header() *RR_Header { return &rr.Hdr } @@ -251,7 +254,7 @@ func (rr *ANY) len() int { } func (rr *CAA) len() int { l := rr.Hdr.len() - l += 1 // Flag + l++ // Flag l += len(rr.Tag) + 1 l += len(rr.Value) return l @@ -260,7 +263,7 @@ func (rr *CERT) len() int { l := rr.Hdr.len() l += 2 // Type l += 2 // KeyTag - l += 1 // Algorithm + l++ // Algorithm l += base64.StdEncoding.DecodedLen(len(rr.Certificate)) return l } @@ -282,16 +285,16 @@ func (rr *DNAME) len() int { func (rr *DNSKEY) len() int { l := rr.Hdr.len() l += 2 // Flags - l += 1 // Protocol - l += 1 // Algorithm + l++ // Protocol + l++ // Algorithm l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) return l } func (rr *DS) len() int { l := rr.Hdr.len() l += 2 // KeyTag - l += 1 // Algorithm - l += 1 // DigestType + l++ // Algorithm + l++ // DigestType l += len(rr.Digest)/2 + 1 return l } @@ -330,8 +333,8 @@ func (rr *HINFO) len() int { } func (rr *HIP) len() int { l := rr.Hdr.len() - l += 1 // HitLength - l += 1 // PublicKeyAlgorithm + l++ // HitLength + l++ // PublicKeyAlgorithm l += 2 // PublicKeyLength l += len(rr.Hit)/2 + 1 l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) @@ -360,10 +363,10 @@ func (rr *L64) len() int { } func (rr *LOC) len() int { l := rr.Hdr.len() - l += 1 // Version - l += 1 // Size - l += 1 // HorizPre - l += 1 // VertPre + l++ // Version + l++ // Size + l++ // HorizPre + l++ // VertPre l += 4 // Latitude l += 4 // Longitude l += 4 // Altitude @@ -452,10 +455,10 @@ func (rr *NSAPPTR) len() int { } func (rr *NSEC3PARAM) len() int { l := rr.Hdr.len() - l += 1 // Hash - l += 1 // Flags + l++ // Hash + l++ // Flags l += 2 // Iterations - l += 1 // SaltLength + l++ // SaltLength l += len(rr.Salt)/2 + 1 return l } @@ -484,8 +487,8 @@ func (rr *RFC3597) len() int { func (rr *RKEY) len() int { l := rr.Hdr.len() l += 2 // Flags - l += 1 // Protocol - l += 1 // Algorithm + l++ // Protocol + l++ // Algorithm l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) return l } @@ -498,8 +501,8 @@ func (rr *RP) len() int { func (rr *RRSIG) len() int { l := rr.Hdr.len() l += 2 // TypeCovered - l += 1 // Algorithm - l += 1 // Labels + l++ // Algorithm + l++ // Labels l += 4 // OrigTtl l += 4 // Expiration l += 4 // Inception @@ -514,6 +517,14 @@ func (rr *RT) len() int { l += len(rr.Host) + 1 return l } +func (rr *SMIMEA) len() int { + l := rr.Hdr.len() + l++ // Usage + l++ // Selector + l++ // MatchingType + l += len(rr.Certificate)/2 + 1 + return l +} func (rr *SOA) len() int { l := rr.Hdr.len() l += len(rr.Ns) + 1 @@ -542,16 +553,16 @@ func (rr *SRV) len() int { } func (rr *SSHFP) len() int { l := rr.Hdr.len() - l += 1 // Algorithm - l += 1 // Type + l++ // Algorithm + l++ // Type l += len(rr.FingerPrint)/2 + 1 return l } func (rr *TA) len() int { l := rr.Hdr.len() l += 2 // KeyTag - l += 1 // Algorithm - l += 1 // DigestType + l++ // Algorithm + l++ // DigestType l += len(rr.Digest)/2 + 1 return l } @@ -576,9 +587,9 @@ func (rr *TKEY) len() int { } func (rr *TLSA) len() int { l := rr.Hdr.len() - l += 1 // Usage - l += 1 // Selector - l += 1 // MatchingType + l++ // Usage + l++ // Selector + l++ // MatchingType l += len(rr.Certificate)/2 + 1 return l } @@ -780,6 +791,9 @@ func (rr *RRSIG) copy() RR { func (rr *RT) copy() RR { return &RT{*rr.Hdr.copyHeader(), rr.Preference, rr.Host} } +func (rr *SMIMEA) copy() RR { + return &SMIMEA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate} +} func (rr *SOA) copy() RR { return &SOA{*rr.Hdr.copyHeader(), rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl} } diff --git a/vendor/vendor.json b/vendor/vendor.json index 599669bfb..3776cfc4d 100644 --- a/vendor/vendor.json +++ b/vendor/vendor.json @@ -237,10 +237,10 @@ "revisionTime": "2015-04-13T22:18:30+03:00" }, { - "checksumSHA1": "OUZ1FFXyKs+Cfg9M9rmXqqweQck=", + "checksumSHA1": "lxO8OJ+oWgBLoHNELCXxxTVc84w=", "path": "github.com/miekg/dns", - "revision": "db96a2b759cdef4f11a34506a42eb8d1290c598e", - "revisionTime": "2016-07-26T03:20:27Z" + "revision": "765aea0018871a5acd99796645585323343ba39c", + "revisionTime": "2017-03-22T06:49:16Z" }, { "checksumSHA1": "9SrLPArdQmp45MGosz7IEGX46Ng=",