Vendor update miekg/dns to pick up bugfixes and features (#3547)

This commit is contained in:
preetapan 2017-10-06 13:34:41 -05:00 committed by James Phillips
parent 467f74586f
commit 285dbe2d76
36 changed files with 1272 additions and 603 deletions

View File

@ -1,4 +1,5 @@
[![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns) [![Build Status](https://travis-ci.org/miekg/dns.svg?branch=master)](https://travis-ci.org/miekg/dns)
[![](https://godoc.org/github.com/miekg/dns?status.svg)](https://godoc.org/github.com/miekg/dns)
# Alternative (more granular) approach to a DNS library # Alternative (more granular) approach to a DNS library
@ -12,18 +13,19 @@ can build servers and resolvers with it.
We try to keep the "master" branch as sane as possible and at the bleeding edge 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 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.7 and 1.8.
# Goals # Goals
* KISS; * KISS;
* Fast; * Fast;
* Small API, if its easy to code in Go, don't make a function for it. * Small API. If it's easy to code in Go, don't make a function for it.
# Users # Users
A not-so-up-to-date-list-that-may-be-actually-current: A not-so-up-to-date-list-that-may-be-actually-current:
* https://github.com/coredns/coredns
* https://cloudflare.com * https://cloudflare.com
* https://github.com/abh/geodns * https://github.com/abh/geodns
* http://www.statdns.com/ * http://www.statdns.com/
@ -50,6 +52,14 @@ A not-so-up-to-date-list-that-may-be-actually-current:
* https://dnslookup.org * https://dnslookup.org
* https://github.com/looterz/grimd * https://github.com/looterz/grimd
* https://github.com/phamhongviet/serf-dns * 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)
* https://github.com/StackExchange/dnscontrol/
* https://www.dnsperf.com/
* https://dnssectest.net/
Send pull request if you want to be listed here. Send pull request if you want to be listed here.
@ -138,6 +148,7 @@ Example programs can be found in the `github.com/miekg/exdns` repository.
* 6975 - Algorithm Understanding in DNSSEC * 6975 - Algorithm Understanding in DNSSEC
* 7043 - EUI48/EUI64 records * 7043 - EUI48/EUI64 records
* 7314 - DNS (EDNS) EXPIRE Option * 7314 - DNS (EDNS) EXPIRE Option
* 7828 - edns-tcp-keepalive EDNS0 Option
* 7553 - URI record * 7553 - URI record
* 7858 - DNS over TLS: Initiation and Performance Considerations (draft) * 7858 - DNS over TLS: Initiation and Performance Considerations (draft)
* 7873 - Domain Name System (DNS) Cookies (draft-ietf-dnsop-cookies) * 7873 - Domain Name System (DNS) Cookies (draft-ietf-dnsop-cookies)

106
vendor/github.com/miekg/dns/client.go generated vendored
View File

@ -4,6 +4,7 @@ package dns
import ( import (
"bytes" "bytes"
"context"
"crypto/tls" "crypto/tls"
"encoding/binary" "encoding/binary"
"io" "io"
@ -39,7 +40,7 @@ type Client struct {
} }
// Exchange performs a synchronous UDP query. It sends the message m to the address // 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. // will it fall back to TCP in case of truncation.
// See client.Exchange for more information on setting larger buffer sizes. // See client.Exchange for more information on setting larger buffer sizes.
func Exchange(m *Msg, a string) (r *Msg, err error) { func Exchange(m *Msg, a string) (r *Msg, err error) {
@ -70,6 +71,43 @@ func Exchange(m *Msg, a string) (r *Msg, err error) {
return r, err return r, err
} }
// ExchangeContext performs a synchronous UDP query, like Exchange. It
// additionally obeys deadlines from the passed Context.
func ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg, err error) {
// Combine context deadline with built-in timeout. Context chooses whichever
// is sooner.
timeoutCtx, cancel := context.WithTimeout(ctx, dnsTimeout)
defer cancel()
deadline, _ := timeoutCtx.Deadline()
co := new(Conn)
dialer := net.Dialer{}
co.Conn, err = dialer.DialContext(timeoutCtx, "udp", a)
if err != nil {
return nil, err
}
defer co.Conn.Close()
opt := m.IsEdns0()
// If EDNS0 is used use that for size.
if opt != nil && opt.UDPSize() >= MinMsgSize {
co.UDPSize = opt.UDPSize()
}
co.SetWriteDeadline(deadline)
if err = co.WriteMsg(m); err != nil {
return nil, err
}
co.SetReadDeadline(deadline)
r, err = co.ReadMsg()
if err == nil && r.Id != m.Id {
err = ErrId
}
return r, err
}
// ExchangeConn performs a synchronous query. It sends the message m via the connection // ExchangeConn performs a synchronous query. It sends the message m via the connection
// c and waits for a reply. The connection c is not closed by ExchangeConn. // c and waits for a reply. The connection c is not closed by ExchangeConn.
// This function is going away, but can easily be mimicked: // This function is going away, but can easily be mimicked:
@ -93,8 +131,8 @@ func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
return r, err return r, err
} }
// Exchange performs an synchronous query. It sends the message m to the address // Exchange performs a 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: // contained in a and waits for a reply. Basic use pattern with a *dns.Client:
// //
// c := new(dns.Client) // c := new(dns.Client)
// in, rtt, err := c.Exchange(message, "127.0.0.1:53") // in, rtt, err := c.Exchange(message, "127.0.0.1:53")
@ -103,11 +141,21 @@ func ExchangeConn(c net.Conn, m *Msg) (r *Msg, err error) {
// case of truncation. // case of truncation.
// It is up to the caller to create a message that allows for larger responses to be // 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 // 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. // of 512 bytes.
func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) { func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
return c.ExchangeContext(context.Background(), m, a)
}
// ExchangeContext acts like Exchange, but honors the deadline on the provided
// context, if present. If there is both a context deadline and a configured
// timeout on the client, the earliest of the two takes effect.
func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (
r *Msg,
rtt time.Duration,
err error) {
if !c.SingleInflight { if !c.SingleInflight {
return c.exchange(m, a) return c.exchange(ctx, m, a)
} }
// This adds a bunch of garbage, TODO(miek). // This adds a bunch of garbage, TODO(miek).
t := "nop" t := "nop"
@ -119,14 +167,14 @@ func (c *Client) Exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
cl = cl1 cl = cl1
} }
r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) { r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
return c.exchange(m, a) return c.exchange(ctx, m, a)
}) })
if r != nil && shared {
r = r.Copy()
}
if err != nil { if err != nil {
return r, rtt, err return r, rtt, err
} }
if shared {
return r.Copy(), rtt, nil
}
return r, rtt, nil return r, rtt, nil
} }
@ -154,7 +202,7 @@ func (c *Client) writeTimeout() time.Duration {
return dnsTimeout return dnsTimeout
} }
func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err error) { func (c *Client) exchange(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
var co *Conn var co *Conn
network := "udp" network := "udp"
tls := false tls := false
@ -180,10 +228,13 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
deadline = time.Now().Add(c.Timeout) deadline = time.Now().Add(c.Timeout)
} }
dialDeadline := deadlineOrTimeoutOrCtx(ctx, deadline, c.dialTimeout())
dialTimeout := dialDeadline.Sub(time.Now())
if tls { if tls {
co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, c.dialTimeout()) co, err = DialTimeoutWithTLS(network, a, c.TLSConfig, dialTimeout)
} else { } else {
co, err = DialTimeout(network, a, c.dialTimeout()) co, err = DialTimeout(network, a, dialTimeout)
} }
if err != nil { if err != nil {
@ -202,12 +253,12 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
} }
co.TsigSecret = c.TsigSecret co.TsigSecret = c.TsigSecret
co.SetWriteDeadline(deadlineOrTimeout(deadline, c.writeTimeout())) co.SetWriteDeadline(deadlineOrTimeoutOrCtx(ctx, deadline, c.writeTimeout()))
if err = co.WriteMsg(m); err != nil { if err = co.WriteMsg(m); err != nil {
return nil, 0, err return nil, 0, err
} }
co.SetReadDeadline(deadlineOrTimeout(deadline, c.readTimeout())) co.SetReadDeadline(deadlineOrTimeoutOrCtx(ctx, deadline, c.readTimeout()))
r, err = co.ReadMsg() r, err = co.ReadMsg()
if err == nil && r.Id != m.Id { if err == nil && r.Id != m.Id {
err = ErrId err = ErrId
@ -300,6 +351,18 @@ func tcpMsgLen(t io.Reader) (int, error) {
if err != nil { if err != nil {
return 0, err 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 { if n != 2 {
return 0, ErrShortRead return 0, ErrShortRead
} }
@ -400,7 +463,7 @@ func (co *Conn) Write(p []byte) (n int, err error) {
n, err := io.Copy(w, bytes.NewReader(p)) n, err := io.Copy(w, bytes.NewReader(p))
return int(n), err return int(n), err
} }
n, err = co.Conn.(*net.UDPConn).Write(p) n, err = co.Conn.Write(p)
return n, err return n, err
} }
@ -447,9 +510,22 @@ func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout
return conn, nil return conn, nil
} }
// deadlineOrTimeout chooses between the provided deadline and timeout
// by always preferring the deadline so long as it's non-zero (regardless
// of which is bigger), and returns the equivalent deadline value.
func deadlineOrTimeout(deadline time.Time, timeout time.Duration) time.Time { func deadlineOrTimeout(deadline time.Time, timeout time.Duration) time.Time {
if deadline.IsZero() { if deadline.IsZero() {
return time.Now().Add(timeout) return time.Now().Add(timeout)
} }
return deadline return deadline
} }
// deadlineOrTimeoutOrCtx returns the earliest of: a context deadline, or the
// output of deadlineOrtimeout.
func deadlineOrTimeoutOrCtx(ctx context.Context, deadline time.Time, timeout time.Duration) time.Time {
result := deadlineOrTimeout(deadline, timeout)
if ctxDeadline, ok := ctx.Deadline(); ok && ctxDeadline.Before(result) {
result = ctxDeadline
}
return result
}

View File

@ -97,3 +97,35 @@ func ClientConfigFromFile(resolvconf string) (*ClientConfig, error) {
} }
return c, nil 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
}

184
vendor/github.com/miekg/dns/compress_generate.go generated vendored Normal file
View File

@ -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)
}
}

43
vendor/github.com/miekg/dns/dane.go generated vendored Normal file
View File

@ -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")
}

View File

@ -13,9 +13,12 @@ const hexDigit = "0123456789abcdef"
// SetReply creates a reply message from a request message. // SetReply creates a reply message from a request message.
func (dns *Msg) SetReply(request *Msg) *Msg { func (dns *Msg) SetReply(request *Msg) *Msg {
dns.Id = request.Id dns.Id = request.Id
dns.RecursionDesired = request.RecursionDesired // Copy rd bit
dns.Response = true dns.Response = true
dns.Opcode = OpcodeQuery dns.Opcode = request.Opcode
if dns.Opcode == OpcodeQuery {
dns.RecursionDesired = request.RecursionDesired // Copy rd bit
dns.CheckingDisabled = request.CheckingDisabled // Copy cd bit
}
dns.Rcode = RcodeSuccess dns.Rcode = RcodeSuccess
if len(request.Question) > 0 { if len(request.Question) > 0 {
dns.Question = make([]Question, 1) dns.Question = make([]Question, 1)
@ -102,11 +105,11 @@ func (dns *Msg) SetAxfr(z string) *Msg {
// SetTsig appends a TSIG RR to the message. // SetTsig appends a TSIG RR to the message.
// This is only a skeleton TSIG RR that is added as the last RR in the // 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. // 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 := new(TSIG)
t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0} t.Hdr = RR_Header{z, TypeTSIG, ClassANY, 0, 0}
t.Algorithm = algo t.Algorithm = algo
t.Fudge = 300 t.Fudge = fudge
t.TimeSigned = uint64(timesigned) t.TimeSigned = uint64(timesigned)
t.OrigId = dns.Id t.OrigId = dns.Id
dns.Extra = append(dns.Extra, t) dns.Extra = append(dns.Extra, t)

View File

@ -43,7 +43,7 @@ const (
PRIVATEOID uint8 = 254 PRIVATEOID uint8 = 254
) )
// Map for algorithm names. // AlgorithmToString is a map of algorithm IDs to algorithm names.
var AlgorithmToString = map[uint8]string{ var AlgorithmToString = map[uint8]string{
RSAMD5: "RSAMD5", RSAMD5: "RSAMD5",
DH: "DH", DH: "DH",
@ -61,10 +61,10 @@ var AlgorithmToString = map[uint8]string{
PRIVATEOID: "PRIVATEOID", PRIVATEOID: "PRIVATEOID",
} }
// Map of algorithm strings. // StringToAlgorithm is the reverse of AlgorithmToString.
var StringToAlgorithm = reverseInt8(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{ var AlgorithmToHash = map[uint8]crypto.Hash{
RSAMD5: crypto.MD5, // Deprecated in RFC 6725 RSAMD5: crypto.MD5, // Deprecated in RFC 6725
RSASHA1: crypto.SHA1, RSASHA1: crypto.SHA1,
@ -85,7 +85,7 @@ const (
SHA512 // Experimental SHA512 // Experimental
) )
// Map for hash names. // HashToString is a map of hash IDs to names.
var HashToString = map[uint8]string{ var HashToString = map[uint8]string{
SHA1: "SHA1", SHA1: "SHA1",
SHA256: "SHA256", SHA256: "SHA256",
@ -94,7 +94,7 @@ var HashToString = map[uint8]string{
SHA512: "SHA512", SHA512: "SHA512",
} }
// Map of hash strings. // StringToHash is a map of names to hash IDs.
var StringToHash = reverseInt8(HashToString) var StringToHash = reverseInt8(HashToString)
// DNSKEY flag values. // DNSKEY flag values.
@ -208,9 +208,6 @@ func (k *DNSKEY) ToDS(h uint8) *DS {
// "|" denotes concatenation // "|" denotes concatenation
// DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. // DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key.
// digest buffer
digest := append(owner, wire...) // another copy
var hash crypto.Hash var hash crypto.Hash
switch h { switch h {
case SHA1: case SHA1:
@ -226,7 +223,8 @@ func (k *DNSKEY) ToDS(h uint8) *DS {
} }
s := hash.New() s := hash.New()
s.Write(digest) s.Write(owner)
s.Write(wire)
ds.Digest = hex.EncodeToString(s.Sum(nil)) ds.Digest = hex.EncodeToString(s.Sum(nil))
return ds return ds
} }
@ -297,7 +295,6 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
if err != nil { if err != nil {
return err return err
} }
signdata = append(signdata, wire...)
hash, ok := AlgorithmToHash[rr.Algorithm] hash, ok := AlgorithmToHash[rr.Algorithm]
if !ok { if !ok {
@ -306,6 +303,7 @@ func (rr *RRSIG) Sign(k crypto.Signer, rrset []RR) error {
h := hash.New() h := hash.New()
h.Write(signdata) h.Write(signdata)
h.Write(wire)
signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm) signature, err := sign(k, h.Sum(nil), hash, rr.Algorithm)
if err != nil { if err != nil {
@ -415,7 +413,6 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
if err != nil { if err != nil {
return err return err
} }
signeddata = append(signeddata, wire...)
sigbuf := rr.sigBuf() // Get the binary signature data sigbuf := rr.sigBuf() // Get the binary signature data
if rr.Algorithm == PRIVATEDNS { // PRIVATEOID if rr.Algorithm == PRIVATEDNS { // PRIVATEOID
@ -438,6 +435,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
h := hash.New() h := hash.New()
h.Write(signeddata) h.Write(signeddata)
h.Write(wire)
return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf) return rsa.VerifyPKCS1v15(pubkey, hash, h.Sum(nil), sigbuf)
case ECDSAP256SHA256, ECDSAP384SHA384: case ECDSAP256SHA256, ECDSAP384SHA384:
@ -452,6 +450,7 @@ func (rr *RRSIG) Verify(k *DNSKEY, rrset []RR) error {
h := hash.New() h := hash.New()
h.Write(signeddata) h.Write(signeddata)
h.Write(wire)
if ecdsa.Verify(pubkey, h.Sum(nil), r, s) { if ecdsa.Verify(pubkey, h.Sum(nil), r, s) {
return nil return nil
} }
@ -516,7 +515,7 @@ func (k *DNSKEY) publicKeyRSA() *rsa.PublicKey {
} }
// Remainder // Remainder
expo += uint64(keybuf[keyoff]) expo += uint64(keybuf[keyoff])
if expo > 2<<31 { if expo > (2<<31)+1 {
// Larger expo than supported. // Larger expo than supported.
// println("dns: F5 primes (or larger) are not supported") // println("dns: F5 primes (or larger) are not supported")
return nil return nil

View File

@ -121,17 +121,17 @@ func (k *DNSKEY) setPublicKeyDSA(_Q, _P, _G, _Y *big.Int) bool {
// RFC 3110: Section 2. RSA Public KEY Resource Records // RFC 3110: Section 2. RSA Public KEY Resource Records
func exponentToBuf(_E int) []byte { func exponentToBuf(_E int) []byte {
var buf []byte var buf []byte
i := big.NewInt(int64(_E)) i := big.NewInt(int64(_E)).Bytes()
if len(i.Bytes()) < 256 { if len(i) < 256 {
buf = make([]byte, 1) buf = make([]byte, 1, 1+len(i))
buf[0] = uint8(len(i.Bytes())) buf[0] = uint8(len(i))
} else { } else {
buf = make([]byte, 3) buf = make([]byte, 3, 3+len(i))
buf[0] = 0 buf[0] = 0
buf[1] = uint8(len(i.Bytes()) >> 8) buf[1] = uint8(len(i) >> 8)
buf[2] = uint8(len(i.Bytes())) buf[2] = uint8(len(i))
} }
buf = append(buf, i.Bytes()...) buf = append(buf, i...)
return buf return buf
} }

View File

@ -14,7 +14,7 @@ import (
// NewPrivateKey returns a PrivateKey by parsing the string s. // NewPrivateKey returns a PrivateKey by parsing the string s.
// s should be in the same form of the BIND private key files. // s should be in the same form of the BIND private key files.
func (k *DNSKEY) NewPrivateKey(s string) (crypto.PrivateKey, error) { 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+"\n"), "")
} }
return k.ReadPrivateKey(strings.NewReader(s), "") 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 return nil, ErrPrivKey
} }
// TODO(mg): check if the pubkey matches the private key // 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 { if err != nil {
return nil, ErrPrivKey return nil, ErrPrivKey
} }

2
vendor/github.com/miekg/dns/doc.go generated vendored
View File

@ -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 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. 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. information.
EDNS0 EDNS0

101
vendor/github.com/miekg/dns/edns.go generated vendored
View File

@ -4,25 +4,27 @@ import (
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt"
"net" "net"
"strconv" "strconv"
) )
// EDNS0 Option codes. // EDNS0 Option codes.
const ( const (
EDNS0LLQ = 0x1 // long lived queries: http://tools.ietf.org/html/draft-sekar-dns-llq-01 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 EDNS0UL = 0x2 // update lease draft: http://files.dns-sd.org/draft-sekar-dns-ul.txt
EDNS0NSID = 0x3 // nsid (RFC5001) EDNS0NSID = 0x3 // nsid (RFC5001)
EDNS0DAU = 0x5 // DNSSEC Algorithm Understood EDNS0DAU = 0x5 // DNSSEC Algorithm Understood
EDNS0DHU = 0x6 // DS Hash Understood EDNS0DHU = 0x6 // DS Hash Understood
EDNS0N3U = 0x7 // NSEC3 Hash Understood EDNS0N3U = 0x7 // NSEC3 Hash Understood
EDNS0SUBNET = 0x8 // client-subnet (RFC6891) EDNS0SUBNET = 0x8 // client-subnet (RFC6891)
EDNS0EXPIRE = 0x9 // EDNS0 expire EDNS0EXPIRE = 0x9 // EDNS0 expire
EDNS0COOKIE = 0xa // EDNS0 Cookie EDNS0COOKIE = 0xa // EDNS0 Cookie
EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET EDNS0TCPKEEPALIVE = 0xb // EDNS0 tcp keep alive (RFC7828)
EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891) EDNS0SUBNETDRAFT = 0x50fa // Don't use! Use EDNS0SUBNET
EDNS0LOCALEND = 0xFFFE // End of range reserved for local/experimental use (RFC6891) EDNS0LOCALSTART = 0xFDE9 // Beginning of range reserved for local/experimental use (RFC6891)
_DO = 1 << 15 // dnssec ok 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. // 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. // SetDo sets the DO (DNSSEC OK) bit.
func (rr *OPT) SetDo() { // If we pass an argument, set the DO bit to that value.
rr.Hdr.Ttl |= _DO // 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. // EDNS0 defines an EDNS0 Option. An OPT RR can have multiple options appended to it.
@ -145,7 +157,7 @@ type EDNS0 interface {
String() string 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 // identifier. When sending a request Nsid must be set to the empty string
// The identifier is an opaque string encoded as hex. // The identifier is an opaque string encoded as hex.
// Basic use pattern for creating an nsid option: // 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 := new(dns.EDNS0_SUBNET)
// e.Code = dns.EDNS0SUBNET // e.Code = dns.EDNS0SUBNET
// e.Family = 1 // 1 for IPv4 source address, 2 for IPv6 // 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.SourceScope = 0
// e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4 // e.Address = net.ParseIP("127.0.0.1").To4() // for IPv4
// // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6 // // e.Address = net.ParseIP("2001:7b8:32a::2") // for IPV6
@ -289,7 +301,7 @@ func (e *EDNS0_SUBNET) String() (s string) {
return return
} }
// The Cookie EDNS0 option // The EDNS0_COOKIE option is used to add a DNS Cookie to a message.
// //
// o := new(dns.OPT) // o := new(dns.OPT)
// o.Hdr.Name = "." // o.Hdr.Name = "."
@ -530,3 +542,56 @@ func (e *EDNS0_LOCAL) unpack(b []byte) error {
} }
return nil 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
}

View File

@ -1,5 +1,7 @@
package dns package dns
import "strings"
// Holds a bunch of helper functions for dealing with labels. // Holds a bunch of helper functions for dealing with labels.
// SplitDomainName splits a name string into it's labels. // SplitDomainName splits a name string into it's labels.
@ -50,6 +52,7 @@ func SplitDomainName(s string) (labels []string) {
// //
// s1 and s2 must be syntactically valid domain names. // s1 and s2 must be syntactically valid domain names.
func CompareDomainName(s1, s2 string) (n int) { func CompareDomainName(s1, s2 string) (n int) {
s1, s2 = strings.ToLower(s1), strings.ToLower(s2)
s1 = Fqdn(s1) s1 = Fqdn(s1)
s2 = Fqdn(s2) s2 = Fqdn(s2)
l1 := Split(s1) l1 := Split(s1)

230
vendor/github.com/miekg/dns/msg.go generated vendored
View File

@ -9,42 +9,35 @@
package dns package dns
//go:generate go run msg_generate.go //go:generate go run msg_generate.go
//go:generate go run compress_generate.go
import ( import (
crand "crypto/rand" crand "crypto/rand"
"encoding/binary" "encoding/binary"
"fmt"
"math/big" "math/big"
"math/rand" "math/rand"
"strconv" "strconv"
"sync"
) )
func init() { const (
// Initialize default math/rand source using crypto/rand to provide better maxCompressionOffset = 2 << 13 // We have 14 bits for the compression pointer
// security without the performance trade-off. maxDomainNameWireOctets = 255 // See RFC 1035 section 2.3.4
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 ( var (
ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm. ErrAlg error = &Error{err: "bad algorithm"} // ErrAlg indicates an error with the (DNSSEC) algorithm.
ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication. ErrAuth error = &Error{err: "bad authentication"} // ErrAuth indicates an error in the TSIG authentication.
ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used it too small for the message. ErrBuf error = &Error{err: "buffer size too small"} // ErrBuf indicates that the buffer used is too small for the message.
ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being uses before it is initialized. ErrConnEmpty error = &Error{err: "conn has no connection"} // ErrConnEmpty indicates a connection is being used before it is initialized.
ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ... ErrExtendedRcode error = &Error{err: "bad extended rcode"} // ErrExtendedRcode ...
ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot. ErrFqdn error = &Error{err: "domain must be fully qualified"} // ErrFqdn indicates that a domain name does not have a closing dot.
ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID. ErrId error = &Error{err: "id mismatch"} // ErrId indicates there is a mismatch with the message's ID.
ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid. ErrKeyAlg error = &Error{err: "bad key algorithm"} // ErrKeyAlg indicates that the algorithm in the key is not valid.
ErrKey error = &Error{err: "bad key"} ErrKey error = &Error{err: "bad key"}
ErrKeySize error = &Error{err: "bad key size"} ErrKeySize error = &Error{err: "bad key size"}
ErrLongDomain error = &Error{err: fmt.Sprintf("domain name exceeded %d wire-format octets", maxDomainNameWireOctets)}
ErrNoSig error = &Error{err: "no signature found"} ErrNoSig error = &Error{err: "no signature found"}
ErrPrivKey error = &Error{err: "bad private key"} ErrPrivKey error = &Error{err: "bad private key"}
ErrRcode error = &Error{err: "bad rcode"} ErrRcode error = &Error{err: "bad rcode"}
@ -58,7 +51,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. 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 // message id. The random provided should be good enough. This being a
// variable the function can be reassigned to a custom function. // variable the function can be reassigned to a custom function.
// For instance, to make it return a static value: // For instance, to make it return a static value:
@ -66,11 +59,45 @@ var (
// dns.Id = func() uint16 { return 3 } // dns.Id = func() uint16 { return 3 }
var Id func() uint16 = id var Id func() uint16 = id
var (
idLock sync.Mutex
idRand *rand.Rand
)
// id returns a 16 bits random number to be used as a // id returns a 16 bits random number to be used as a
// message id. The random provided should be good enough. // message id. The random provided should be good enough.
func id() uint16 { func id() uint16 {
id32 := rand.Uint32() idLock.Lock()
return uint16(id32)
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). // MsgHdr is a a manually-unpacked version of (id, bits).
@ -203,12 +230,6 @@ func packDomainName(s string, msg []byte, off int, compression map[string]int, c
bs[j] = bs[j+2] bs[j] = bs[j+2]
} }
ls -= 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] == '.' escapedDot = bs[i] == '.'
bsFresh = false bsFresh = false
@ -247,7 +268,9 @@ func packDomainName(s string, msg []byte, off int, compression map[string]int, c
bsFresh = true bsFresh = true
} }
// Don't try to compress '.' // 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 { if p, ok := compression[roBs[begin:]]; !ok {
// Only offsets smaller than this can be used. // Only offsets smaller than this can be used.
if offset < maxCompressionOffset { if offset < maxCompressionOffset {
@ -311,6 +334,7 @@ func UnpackDomainName(msg []byte, off int) (string, int, error) {
s := make([]byte, 0, 64) s := make([]byte, 0, 64)
off1 := 0 off1 := 0
lenmsg := len(msg) lenmsg := len(msg)
maxLen := maxDomainNameWireOctets
ptr := 0 // number of pointers followed ptr := 0 // number of pointers followed
Loop: Loop:
for { for {
@ -335,12 +359,10 @@ Loop:
fallthrough fallthrough
case '"', '\\': case '"', '\\':
s = append(s, '\\', b) s = append(s, '\\', b)
case '\t': // presentation-format \X escapes add an extra byte
s = append(s, '\\', 't') maxLen += 1
case '\r':
s = append(s, '\\', 'r')
default: default:
if b < 32 || b >= 127 { // unprintable use \DDD if b < 32 || b >= 127 { // unprintable, use \DDD
var buf [3]byte var buf [3]byte
bufs := strconv.AppendInt(buf[:0], int64(b), 10) bufs := strconv.AppendInt(buf[:0], int64(b), 10)
s = append(s, '\\') s = append(s, '\\')
@ -350,6 +372,8 @@ Loop:
for _, r := range bufs { for _, r := range bufs {
s = append(s, r) s = append(s, r)
} }
// presentation-format \DDD escapes add 3 extra bytes
maxLen += 3
} else { } else {
s = append(s, b) s = append(s, b)
} }
@ -374,6 +398,9 @@ Loop:
if ptr++; ptr > 10 { if ptr++; ptr > 10 {
return "", lenmsg, &Error{err: "too many compression pointers"} return "", lenmsg, &Error{err: "too many compression pointers"}
} }
// pointer should guarantee that it advances and points forwards at least
// but the condition on previous three lines guarantees that it's
// at least loop-free
off = (c^0xC0)<<8 | int(c1) off = (c^0xC0)<<8 | int(c1)
default: default:
// 0x80 and 0x40 are reserved // 0x80 and 0x40 are reserved
@ -385,6 +412,9 @@ Loop:
} }
if len(s) == 0 { if len(s) == 0 {
s = []byte(".") s = []byte(".")
} else if len(s) >= maxLen {
// error if the name is too long, but don't throw it away
return string(s), lenmsg, ErrLongDomain
} }
return string(s), off1, nil return string(s), off1, nil
} }
@ -431,12 +461,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]) { if i+2 < len(bs) && isDigit(bs[i]) && isDigit(bs[i+1]) && isDigit(bs[i+2]) {
msg[offset] = dddToByte(bs[i:]) msg[offset] = dddToByte(bs[i:])
i += 2 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 { } else {
msg[offset] = bs[i] msg[offset] = bs[i]
} }
@ -508,12 +532,6 @@ func unpackTxtString(msg []byte, offset int) (string, int, error) {
switch b { switch b {
case '"', '\\': case '"', '\\':
s = append(s, '\\', b) s = append(s, '\\', b)
case '\t':
s = append(s, `\t`...)
case '\r':
s = append(s, `\r`...)
case '\n':
s = append(s, `\n`...)
default: default:
if b < 32 || b > 127 { // unprintable if b < 32 || b > 127 { // unprintable
var buf [3]byte var buf [3]byte
@ -732,12 +750,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. // We need the uncompressed length here, because we first pack it and then compress it.
msg = buf msg = buf
compress := dns.Compress uncompressedLen := compressedLen(dns, false)
dns.Compress = false if packLen := uncompressedLen + 1; len(msg) < packLen {
if packLen := dns.Len() + 1; len(msg) < packLen {
msg = make([]byte, packLen) msg = make([]byte, packLen)
} }
dns.Compress = compress
// Pack it in: header and then the pieces. // Pack it in: header and then the pieces.
off := 0 off := 0
@ -781,9 +797,6 @@ func (dns *Msg) Unpack(msg []byte) (err error) {
if dh, off, err = unpackMsgHdr(msg, off); err != nil { if dh, off, err = unpackMsgHdr(msg, off); err != nil {
return err return err
} }
if off == len(msg) {
return ErrTruncated
}
dns.Id = dh.Id dns.Id = dh.Id
dns.Response = (dh.Bits & _QR) != 0 dns.Response = (dh.Bits & _QR) != 0
@ -797,6 +810,10 @@ func (dns *Msg) Unpack(msg []byte) (err error) {
dns.CheckingDisabled = (dh.Bits & _CD) != 0 dns.CheckingDisabled = (dh.Bits & _CD) != 0
dns.Rcode = int(dh.Bits & 0xF) dns.Rcode = int(dh.Bits & 0xF)
if off == len(msg) {
return ErrTruncated
}
// Optimistically use the count given to us in the header // Optimistically use the count given to us in the header
dns.Question = make([]Question, 0, int(dh.Qdcount)) dns.Question = make([]Question, 0, int(dh.Qdcount))
@ -889,16 +906,18 @@ func (dns *Msg) String() string {
// If dns.Compress is true compression it is taken into account. Len() // 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, // 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. // 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. // We always return one more than needed.
l := 12 // Message header is always 12 bytes l := 12 // Message header is always 12 bytes
var compression map[string]int compression := map[string]int{}
if dns.Compress {
compression = make(map[string]int)
}
for i := 0; i < len(dns.Question); i++ { for i := 0; i < len(dns.Question); i++ {
l += dns.Question[i].len() l += dns.Question[i].len()
if dns.Compress { if compress {
compressionLenHelper(compression, dns.Question[i].Name) compressionLenHelper(compression, dns.Question[i].Name)
} }
} }
@ -907,7 +926,7 @@ func (dns *Msg) Len() int {
continue continue
} }
l += dns.Answer[i].len() l += dns.Answer[i].len()
if dns.Compress { if compress {
k, ok := compressionLenSearch(compression, dns.Answer[i].Header().Name) k, ok := compressionLenSearch(compression, dns.Answer[i].Header().Name)
if ok { if ok {
l += 1 - k l += 1 - k
@ -925,7 +944,7 @@ func (dns *Msg) Len() int {
continue continue
} }
l += dns.Ns[i].len() l += dns.Ns[i].len()
if dns.Compress { if compress {
k, ok := compressionLenSearch(compression, dns.Ns[i].Header().Name) k, ok := compressionLenSearch(compression, dns.Ns[i].Header().Name)
if ok { if ok {
l += 1 - k l += 1 - k
@ -943,7 +962,7 @@ func (dns *Msg) Len() int {
continue continue
} }
l += dns.Extra[i].len() l += dns.Extra[i].len()
if dns.Compress { if compress {
k, ok := compressionLenSearch(compression, dns.Extra[i].Header().Name) k, ok := compressionLenSearch(compression, dns.Extra[i].Header().Name)
if ok { if ok {
l += 1 - k l += 1 - k
@ -991,97 +1010,6 @@ func compressionLenSearch(c map[string]int, s string) (int, bool) {
return 0, false 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. // Copy returns a new RR which is a deep-copy of r.
func Copy(r RR) RR { r1 := r.copy(); return r1 } func Copy(r RR) RR { r1 := r.copy(); return r1 }

View File

@ -117,9 +117,9 @@ return off, err
switch { switch {
case st.Tag(i) == `dns:"-"`: // ignored case st.Tag(i) == `dns:"-"`: // ignored
case st.Tag(i) == `dns:"cdomain-name"`: 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") 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"`: case st.Tag(i) == `dns:"a"`:
o("off, err = packDataA(rr.%s, msg, off)\n") o("off, err = packDataA(rr.%s, msg, off)\n")
case st.Tag(i) == `dns:"aaaa"`: case st.Tag(i) == `dns:"aaaa"`:
@ -139,8 +139,17 @@ return off, err
case st.Tag(i) == `dns:"base64"`: case st.Tag(i) == `dns:"base64"`:
o("off, err = packStringBase64(rr.%s, msg, off)\n") 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 case strings.HasPrefix(st.Tag(i), `dns:"size-hex:SaltLength`):
o("if rr.%s == \"-\" { /* do nothing, empty salt */ }\n") // 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 continue
case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex case strings.HasPrefix(st.Tag(i), `dns:"size-hex`): // size-hex can be packed just like hex
fallthrough fallthrough

View File

@ -96,7 +96,7 @@ func unpackHeader(msg []byte, off int) (rr RR_Header, off1 int, truncmsg []byte,
return hdr, len(msg), msg, err return hdr, len(msg), msg, err
} }
msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength) msg, err = truncateMsgFromRdlength(msg, off, hdr.Rdlength)
return hdr, off, msg, nil return hdr, off, msg, err
} }
// pack packs an RR header, returning the offset to the end of the header. // pack packs an RR header, returning the offset to the end of the header.
@ -142,6 +142,11 @@ func truncateMsgFromRdlength(msg []byte, off int, rdlength uint16) (truncmsg []b
} }
func fromBase32(s []byte) (buf []byte, err error) { 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)) buflen := base32.HexEncoding.DecodedLen(len(s))
buf = make([]byte, buflen) buf = make([]byte, buflen)
n, err := base32.HexEncoding.Decode(buf, s) n, err := base32.HexEncoding.Decode(buf, s)
@ -263,8 +268,6 @@ func unpackString(msg []byte, off int) (string, int, error) {
switch b { switch b {
case '"', '\\': case '"', '\\':
s = append(s, '\\', b) s = append(s, '\\', b)
case '\t', '\r', '\n':
s = append(s, b)
default: default:
if b < 32 || b > 127 { // unprintable if b < 32 || b > 127 { // unprintable
var buf [3]byte var buf [3]byte

87
vendor/github.com/miekg/dns/nsecx.go generated vendored
View File

@ -3,7 +3,6 @@ package dns
import ( import (
"crypto/sha1" "crypto/sha1"
"hash" "hash"
"io"
"strings" "strings"
) )
@ -36,75 +35,63 @@ func HashName(label string, ha uint8, iter uint16, salt string) string {
} }
// k = 0 // k = 0
name = append(name, wire...) s.Write(name)
io.WriteString(s, string(name)) s.Write(wire)
nsec3 := s.Sum(nil) nsec3 := s.Sum(nil)
// k > 0 // k > 0
for k := uint16(0); k < iter; k++ { for k := uint16(0); k < iter; k++ {
s.Reset() s.Reset()
nsec3 = append(nsec3, wire...) s.Write(nsec3)
io.WriteString(s, string(nsec3)) s.Write(wire)
nsec3 = s.Sum(nil) nsec3 = s.Sum(nsec3[:0])
} }
return toBase32(nsec3) return toBase32(nsec3)
} }
// Denialer is an interface that should be implemented by types that are used to denial // Cover returns true if a name is covered by the NSEC3 record
// answers in DNSSEC.
type Denialer interface {
// Cover will check if the (unhashed) name is being covered by this NSEC or NSEC3.
Cover(name string) bool
// Match will check if the ownername matches the (unhashed) name for this NSEC3 or NSEC3.
Match(name string) bool
}
// Cover implements the Denialer interface.
func (rr *NSEC) Cover(name string) bool {
return true
}
// Match implements the Denialer interface.
func (rr *NSEC) Match(name string) bool {
return true
}
// Cover implements the Denialer interface.
func (rr *NSEC3) Cover(name string) bool { func (rr *NSEC3) Cover(name string) bool {
// FIXME(miek): check if the zones match nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
// FIXME(miek): check if we're not dealing with parent nsec3 owner := strings.ToUpper(rr.Hdr.Name)
hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt) labelIndices := Split(owner)
labels := Split(rr.Hdr.Name) if len(labelIndices) < 2 {
if len(labels) < 2 {
return false return false
} }
hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the dot ownerHash := owner[:labelIndices[1]-1]
if hash == rr.NextDomain { ownerZone := owner[labelIndices[1]:]
return false // empty interval if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
}
if hash > rr.NextDomain { // last name, points to apex
// hname > hash
// hname > rr.NextDomain
// TODO(miek)
}
if hname <= hash {
return false return false
} }
if hname >= rr.NextDomain {
nextHash := rr.NextDomain
if ownerHash == nextHash { // empty interval
return false return false
} }
return true if ownerHash > nextHash { // end of zone
if nameHash > ownerHash { // covered since there is nothing after ownerHash
return true
}
return nameHash < nextHash // if nameHash is before beginning of zone it is covered
}
if nameHash < ownerHash { // nameHash is before ownerHash, not covered
return false
}
return nameHash < nextHash // if nameHash is before nextHash is it covered (between ownerHash and nextHash)
} }
// Match implements the Denialer interface. // Match returns true if a name matches the NSEC3 record
func (rr *NSEC3) Match(name string) bool { func (rr *NSEC3) Match(name string) bool {
// FIXME(miek): Check if we are in the same zone nameHash := HashName(name, rr.Hash, rr.Iterations, rr.Salt)
hname := HashName(name, rr.Hash, rr.Iterations, rr.Salt) owner := strings.ToUpper(rr.Hdr.Name)
labels := Split(rr.Hdr.Name) labelIndices := Split(owner)
if len(labels) < 2 { if len(labelIndices) < 2 {
return false return false
} }
hash := strings.ToUpper(rr.Hdr.Name[labels[0] : labels[1]-1]) // -1 to remove the . ownerHash := owner[:labelIndices[1]-1]
if hash == hname { ownerZone := owner[labelIndices[1]:]
if !IsSubDomain(ownerZone, strings.ToUpper(name)) { // name is outside owner zone
return false
}
if ownerHash == nameHash {
return true return true
} }
return false return false

View File

@ -6,10 +6,10 @@ var StringToType = reverseInt16(TypeToString)
// StringToClass is the reverse of ClassToString, needed for string parsing. // StringToClass is the reverse of ClassToString, needed for string parsing.
var StringToClass = reverseInt16(ClassToString) var StringToClass = reverseInt16(ClassToString)
// Map of opcodes strings. // StringToOpcode is a map of opcodes to strings.
var StringToOpcode = reverseInt(OpcodeToString) var StringToOpcode = reverseInt(OpcodeToString)
// Map of rcodes strings. // StringToRcode is a map of rcodes to strings.
var StringToRcode = reverseInt(RcodeToString) var StringToRcode = reverseInt(RcodeToString)
// Reverse a map // Reverse a map

24
vendor/github.com/miekg/dns/scan.go generated vendored
View File

@ -278,8 +278,7 @@ func parseZone(r io.Reader, origin, f string, t chan *Token, include int) {
return return
} }
neworigin := origin // There may be optionally a new origin set after the filename, if not use current one neworigin := origin // There may be optionally a new origin set after the filename, if not use current one
l := <-c switch l := <-c; l.value {
switch l.value {
case zBlank: case zBlank:
l := <-c l := <-c
if l.value == zString { if l.value == zString {
@ -627,6 +626,7 @@ func zlexer(s *scan, c chan lex) {
if stri > 0 { if stri > 0 {
l.value = zString l.value = zString
l.token = string(str[:stri]) l.token = string(str[:stri])
l.tokenUpper = strings.ToUpper(l.token)
l.length = stri l.length = stri
debug.Printf("[4 %+v]", l.token) debug.Printf("[4 %+v]", l.token)
c <- l c <- l
@ -663,6 +663,7 @@ func zlexer(s *scan, c chan lex) {
owner = true owner = true
l.value = zNewline l.value = zNewline
l.token = "\n" l.token = "\n"
l.tokenUpper = l.token
l.length = 1 l.length = 1
l.comment = string(com[:comi]) l.comment = string(com[:comi])
debug.Printf("[3 %+v %+v]", l.token, l.comment) debug.Printf("[3 %+v %+v]", l.token, l.comment)
@ -696,6 +697,7 @@ func zlexer(s *scan, c chan lex) {
} }
l.value = zNewline l.value = zNewline
l.token = "\n" l.token = "\n"
l.tokenUpper = l.token
l.length = 1 l.length = 1
debug.Printf("[1 %+v]", l.token) debug.Printf("[1 %+v]", l.token)
c <- l c <- l
@ -740,6 +742,7 @@ func zlexer(s *scan, c chan lex) {
if stri != 0 { if stri != 0 {
l.value = zString l.value = zString
l.token = string(str[:stri]) l.token = string(str[:stri])
l.tokenUpper = strings.ToUpper(l.token)
l.length = stri l.length = stri
debug.Printf("[%+v]", l.token) debug.Printf("[%+v]", l.token)
@ -750,6 +753,7 @@ func zlexer(s *scan, c chan lex) {
// send quote itself as separate token // send quote itself as separate token
l.value = zQuote l.value = zQuote
l.token = "\"" l.token = "\""
l.tokenUpper = l.token
l.length = 1 l.length = 1
c <- l c <- l
quote = !quote quote = !quote
@ -775,6 +779,7 @@ func zlexer(s *scan, c chan lex) {
brace-- brace--
if brace < 0 { if brace < 0 {
l.token = "extra closing brace" l.token = "extra closing brace"
l.tokenUpper = l.token
l.err = true l.err = true
debug.Printf("[%+v]", l.token) debug.Printf("[%+v]", l.token)
c <- l c <- l
@ -799,11 +804,18 @@ func zlexer(s *scan, c chan lex) {
if stri > 0 { if stri > 0 {
// Send remainder // Send remainder
l.token = string(str[:stri]) l.token = string(str[:stri])
l.tokenUpper = strings.ToUpper(l.token)
l.length = stri l.length = stri
l.value = zString l.value = zString
debug.Printf("[%+v]", l.token) debug.Printf("[%+v]", l.token)
c <- l c <- l
} }
if brace != 0 {
l.token = "unbalanced brace"
l.tokenUpper = l.token
l.err = true
c <- l
}
} }
// Extract the class number from CLASSxx // Extract the class number from CLASSxx
@ -812,8 +824,8 @@ func classToInt(token string) (uint16, bool) {
if len(token) < offset+1 { if len(token) < offset+1 {
return 0, false return 0, false
} }
class, ok := strconv.Atoi(token[offset:]) class, err := strconv.ParseUint(token[offset:], 10, 16)
if ok != nil || class > maxUint16 { if err != nil {
return 0, false return 0, false
} }
return uint16(class), true return uint16(class), true
@ -825,8 +837,8 @@ func typeToInt(token string) (uint16, bool) {
if len(token) < offset+1 { if len(token) < offset+1 {
return 0, false return 0, false
} }
typ, ok := strconv.Atoi(token[offset:]) typ, err := strconv.ParseUint(token[offset:], 10, 16)
if ok != nil || typ > maxUint16 { if err != nil {
return 0, false return 0, false
} }
return uint16(typ), true return uint16(typ), true

View File

@ -64,74 +64,63 @@ func endingToString(c chan lex, errstr, f string) (string, *ParseError, string)
return s, nil, l.comment return s, nil, l.comment
} }
// A remainder of the rdata with embedded spaces, return the parsed string slice (sans the spaces) // A remainder of the rdata with embedded spaces, split on unquoted whitespace
// or an error // and return the parsed string slice or an error
func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) { func endingToTxtSlice(c chan lex, errstr, f string) ([]string, *ParseError, string) {
// Get the remaining data until we see a zNewline // Get the remaining data until we see a zNewline
quote := false
l := <-c l := <-c
var s []string
if l.err { 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
} // Build the slice
p, i = p+255, i+255 s := make([]string, 0)
} quote := false
s = append(s, sx...) empty := false
break for l.value != zNewline && l.value != zEOF {
} if l.err {
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 nil, &ParseError{f, errstr, l}, ""
} }
case false: // Unquoted text record switch l.value {
s = make([]string, 1) case zString:
for l.value != zNewline && l.value != zEOF { empty = false
if l.err { if len(l.token) > 255 {
return s, &ParseError{f, errstr, l}, "" // 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 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 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad MX Pref", l}, "" 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 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil { if e != nil {
return nil, &ParseError{f, "bad RT Preference", l}, "" 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 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad AFSDB Subtype", l}, "" 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 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad KX Pref", l}, "" 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 { if l.err {
return nil, &ParseError{f, "bad SOA zone parameter", l}, "" 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 { if i == 0 {
// Serial should be a number // Serial should be a number
return nil, &ParseError{f, "bad SOA zone parameter", l}, "" 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 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad SRV Priority", l}, "" return nil, &ParseError{f, "bad SRV Priority", l}, ""
} }
rr.Priority = uint16(i) rr.Priority = uint16(i)
<-c // zBlank <-c // zBlank
l = <-c // zString l = <-c // zString
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad SRV Weight", l}, "" return nil, &ParseError{f, "bad SRV Weight", l}, ""
} }
rr.Weight = uint16(i) rr.Weight = uint16(i)
<-c // zBlank <-c // zBlank
l = <-c // zString l = <-c // zString
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad SRV Port", l}, "" 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 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad NAPTR Order", l}, "" return nil, &ParseError{f, "bad NAPTR Order", l}, ""
} }
rr.Order = uint16(i) rr.Order = uint16(i)
<-c // zBlank <-c // zBlank
l = <-c // zString l = <-c // zString
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad NAPTR Preference", l}, "" 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 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 32)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad LOC Latitude", l}, "" 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 { if rr.Latitude, ok = locCheckNorth(l.token, rr.Latitude); ok {
goto East goto East
} }
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 32)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad LOC Latitude minutes", l}, "" return nil, &ParseError{f, "bad LOC Latitude minutes", l}, ""
} }
@ -934,7 +923,7 @@ East:
// East // East
<-c // zBlank <-c // zBlank
l = <-c 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}, "" return nil, &ParseError{f, "bad LOC Longitude", l}, ""
} else { } else {
rr.Longitude = 1000 * 60 * 60 * uint32(i) rr.Longitude = 1000 * 60 * 60 * uint32(i)
@ -945,7 +934,7 @@ East:
if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok { if rr.Longitude, ok = locCheckEast(l.token, rr.Longitude); ok {
goto Altitude 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}, "" return nil, &ParseError{f, "bad LOC Longitude minutes", l}, ""
} else { } else {
rr.Longitude += 1000 * 60 * uint32(i) 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 { if l.length == 0 {
return rr, nil, l.comment return rr, nil, l.comment
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad HIP PublicKeyAlgorithm", l}, "" 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 { if v, ok := StringToCertType[l.token]; ok {
rr.Type = v 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}, "" return nil, &ParseError{f, "bad CERT Type", l}, ""
} else { } else {
rr.Type = uint16(i) rr.Type = uint16(i)
} }
<-c // zBlank <-c // zBlank
l = <-c // zString l = <-c // zString
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad CERT KeyTag", l}, "" 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 l = <-c // zString
if v, ok := StringToAlgorithm[l.token]; ok { if v, ok := StringToAlgorithm[l.token]; ok {
rr.Algorithm = v 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}, "" return nil, &ParseError{f, "bad CERT Algorithm", l}, ""
} else { } else {
rr.Algorithm = uint8(i) rr.Algorithm = uint8(i)
@ -1159,21 +1148,21 @@ func setRRSIG(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
} }
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, err := strconv.Atoi(l.token) i, err := strconv.ParseUint(l.token, 10, 8)
if err != nil || l.err { if err != nil || l.err {
return nil, &ParseError{f, "bad RRSIG Algorithm", l}, "" return nil, &ParseError{f, "bad RRSIG Algorithm", l}, ""
} }
rr.Algorithm = uint8(i) rr.Algorithm = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, err = strconv.Atoi(l.token) i, err = strconv.ParseUint(l.token, 10, 8)
if err != nil || l.err { if err != nil || l.err {
return nil, &ParseError{f, "bad RRSIG Labels", l}, "" return nil, &ParseError{f, "bad RRSIG Labels", l}, ""
} }
rr.Labels = uint8(i) rr.Labels = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, err = strconv.Atoi(l.token) i, err = strconv.ParseUint(l.token, 10, 32)
if err != nil || l.err { if err != nil || l.err {
return nil, &ParseError{f, "bad RRSIG OrigTtl", l}, "" 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 <-c // zBlank
l = <-c l = <-c
i, err = strconv.Atoi(l.token) i, err = strconv.ParseUint(l.token, 10, 16)
if err != nil || l.err { if err != nil || l.err {
return nil, &ParseError{f, "bad RRSIG KeyTag", l}, "" 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 { if l.length == 0 {
return rr, nil, l.comment return rr, nil, l.comment
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3 Hash", l}, "" return nil, &ParseError{f, "bad NSEC3 Hash", l}, ""
} }
rr.Hash = uint8(i) rr.Hash = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3 Flags", l}, "" return nil, &ParseError{f, "bad NSEC3 Flags", l}, ""
} }
rr.Flags = uint8(i) rr.Flags = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3 Iterations", l}, "" 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 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, "" return nil, &ParseError{f, "bad NSEC3PARAM Hash", l}, ""
} }
rr.Hash = uint8(i) rr.Hash = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, "" return nil, &ParseError{f, "bad NSEC3PARAM Flags", l}, ""
} }
rr.Flags = uint8(i) rr.Flags = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad NSEC3PARAM Iterations", l}, "" 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 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad SSHFP Algorithm", l}, "" return nil, &ParseError{f, "bad SSHFP Algorithm", l}, ""
} }
rr.Algorithm = uint8(i) rr.Algorithm = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad SSHFP Type", l}, "" 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 { if l.length == 0 {
return rr, nil, l.comment return rr, nil, l.comment
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad " + typ + " Flags", l}, "" return nil, &ParseError{f, "bad " + typ + " Flags", l}, ""
} }
rr.Flags = uint16(i) rr.Flags = uint16(i)
<-c // zBlank <-c // zBlank
l = <-c // zString l = <-c // zString
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad " + typ + " Protocol", l}, "" return nil, &ParseError{f, "bad " + typ + " Protocol", l}, ""
} }
rr.Protocol = uint8(i) rr.Protocol = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c // zString l = <-c // zString
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" 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 { if l.length == 0 {
return rr, nil, l.comment return rr, nil, l.comment
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad RKEY Flags", l}, "" return nil, &ParseError{f, "bad RKEY Flags", l}, ""
} }
rr.Flags = uint16(i) rr.Flags = uint16(i)
<-c // zBlank <-c // zBlank
l = <-c // zString l = <-c // zString
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad RKEY Protocol", l}, "" return nil, &ParseError{f, "bad RKEY Protocol", l}, ""
} }
rr.Protocol = uint8(i) rr.Protocol = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c // zString l = <-c // zString
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad RKEY Algorithm", l}, "" 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 { if l.length == 0 {
return rr, nil, l.comment return rr, nil, l.comment
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, "" return nil, &ParseError{f, "bad " + typ + " KeyTag", l}, ""
} }
rr.KeyTag = uint16(i) rr.KeyTag = uint16(i)
<-c // zBlank <-c // zBlank
l = <-c 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] i, ok := StringToAlgorithm[l.tokenUpper]
if !ok || l.err { if !ok || l.err {
return nil, &ParseError{f, "bad " + typ + " Algorithm", l}, "" 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 <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad " + typ + " DigestType", l}, "" 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 { if l.length == 0 {
return rr, nil, l.comment return rr, nil, l.comment
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad TA KeyTag", l}, "" return nil, &ParseError{f, "bad TA KeyTag", l}, ""
} }
rr.KeyTag = uint16(i) rr.KeyTag = uint16(i)
<-c // zBlank <-c // zBlank
l = <-c 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] i, ok := StringToAlgorithm[l.tokenUpper]
if !ok || l.err { if !ok || l.err {
return nil, &ParseError{f, "bad TA Algorithm", l}, "" 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 <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad TA DigestType", l}, "" 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 { if l.length == 0 {
return rr, nil, l.comment return rr, nil, l.comment
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad TLSA Usage", l}, "" return nil, &ParseError{f, "bad TLSA Usage", l}, ""
} }
rr.Usage = uint8(i) rr.Usage = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad TLSA Selector", l}, "" return nil, &ParseError{f, "bad TLSA Selector", l}, ""
} }
rr.Selector = uint8(i) rr.Selector = uint8(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 8)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad TLSA MatchingType", l}, "" 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 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) { func setRFC3597(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(RFC3597) rr := new(RFC3597)
rr.Hdr = h rr.Hdr = h
@ -1783,6 +1807,18 @@ func setSPF(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, c1 return rr, nil, c1
} }
func setAVC(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(AVC)
rr.Hdr = h
s, e, c1 := endingToTxtSlice(c, "bad AVC Txt", f)
if e != nil {
return nil, e, ""
}
rr.Txt = s
return rr, nil, c1
}
func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) { func setTXT(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr := new(TXT) rr := new(TXT)
rr.Hdr = h rr.Hdr = h
@ -1818,14 +1854,14 @@ func setURI(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad URI Priority", l}, "" return nil, &ParseError{f, "bad URI Priority", l}, ""
} }
rr.Priority = uint16(i) rr.Priority = uint16(i)
<-c // zBlank <-c // zBlank
l = <-c l = <-c
i, e = strconv.Atoi(l.token) i, e = strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad URI Weight", l}, "" return nil, &ParseError{f, "bad URI Weight", l}, ""
} }
@ -1864,7 +1900,7 @@ func setNID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
if l.length == 0 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad NID Preference", l}, "" return nil, &ParseError{f, "bad NID Preference", l}, ""
} }
@ -1887,7 +1923,7 @@ func setL32(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
if l.length == 0 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad L32 Preference", l}, "" return nil, &ParseError{f, "bad L32 Preference", l}, ""
} }
@ -1909,7 +1945,7 @@ func setLP(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
if l.length == 0 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad LP Preference", l}, "" return nil, &ParseError{f, "bad LP Preference", l}, ""
} }
@ -1942,7 +1978,7 @@ func setL64(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
if l.length == 0 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad L64 Preference", l}, "" return nil, &ParseError{f, "bad L64 Preference", l}, ""
} }
@ -1964,7 +2000,7 @@ func setUID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
if l.length == 0 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 32)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad UID Uid", l}, "" return nil, &ParseError{f, "bad UID Uid", l}, ""
} }
@ -1979,7 +2015,7 @@ func setGID(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
if l.length == 0 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 32)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad GID Gid", l}, "" return nil, &ParseError{f, "bad GID Gid", l}, ""
} }
@ -1992,9 +2028,12 @@ func setUINFO(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
rr.Hdr = h rr.Hdr = h
s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f) s, e, c1 := endingToTxtSlice(c, "bad UINFO Uinfo", f)
if e != nil { 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 return rr, nil, c1
} }
@ -2006,7 +2045,7 @@ func setPX(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
if l.length == 0 { if l.length == 0 {
return rr, nil, "" return rr, nil, ""
} }
i, e := strconv.Atoi(l.token) i, e := strconv.ParseUint(l.token, 10, 16)
if e != nil || l.err { if e != nil || l.err {
return nil, &ParseError{f, "bad PX Preference", l}, "" return nil, &ParseError{f, "bad PX Preference", l}, ""
} }
@ -2052,7 +2091,7 @@ func setCAA(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
if l.length == 0 { if l.length == 0 {
return rr, nil, l.comment return rr, nil, l.comment
} }
i, err := strconv.Atoi(l.token) i, err := strconv.ParseUint(l.token, 10, 8)
if err != nil || l.err { if err != nil || l.err {
return nil, &ParseError{f, "bad CAA Flag", l}, "" return nil, &ParseError{f, "bad CAA Flag", l}, ""
} }
@ -2128,8 +2167,10 @@ var typeToparserFunc = map[uint16]parserFunc{
TypeRP: {setRP, false}, TypeRP: {setRP, false},
TypeRRSIG: {setRRSIG, true}, TypeRRSIG: {setRRSIG, true},
TypeRT: {setRT, false}, TypeRT: {setRT, false},
TypeSMIMEA: {setSMIMEA, true},
TypeSOA: {setSOA, false}, TypeSOA: {setSOA, false},
TypeSPF: {setSPF, true}, TypeSPF: {setSPF, true},
TypeAVC: {setAVC, true},
TypeSRV: {setSRV, false}, TypeSRV: {setSRV, false},
TypeSSHFP: {setSSHFP, true}, TypeSSHFP: {setSSHFP, true},
TypeTALINK: {setTALINK, false}, TypeTALINK: {setTALINK, false},

View File

@ -147,7 +147,7 @@ func (mux *ServeMux) match(q string, t uint16) Handler {
b[i] |= ('a' - 'A') b[i] |= ('a' - 'A')
} }
} }
if h, ok := mux.z[string(b[:l])]; ok { // 'causes garbage, might want to change the map key if h, ok := mux.z[string(b[:l])]; ok { // causes garbage, might want to change the map key
if t != TypeDS { if t != TypeDS {
return h return h
} }
@ -339,7 +339,7 @@ func (srv *Server) ListenAndServe() error {
network := "tcp" network := "tcp"
if srv.Net == "tcp4-tls" { if srv.Net == "tcp4-tls" {
network = "tcp4" network = "tcp4"
} else if srv.Net == "tcp6" { } else if srv.Net == "tcp6-tls" {
network = "tcp6" network = "tcp6"
} }
@ -389,7 +389,9 @@ func (srv *Server) ActivateAndServe() error {
if srv.UDPSize == 0 { if srv.UDPSize == 0 {
srv.UDPSize = MinMsgSize 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 { if e := setUDPSocketOptions(t); e != nil {
return e return e
} }

View File

@ -60,16 +60,15 @@ func (rr *SIG) Sign(k crypto.Signer, m *Msg) ([]byte, error) {
} }
rr.Signature = toBase64(signature) rr.Signature = toBase64(signature)
sig := string(signature)
buf = append(buf, sig...) buf = append(buf, signature...)
if len(buf) > int(^uint16(0)) { if len(buf) > int(^uint16(0)) {
return nil, ErrBuf return nil, ErrBuf
} }
// Adjust sig data length // Adjust sig data length
rdoff := len(mbuf) + 1 + 2 + 2 + 4 rdoff := len(mbuf) + 1 + 2 + 2 + 4
rdlen := binary.BigEndian.Uint16(buf[rdoff:]) rdlen := binary.BigEndian.Uint16(buf[rdoff:])
rdlen += uint16(len(sig)) rdlen += uint16(len(signature))
binary.BigEndian.PutUint16(buf[rdoff:], rdlen) binary.BigEndian.PutUint16(buf[rdoff:], rdlen)
// Adjust additional count // Adjust additional count
adc := binary.BigEndian.Uint16(buf[10:]) adc := binary.BigEndian.Uint16(buf[10:])

47
vendor/github.com/miekg/dns/smimea.go generated vendored Normal file
View File

@ -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
}

39
vendor/github.com/miekg/dns/tlsa.go generated vendored
View File

@ -1,50 +1,11 @@
package dns package dns
import ( import (
"crypto/sha256"
"crypto/sha512"
"crypto/x509" "crypto/x509"
"encoding/hex"
"errors"
"io"
"net" "net"
"strconv" "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. // Sign creates a TLSA record from an SSL certificate.
func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) { func (r *TLSA) Sign(usage, selector, matchingType int, cert *x509.Certificate) (err error) {
r.Hdr.Rrtype = TypeTLSA r.Hdr.Rrtype = TypeTLSA

View File

@ -9,7 +9,6 @@ import (
"encoding/binary" "encoding/binary"
"encoding/hex" "encoding/hex"
"hash" "hash"
"io"
"strconv" "strconv"
"strings" "strings"
"time" "time"
@ -124,7 +123,7 @@ func TsigGenerate(m *Msg, secret, requestMAC string, timersOnly bool) ([]byte, s
default: default:
return nil, "", ErrKeyAlg return nil, "", ErrKeyAlg
} }
io.WriteString(h, string(buf)) h.Write(buf)
t.MAC = hex.EncodeToString(h.Sum(nil)) t.MAC = hex.EncodeToString(h.Sum(nil))
t.MACSize = uint16(len(t.MAC) / 2) // Size is half! t.MACSize = uint16(len(t.MAC) / 2) // Size is half!

116
vendor/github.com/miekg/dns/types.go generated vendored
View File

@ -70,6 +70,7 @@ const (
TypeNSEC3 uint16 = 50 TypeNSEC3 uint16 = 50
TypeNSEC3PARAM uint16 = 51 TypeNSEC3PARAM uint16 = 51
TypeTLSA uint16 = 52 TypeTLSA uint16 = 52
TypeSMIMEA uint16 = 53
TypeHIP uint16 = 55 TypeHIP uint16 = 55
TypeNINFO uint16 = 56 TypeNINFO uint16 = 56
TypeRKEY uint16 = 57 TypeRKEY uint16 = 57
@ -90,6 +91,7 @@ const (
TypeEUI64 uint16 = 109 TypeEUI64 uint16 = 109
TypeURI uint16 = 256 TypeURI uint16 = 256
TypeCAA uint16 = 257 TypeCAA uint16 = 257
TypeAVC uint16 = 258
TypeTKEY uint16 = 249 TypeTKEY uint16 = 249
TypeTSIG uint16 = 250 TypeTSIG uint16 = 250
@ -113,27 +115,27 @@ const (
ClassNONE = 254 ClassNONE = 254
ClassANY = 255 ClassANY = 255
// Message Response Codes. // Message Response Codes, see https://www.iana.org/assignments/dns-parameters/dns-parameters.xhtml
RcodeSuccess = 0 RcodeSuccess = 0 // NoError - No Error [DNS]
RcodeFormatError = 1 RcodeFormatError = 1 // FormErr - Format Error [DNS]
RcodeServerFailure = 2 RcodeServerFailure = 2 // ServFail - Server Failure [DNS]
RcodeNameError = 3 RcodeNameError = 3 // NXDomain - Non-Existent Domain [DNS]
RcodeNotImplemented = 4 RcodeNotImplemented = 4 // NotImp - Not Implemented [DNS]
RcodeRefused = 5 RcodeRefused = 5 // Refused - Query Refused [DNS]
RcodeYXDomain = 6 RcodeYXDomain = 6 // YXDomain - Name Exists when it should not [DNS Update]
RcodeYXRrset = 7 RcodeYXRrset = 7 // YXRRSet - RR Set Exists when it should not [DNS Update]
RcodeNXRrset = 8 RcodeNXRrset = 8 // NXRRSet - RR Set that should exist does not [DNS Update]
RcodeNotAuth = 9 RcodeNotAuth = 9 // NotAuth - Server Not Authoritative for zone [DNS Update]
RcodeNotZone = 10 RcodeNotZone = 10 // NotZone - Name not contained in zone [DNS Update/TSIG]
RcodeBadSig = 16 // TSIG RcodeBadSig = 16 // BADSIG - TSIG Signature Failure [TSIG]
RcodeBadVers = 16 // EDNS0 RcodeBadVers = 16 // BADVERS - Bad OPT Version [EDNS0]
RcodeBadKey = 17 RcodeBadKey = 17 // BADKEY - Key not recognized [TSIG]
RcodeBadTime = 18 RcodeBadTime = 18 // BADTIME - Signature out of time window [TSIG]
RcodeBadMode = 19 // TKEY RcodeBadMode = 19 // BADMODE - Bad TKEY Mode [TKEY]
RcodeBadName = 20 RcodeBadName = 20 // BADNAME - Duplicate key name [TKEY]
RcodeBadAlg = 21 RcodeBadAlg = 21 // BADALG - Algorithm not supported [TKEY]
RcodeBadTrunc = 22 // TSIG RcodeBadTrunc = 22 // BADTRUNC - Bad Truncation [TSIG]
RcodeBadCookie = 23 // DNS Cookies RcodeBadCookie = 23 // BADCOOKIE - Bad/missing Server Cookie [DNS Cookies]
// Message Opcodes. There is no 3. // Message Opcodes. There is no 3.
OpcodeQuery = 0 OpcodeQuery = 0
@ -143,7 +145,7 @@ const (
OpcodeUpdate = 5 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 { type Header struct {
Id uint16 Id uint16
Bits uint16 Bits uint16
@ -479,12 +481,6 @@ func appendDomainNameByte(s []byte, b byte) []byte {
func appendTXTStringByte(s []byte, b byte) []byte { func appendTXTStringByte(s []byte, b byte) []byte {
switch b { switch b {
case '\t':
return append(s, '\\', 't')
case '\r':
return append(s, '\\', 'r')
case '\n':
return append(s, '\\', 'n')
case '"', '\\': case '"', '\\':
return append(s, '\\', b) return append(s, '\\', b)
} }
@ -524,17 +520,8 @@ func nextByte(b []byte, offset int) (byte, int) {
return dddToByte(b[offset+1:]), 4 return dddToByte(b[offset+1:]), 4
} }
} }
// not \ddd, maybe a control char // not \ddd, just an RFC 1035 "quoted" character
switch b[offset+1] { return b[offset+1], 2
case 't':
return '\t', 2
case 'r':
return '\r', 2
case 'n':
return '\n', 2
default:
return b[offset+1], 2
}
} }
type SPF struct { type SPF struct {
@ -544,6 +531,13 @@ type SPF struct {
func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) } func (rr *SPF) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
type AVC struct {
Hdr RR_Header
Txt []string `dns:"txt"`
}
func (rr *AVC) String() string { return rr.Hdr.String() + sprintTxt(rr.Txt) }
type SRV struct { type SRV struct {
Hdr RR_Header Hdr RR_Header
Priority uint16 Priority uint16
@ -1047,6 +1041,28 @@ func (rr *TLSA) String() string {
" " + rr.Certificate " " + 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 { type HIP struct {
Hdr RR_Header Hdr RR_Header
HitLength uint8 HitLength uint8
@ -1247,3 +1263,25 @@ func copyIP(ip net.IP) net.IP {
copy(p, ip) copy(p, ip)
return p 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
}

View File

@ -197,7 +197,7 @@ func main() {
case st.Tag(i) == "": case st.Tag(i) == "":
switch st.Field(i).Type().(*types.Basic).Kind() { switch st.Field(i).Type().(*types.Basic).Kind() {
case types.Uint8: case types.Uint8:
o("l += 1 // %s\n") o("l++ // %s\n")
case types.Uint16: case types.Uint16:
o("l += 2 // %s\n") o("l += 2 // %s\n")
case types.Uint32: case types.Uint32:

26
vendor/github.com/miekg/dns/udp.go generated vendored
View File

@ -1,10 +1,9 @@
// +build !windows,!plan9 // +build !windows
package dns package dns
import ( import (
"net" "net"
"syscall"
) )
// SessionUDP holds the remote address and the associated // SessionUDP holds the remote address and the associated
@ -17,29 +16,6 @@ type SessionUDP struct {
// RemoteAddr returns the remote network address. // RemoteAddr returns the remote network address.
func (s *SessionUDP) RemoteAddr() net.Addr { return s.raddr } 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 // ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
// net.UDPAddr. // net.UDPAddr.
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) {

View File

@ -1,4 +1,4 @@
// +build linux // +build linux,!appengine
package dns package dns
@ -15,6 +15,29 @@ import (
"syscall" "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. // setUDPSocketOptions4 prepares the v4 socket for sessions.
func setUDPSocketOptions4(conn *net.UDPConn) error { func setUDPSocketOptions4(conn *net.UDPConn) error {
file, err := conn.File() file, err := conn.File()
@ -22,14 +45,17 @@ func setUDPSocketOptions4(conn *net.UDPConn) error {
return err return err
} }
if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IP, syscall.IP_PKTINFO, 1); err != nil { if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IP, syscall.IP_PKTINFO, 1); err != nil {
file.Close()
return err return err
} }
// Calling File() above results in the connection becoming blocking, we must fix that. // Calling File() above results in the connection becoming blocking, we must fix that.
// See https://github.com/miekg/dns/issues/279 // See https://github.com/miekg/dns/issues/279
err = syscall.SetNonblock(int(file.Fd()), true) err = syscall.SetNonblock(int(file.Fd()), true)
if err != nil { if err != nil {
file.Close()
return err return err
} }
file.Close()
return nil return nil
} }
@ -40,12 +66,15 @@ func setUDPSocketOptions6(conn *net.UDPConn) error {
return err return err
} }
if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1); err != nil { if err := syscall.SetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_RECVPKTINFO, 1); err != nil {
file.Close()
return err return err
} }
err = syscall.SetNonblock(int(file.Fd()), true) err = syscall.SetNonblock(int(file.Fd()), true)
if err != nil { if err != nil {
file.Close()
return err return err
} }
file.Close()
return nil 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 // 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) v6only, err := syscall.GetsockoptInt(int(file.Fd()), syscall.IPPROTO_IPV6, syscall.IPV6_V6ONLY)
if err != nil { if err != nil {
file.Close()
return false, err return false, err
} }
file.Close()
return v6only == 1, nil return v6only == 1, nil
} }
@ -69,5 +100,6 @@ func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) {
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer file.Close()
return syscall.Getsockname(int(file.Fd())) return syscall.Getsockname(int(file.Fd()))
} }

View File

@ -1,17 +1,15 @@
// +build !linux,!plan9 // +build !linux appengine
package dns package dns
import ( import (
"net" "net"
"syscall"
) )
// These do nothing. See udp_linux.go for an example of how to implement this. // 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. // 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 setUDPSocketOptions4(conn *net.UDPConn) error { return nil }
func setUDPSocketOptions6(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 getUDPSocketOptions6Only(conn *net.UDPConn) (bool, error) { return false, nil }
func getUDPSocketName(conn *net.UDPConn) (syscall.Sockaddr, error) { return nil, nil }

View File

@ -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
}

View File

@ -8,6 +8,8 @@ type SessionUDP struct {
raddr *net.UDPAddr 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 // ReadFromSessionUDP acts just like net.UDPConn.ReadFrom(), but returns a session object instead of a
// net.UDPAddr. // net.UDPAddr.
func ReadFromSessionUDP(conn *net.UDPConn, b []byte) (int, *SessionUDP, error) { 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 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
}

11
vendor/github.com/miekg/dns/xfr.go generated vendored
View File

@ -1,6 +1,7 @@
package dns package dns
import ( import (
"fmt"
"time" "time"
) )
@ -81,6 +82,10 @@ func (t *Transfer) inAxfr(id uint16, c chan *Envelope) {
return return
} }
if first { if first {
if in.Rcode != RcodeSuccess {
c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
return
}
if !isSOAFirst(in) { if !isSOAFirst(in) {
c <- &Envelope{in.Answer, ErrSoa} c <- &Envelope{in.Answer, ErrSoa}
return return
@ -126,6 +131,10 @@ func (t *Transfer) inIxfr(id uint16, c chan *Envelope) {
return return
} }
if first { if first {
if in.Rcode != RcodeSuccess {
c <- &Envelope{in.Answer, &Error{err: fmt.Sprintf(errXFR, in.Rcode)}}
return
}
// A single SOA RR signals "no changes" // A single SOA RR signals "no changes"
if len(in.Answer) == 1 && isSOAFirst(in) { if len(in.Answer) == 1 && isSOAFirst(in) {
c <- &Envelope{in.Answer, nil} c <- &Envelope{in.Answer, nil}
@ -242,3 +251,5 @@ func isSOALast(in *Msg) bool {
} }
return false return false
} }
const errXFR = "bad xfr rcode: %d"

119
vendor/github.com/miekg/dns/zcompress.go generated vendored Normal file
View File

@ -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 *PTR:
compressionLenHelper(c, x.Ptr)
case *SOA:
compressionLenHelper(c, x.Ns)
compressionLenHelper(c, x.Mbox)
case *AFSDB:
compressionLenHelper(c, x.Hostname)
case *HIP:
for i := range x.RendezvousServers {
compressionLenHelper(c, x.RendezvousServers[i])
}
case *LP:
compressionLenHelper(c, x.Fqdn)
case *CNAME:
compressionLenHelper(c, x.Target)
case *MB:
compressionLenHelper(c, x.Mb)
case *RP:
compressionLenHelper(c, x.Mbox)
compressionLenHelper(c, x.Txt)
case *RRSIG:
compressionLenHelper(c, x.SignerName)
case *MF:
compressionLenHelper(c, x.Mf)
case *MINFO:
compressionLenHelper(c, x.Rmail)
compressionLenHelper(c, x.Email)
case *SIG:
compressionLenHelper(c, x.SignerName)
case *SRV:
compressionLenHelper(c, x.Target)
case *TSIG:
compressionLenHelper(c, x.Algorithm)
case *KX:
compressionLenHelper(c, x.Exchanger)
case *MG:
compressionLenHelper(c, x.Mg)
case *NSAPPTR:
compressionLenHelper(c, x.Ptr)
case *PX:
compressionLenHelper(c, x.Map822)
compressionLenHelper(c, x.Mapx400)
case *DNAME:
compressionLenHelper(c, x.Target)
case *MR:
compressionLenHelper(c, x.Mr)
case *MX:
compressionLenHelper(c, x.Mx)
case *TKEY:
compressionLenHelper(c, x.Algorithm)
case *NSEC:
compressionLenHelper(c, x.NextDomain)
case *TALINK:
compressionLenHelper(c, x.PreviousName)
compressionLenHelper(c, x.NextName)
case *MD:
compressionLenHelper(c, x.Md)
case *NAPTR:
compressionLenHelper(c, x.Replacement)
case *NS:
compressionLenHelper(c, x.Ns)
case *RT:
compressionLenHelper(c, x.Host)
}
}
func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
switch x := r.(type) {
case *MG:
k1, ok1 := compressionLenSearch(c, x.Mg)
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 *MB:
k1, ok1 := compressionLenSearch(c, x.Mb)
return k1, ok1
case *MD:
k1, ok1 := compressionLenSearch(c, x.Md)
return k1, ok1
case *MF:
k1, ok1 := compressionLenSearch(c, x.Mf)
return k1, ok1
case *NS:
k1, ok1 := compressionLenSearch(c, x.Ns)
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 *CNAME:
k1, ok1 := compressionLenSearch(c, x.Target)
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 *MX:
k1, ok1 := compressionLenSearch(c, x.Mx)
return k1, ok1
}
return 0, false
}

151
vendor/github.com/miekg/dns/zmsg.go generated vendored
View File

@ -61,6 +61,20 @@ func (rr *ANY) pack(msg []byte, off int, compression map[string]int, compress bo
return off, nil return off, nil
} }
func (rr *AVC) 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 = packStringTxt(rr.Txt, msg, off)
if err != nil {
return off, err
}
rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil
}
func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) { func (rr *CAA) pack(msg []byte, off int, compression map[string]int, compress bool) (int, error) {
off, err := rr.Hdr.pack(msg, off, compression, compress) off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil { if err != nil {
@ -221,7 +235,7 @@ func (rr *DNAME) pack(msg []byte, off int, compression map[string]int, compress
return off, err return off, err
} }
headerEnd := off headerEnd := off
off, err = PackDomainName(rr.Target, msg, off, compression, compress) off, err = PackDomainName(rr.Target, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -447,7 +461,7 @@ func (rr *KX) pack(msg []byte, off int, compression map[string]int, compress boo
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.Exchanger, msg, off, compression, compress) off, err = PackDomainName(rr.Exchanger, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -539,7 +553,7 @@ func (rr *LP) pack(msg []byte, off int, compression map[string]int, compress boo
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.Fqdn, msg, off, compression, compress) off, err = PackDomainName(rr.Fqdn, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -679,7 +693,7 @@ func (rr *NAPTR) pack(msg []byte, off int, compression map[string]int, compress
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.Replacement, msg, off, compression, compress) off, err = PackDomainName(rr.Replacement, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -753,7 +767,7 @@ func (rr *NSAPPTR) pack(msg []byte, off int, compression map[string]int, compres
return off, err return off, err
} }
headerEnd := off headerEnd := off
off, err = PackDomainName(rr.Ptr, msg, off, compression, compress) off, err = PackDomainName(rr.Ptr, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -767,7 +781,7 @@ func (rr *NSEC) pack(msg []byte, off int, compression map[string]int, compress b
return off, err return off, err
} }
headerEnd := off headerEnd := off
off, err = PackDomainName(rr.NextDomain, msg, off, compression, compress) off, err = PackDomainName(rr.NextDomain, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -801,10 +815,12 @@ func (rr *NSEC3) pack(msg []byte, off int, compression map[string]int, compress
if err != nil { if err != nil {
return off, err return off, err
} }
if rr.Salt == "-" { /* do nothing, empty salt */ // Only pack salt if value is not "-", i.e. empty
} if rr.Salt != "-" {
if err != nil { off, err = packStringHex(rr.Salt, msg, off)
return off, err if err != nil {
return off, err
}
} }
off, err = packUint8(rr.HashLength, msg, off) off, err = packUint8(rr.HashLength, msg, off)
if err != nil { if err != nil {
@ -844,10 +860,12 @@ func (rr *NSEC3PARAM) pack(msg []byte, off int, compression map[string]int, comp
if err != nil { if err != nil {
return off, err return off, err
} }
if rr.Salt == "-" { /* do nothing, empty salt */ // Only pack salt if value is not "-", i.e. empty
} if rr.Salt != "-" {
if err != nil { off, err = packStringHex(rr.Salt, msg, off)
return off, err if err != nil {
return off, err
}
} }
rr.Header().Rdlength = uint16(off - headerEnd) rr.Header().Rdlength = uint16(off - headerEnd)
return off, nil return off, nil
@ -905,11 +923,11 @@ func (rr *PX) pack(msg []byte, off int, compression map[string]int, compress boo
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.Map822, msg, off, compression, compress) off, err = PackDomainName(rr.Map822, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.Mapx400, msg, off, compression, compress) off, err = PackDomainName(rr.Mapx400, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -963,11 +981,11 @@ func (rr *RP) pack(msg []byte, off int, compression map[string]int, compress boo
return off, err return off, err
} }
headerEnd := off headerEnd := off
off, err = PackDomainName(rr.Mbox, msg, off, compression, compress) off, err = PackDomainName(rr.Mbox, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.Txt, msg, off, compression, compress) off, err = PackDomainName(rr.Txt, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -1009,7 +1027,7 @@ func (rr *RRSIG) pack(msg []byte, off int, compression map[string]int, compress
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.SignerName, msg, off, compression, compress) off, err = PackDomainName(rr.SignerName, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -1073,7 +1091,7 @@ func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.SignerName, msg, off, compression, compress) off, err = PackDomainName(rr.SignerName, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -1085,6 +1103,32 @@ func (rr *SIG) pack(msg []byte, off int, compression map[string]int, compress bo
return off, nil 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) { 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) off, err := rr.Hdr.pack(msg, off, compression, compress)
if err != nil { if err != nil {
@ -1155,7 +1199,7 @@ func (rr *SRV) pack(msg []byte, off int, compression map[string]int, compress bo
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.Target, msg, off, compression, compress) off, err = PackDomainName(rr.Target, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -1217,11 +1261,11 @@ func (rr *TALINK) pack(msg []byte, off int, compression map[string]int, compress
return off, err return off, err
} }
headerEnd := off headerEnd := off
off, err = PackDomainName(rr.PreviousName, msg, off, compression, compress) off, err = PackDomainName(rr.PreviousName, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
off, err = PackDomainName(rr.NextName, msg, off, compression, compress) off, err = PackDomainName(rr.NextName, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -1235,7 +1279,7 @@ func (rr *TKEY) pack(msg []byte, off int, compression map[string]int, compress b
return off, err return off, err
} }
headerEnd := off headerEnd := off
off, err = PackDomainName(rr.Algorithm, msg, off, compression, compress) off, err = PackDomainName(rr.Algorithm, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -1307,7 +1351,7 @@ func (rr *TSIG) pack(msg []byte, off int, compression map[string]int, compress b
return off, err return off, err
} }
headerEnd := off headerEnd := off
off, err = PackDomainName(rr.Algorithm, msg, off, compression, compress) off, err = PackDomainName(rr.Algorithm, msg, off, compression, false)
if err != nil { if err != nil {
return off, err return off, err
} }
@ -1498,6 +1542,23 @@ func unpackANY(h RR_Header, msg []byte, off int) (RR, int, error) {
return rr, off, err return rr, off, err
} }
func unpackAVC(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(AVC)
rr.Hdr = h
if noRdata(h) {
return rr, off, nil
}
var err error
rdStart := off
_ = rdStart
rr.Txt, off, err = unpackStringTxt(msg, off)
if err != nil {
return rr, off, err
}
return rr, off, err
}
func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) { func unpackCAA(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(CAA) rr := new(CAA)
rr.Hdr = h rr.Hdr = h
@ -2907,6 +2968,44 @@ func unpackSIG(h RR_Header, msg []byte, off int) (RR, int, error) {
return rr, off, err 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) { func unpackSOA(h RR_Header, msg []byte, off int) (RR, int, error) {
rr := new(SOA) rr := new(SOA)
rr.Hdr = h rr.Hdr = h
@ -3399,6 +3498,7 @@ var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
TypeAAAA: unpackAAAA, TypeAAAA: unpackAAAA,
TypeAFSDB: unpackAFSDB, TypeAFSDB: unpackAFSDB,
TypeANY: unpackANY, TypeANY: unpackANY,
TypeAVC: unpackAVC,
TypeCAA: unpackCAA, TypeCAA: unpackCAA,
TypeCDNSKEY: unpackCDNSKEY, TypeCDNSKEY: unpackCDNSKEY,
TypeCDS: unpackCDS, TypeCDS: unpackCDS,
@ -3447,6 +3547,7 @@ var typeToUnpack = map[uint16]func(RR_Header, []byte, int) (RR, int, error){
TypeRRSIG: unpackRRSIG, TypeRRSIG: unpackRRSIG,
TypeRT: unpackRT, TypeRT: unpackRT,
TypeSIG: unpackSIG, TypeSIG: unpackSIG,
TypeSMIMEA: unpackSMIMEA,
TypeSOA: unpackSOA, TypeSOA: unpackSOA,
TypeSPF: unpackSPF, TypeSPF: unpackSPF,
TypeSRV: unpackSRV, TypeSRV: unpackSRV,

View File

@ -14,6 +14,7 @@ var TypeToRR = map[uint16]func() RR{
TypeAAAA: func() RR { return new(AAAA) }, TypeAAAA: func() RR { return new(AAAA) },
TypeAFSDB: func() RR { return new(AFSDB) }, TypeAFSDB: func() RR { return new(AFSDB) },
TypeANY: func() RR { return new(ANY) }, TypeANY: func() RR { return new(ANY) },
TypeAVC: func() RR { return new(AVC) },
TypeCAA: func() RR { return new(CAA) }, TypeCAA: func() RR { return new(CAA) },
TypeCDNSKEY: func() RR { return new(CDNSKEY) }, TypeCDNSKEY: func() RR { return new(CDNSKEY) },
TypeCDS: func() RR { return new(CDS) }, TypeCDS: func() RR { return new(CDS) },
@ -62,6 +63,7 @@ var TypeToRR = map[uint16]func() RR{
TypeRRSIG: func() RR { return new(RRSIG) }, TypeRRSIG: func() RR { return new(RRSIG) },
TypeRT: func() RR { return new(RT) }, TypeRT: func() RR { return new(RT) },
TypeSIG: func() RR { return new(SIG) }, TypeSIG: func() RR { return new(SIG) },
TypeSMIMEA: func() RR { return new(SMIMEA) },
TypeSOA: func() RR { return new(SOA) }, TypeSOA: func() RR { return new(SOA) },
TypeSPF: func() RR { return new(SPF) }, TypeSPF: func() RR { return new(SPF) },
TypeSRV: func() RR { return new(SRV) }, TypeSRV: func() RR { return new(SRV) },
@ -85,6 +87,7 @@ var TypeToString = map[uint16]string{
TypeAFSDB: "AFSDB", TypeAFSDB: "AFSDB",
TypeANY: "ANY", TypeANY: "ANY",
TypeATMA: "ATMA", TypeATMA: "ATMA",
TypeAVC: "AVC",
TypeAXFR: "AXFR", TypeAXFR: "AXFR",
TypeCAA: "CAA", TypeCAA: "CAA",
TypeCDNSKEY: "CDNSKEY", TypeCDNSKEY: "CDNSKEY",
@ -141,6 +144,7 @@ var TypeToString = map[uint16]string{
TypeRT: "RT", TypeRT: "RT",
TypeReserved: "Reserved", TypeReserved: "Reserved",
TypeSIG: "SIG", TypeSIG: "SIG",
TypeSMIMEA: "SMIMEA",
TypeSOA: "SOA", TypeSOA: "SOA",
TypeSPF: "SPF", TypeSPF: "SPF",
TypeSRV: "SRV", TypeSRV: "SRV",
@ -164,6 +168,7 @@ func (rr *A) Header() *RR_Header { return &rr.Hdr }
func (rr *AAAA) Header() *RR_Header { return &rr.Hdr } func (rr *AAAA) Header() *RR_Header { return &rr.Hdr }
func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr } func (rr *AFSDB) Header() *RR_Header { return &rr.Hdr }
func (rr *ANY) Header() *RR_Header { return &rr.Hdr } func (rr *ANY) Header() *RR_Header { return &rr.Hdr }
func (rr *AVC) Header() *RR_Header { return &rr.Hdr }
func (rr *CAA) Header() *RR_Header { return &rr.Hdr } func (rr *CAA) Header() *RR_Header { return &rr.Hdr }
func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr } func (rr *CDNSKEY) Header() *RR_Header { return &rr.Hdr }
func (rr *CDS) Header() *RR_Header { return &rr.Hdr } func (rr *CDS) Header() *RR_Header { return &rr.Hdr }
@ -213,6 +218,7 @@ func (rr *RP) Header() *RR_Header { return &rr.Hdr }
func (rr *RRSIG) 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 *RT) Header() *RR_Header { return &rr.Hdr }
func (rr *SIG) 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 *SOA) Header() *RR_Header { return &rr.Hdr }
func (rr *SPF) Header() *RR_Header { return &rr.Hdr } func (rr *SPF) Header() *RR_Header { return &rr.Hdr }
func (rr *SRV) Header() *RR_Header { return &rr.Hdr } func (rr *SRV) Header() *RR_Header { return &rr.Hdr }
@ -249,9 +255,16 @@ func (rr *ANY) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
return l return l
} }
func (rr *AVC) len() int {
l := rr.Hdr.len()
for _, x := range rr.Txt {
l += len(x) + 1
}
return l
}
func (rr *CAA) len() int { func (rr *CAA) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 1 // Flag l++ // Flag
l += len(rr.Tag) + 1 l += len(rr.Tag) + 1
l += len(rr.Value) l += len(rr.Value)
return l return l
@ -260,7 +273,7 @@ func (rr *CERT) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 2 // Type l += 2 // Type
l += 2 // KeyTag l += 2 // KeyTag
l += 1 // Algorithm l++ // Algorithm
l += base64.StdEncoding.DecodedLen(len(rr.Certificate)) l += base64.StdEncoding.DecodedLen(len(rr.Certificate))
return l return l
} }
@ -282,16 +295,16 @@ func (rr *DNAME) len() int {
func (rr *DNSKEY) len() int { func (rr *DNSKEY) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 2 // Flags l += 2 // Flags
l += 1 // Protocol l++ // Protocol
l += 1 // Algorithm l++ // Algorithm
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
return l return l
} }
func (rr *DS) len() int { func (rr *DS) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 2 // KeyTag l += 2 // KeyTag
l += 1 // Algorithm l++ // Algorithm
l += 1 // DigestType l++ // DigestType
l += len(rr.Digest)/2 + 1 l += len(rr.Digest)/2 + 1
return l return l
} }
@ -330,8 +343,8 @@ func (rr *HINFO) len() int {
} }
func (rr *HIP) len() int { func (rr *HIP) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 1 // HitLength l++ // HitLength
l += 1 // PublicKeyAlgorithm l++ // PublicKeyAlgorithm
l += 2 // PublicKeyLength l += 2 // PublicKeyLength
l += len(rr.Hit)/2 + 1 l += len(rr.Hit)/2 + 1
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
@ -360,10 +373,10 @@ func (rr *L64) len() int {
} }
func (rr *LOC) len() int { func (rr *LOC) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 1 // Version l++ // Version
l += 1 // Size l++ // Size
l += 1 // HorizPre l++ // HorizPre
l += 1 // VertPre l++ // VertPre
l += 4 // Latitude l += 4 // Latitude
l += 4 // Longitude l += 4 // Longitude
l += 4 // Altitude l += 4 // Altitude
@ -452,10 +465,10 @@ func (rr *NSAPPTR) len() int {
} }
func (rr *NSEC3PARAM) len() int { func (rr *NSEC3PARAM) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 1 // Hash l++ // Hash
l += 1 // Flags l++ // Flags
l += 2 // Iterations l += 2 // Iterations
l += 1 // SaltLength l++ // SaltLength
l += len(rr.Salt)/2 + 1 l += len(rr.Salt)/2 + 1
return l return l
} }
@ -484,8 +497,8 @@ func (rr *RFC3597) len() int {
func (rr *RKEY) len() int { func (rr *RKEY) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 2 // Flags l += 2 // Flags
l += 1 // Protocol l++ // Protocol
l += 1 // Algorithm l++ // Algorithm
l += base64.StdEncoding.DecodedLen(len(rr.PublicKey)) l += base64.StdEncoding.DecodedLen(len(rr.PublicKey))
return l return l
} }
@ -498,8 +511,8 @@ func (rr *RP) len() int {
func (rr *RRSIG) len() int { func (rr *RRSIG) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 2 // TypeCovered l += 2 // TypeCovered
l += 1 // Algorithm l++ // Algorithm
l += 1 // Labels l++ // Labels
l += 4 // OrigTtl l += 4 // OrigTtl
l += 4 // Expiration l += 4 // Expiration
l += 4 // Inception l += 4 // Inception
@ -514,6 +527,14 @@ func (rr *RT) len() int {
l += len(rr.Host) + 1 l += len(rr.Host) + 1
return l 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 { func (rr *SOA) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += len(rr.Ns) + 1 l += len(rr.Ns) + 1
@ -542,16 +563,16 @@ func (rr *SRV) len() int {
} }
func (rr *SSHFP) len() int { func (rr *SSHFP) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 1 // Algorithm l++ // Algorithm
l += 1 // Type l++ // Type
l += len(rr.FingerPrint)/2 + 1 l += len(rr.FingerPrint)/2 + 1
return l return l
} }
func (rr *TA) len() int { func (rr *TA) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 2 // KeyTag l += 2 // KeyTag
l += 1 // Algorithm l++ // Algorithm
l += 1 // DigestType l++ // DigestType
l += len(rr.Digest)/2 + 1 l += len(rr.Digest)/2 + 1
return l return l
} }
@ -576,9 +597,9 @@ func (rr *TKEY) len() int {
} }
func (rr *TLSA) len() int { func (rr *TLSA) len() int {
l := rr.Hdr.len() l := rr.Hdr.len()
l += 1 // Usage l++ // Usage
l += 1 // Selector l++ // Selector
l += 1 // MatchingType l++ // MatchingType
l += len(rr.Certificate)/2 + 1 l += len(rr.Certificate)/2 + 1
return l return l
} }
@ -638,6 +659,11 @@ func (rr *AFSDB) copy() RR {
func (rr *ANY) copy() RR { func (rr *ANY) copy() RR {
return &ANY{*rr.Hdr.copyHeader()} return &ANY{*rr.Hdr.copyHeader()}
} }
func (rr *AVC) copy() RR {
Txt := make([]string, len(rr.Txt))
copy(Txt, rr.Txt)
return &AVC{*rr.Hdr.copyHeader(), Txt}
}
func (rr *CAA) copy() RR { func (rr *CAA) copy() RR {
return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value} return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value}
} }
@ -780,6 +806,9 @@ func (rr *RRSIG) copy() RR {
func (rr *RT) copy() RR { func (rr *RT) copy() RR {
return &RT{*rr.Hdr.copyHeader(), rr.Preference, rr.Host} 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 { func (rr *SOA) copy() RR {
return &SOA{*rr.Hdr.copyHeader(), rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl} return &SOA{*rr.Hdr.copyHeader(), rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl}
} }

2
vendor/vendor.json vendored
View File

@ -63,7 +63,7 @@
{"path":"github.com/hashicorp/serf/serf","checksumSHA1":"3WPnGSL9ZK6EmkAE6tEW5SCxrd8=","comment":"v0.7.0-66-g6c4672d","revision":"b84a66cc5575994cb672940d244a2404141688c0","revisionTime":"2017-08-17T21:22:02Z"}, {"path":"github.com/hashicorp/serf/serf","checksumSHA1":"3WPnGSL9ZK6EmkAE6tEW5SCxrd8=","comment":"v0.7.0-66-g6c4672d","revision":"b84a66cc5575994cb672940d244a2404141688c0","revisionTime":"2017-08-17T21:22:02Z"},
{"path":"github.com/hashicorp/yamux","checksumSHA1":"ZhK6IO2XN81Y+3RAjTcVm1Ic7oU=","revision":"d1caa6c97c9fc1cc9e83bbe34d0603f9ff0ce8bd","revisionTime":"2016-07-20T23:31:40Z"}, {"path":"github.com/hashicorp/yamux","checksumSHA1":"ZhK6IO2XN81Y+3RAjTcVm1Ic7oU=","revision":"d1caa6c97c9fc1cc9e83bbe34d0603f9ff0ce8bd","revisionTime":"2016-07-20T23:31:40Z"},
{"path":"github.com/mattn/go-isatty","checksumSHA1":"xZuhljnmBysJPta/lMyYmJdujCg=","revision":"66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8","revisionTime":"2016-08-06T12:27:52Z"}, {"path":"github.com/mattn/go-isatty","checksumSHA1":"xZuhljnmBysJPta/lMyYmJdujCg=","revision":"66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8","revisionTime":"2016-08-06T12:27:52Z"},
{"path":"github.com/miekg/dns","checksumSHA1":"OUZ1FFXyKs+Cfg9M9rmXqqweQck=","revision":"db96a2b759cdef4f11a34506a42eb8d1290c598e","revisionTime":"2016-07-26T03:20:27Z"}, {"path":"github.com/miekg/dns","checksumSHA1":"Jo+pItYOocIRdoFL0fc4nHhUEJY=","revision":"bbca4873b326f5dc54bfe31148446d4ed79a5a02","revisionTime":"2017-08-08T22:19:10Z"},
{"path":"github.com/mitchellh/cli","checksumSHA1":"GzfpPGtV2UJH9hFsKwzGjKrhp/A=","revision":"dff723fff508858a44c1f4bd0911f00d73b0202f","revisionTime":"2017-09-05T22:10:09Z"}, {"path":"github.com/mitchellh/cli","checksumSHA1":"GzfpPGtV2UJH9hFsKwzGjKrhp/A=","revision":"dff723fff508858a44c1f4bd0911f00d73b0202f","revisionTime":"2017-09-05T22:10:09Z"},
{"path":"github.com/mitchellh/copystructure","checksumSHA1":"86nE93o1VIND0Doe8PuhCXnhUx0=","revision":"cdac8253d00f2ecf0a0b19fbff173a9a72de4f82","revisionTime":"2016-08-04T03:23:30Z"}, {"path":"github.com/mitchellh/copystructure","checksumSHA1":"86nE93o1VIND0Doe8PuhCXnhUx0=","revision":"cdac8253d00f2ecf0a0b19fbff173a9a72de4f82","revisionTime":"2016-08-04T03:23:30Z"},
{"path":"github.com/mitchellh/go-homedir","checksumSHA1":"V/quM7+em2ByJbWBLOsEwnY3j/Q=","revision":"b8bc1bf767474819792c23f32d8286a45736f1c6","revisionTime":"2016-12-03T19:45:07Z"}, {"path":"github.com/mitchellh/go-homedir","checksumSHA1":"V/quM7+em2ByJbWBLOsEwnY3j/Q=","revision":"b8bc1bf767474819792c23f32d8286a45736f1c6","revisionTime":"2016-12-03T19:45:07Z"},