From 61e7d061741853ab9ebaa0e00e959163a7fc0a27 Mon Sep 17 00:00:00 2001
From: Pierre Souchay
Date: Wed, 16 May 2018 10:52:51 +0200
Subject: [PATCH 1/8] Bump DNS lib to 1.0.7 with 14bits Len() fix
---
vendor/github.com/miekg/dns/client.go | 104 ++++++++-
vendor/github.com/miekg/dns/clientconfig.go | 2 +-
.../github.com/miekg/dns/compress_generate.go | 28 ++-
vendor/github.com/miekg/dns/dns.go | 10 -
vendor/github.com/miekg/dns/dnssec.go | 5 +-
vendor/github.com/miekg/dns/doc.go | 4 +-
vendor/github.com/miekg/dns/msg.go | 160 +++++++++-----
vendor/github.com/miekg/dns/privaterr.go | 3 +-
vendor/github.com/miekg/dns/scan_rr.go | 12 +-
vendor/github.com/miekg/dns/server.go | 199 ++++++++++++------
vendor/github.com/miekg/dns/types_generate.go | 2 +-
vendor/github.com/miekg/dns/udp.go | 33 ++-
vendor/github.com/miekg/dns/version.go | 2 +-
vendor/github.com/miekg/dns/zcompress.go | 165 +++++++++------
vendor/github.com/miekg/dns/ztypes.go | 130 ++++++------
vendor/vendor.json | 2 +-
16 files changed, 560 insertions(+), 301 deletions(-)
diff --git a/vendor/github.com/miekg/dns/client.go b/vendor/github.com/miekg/dns/client.go
index 856b1698d..6aa4235d1 100644
--- a/vendor/github.com/miekg/dns/client.go
+++ b/vendor/github.com/miekg/dns/client.go
@@ -7,8 +7,12 @@ import (
"context"
"crypto/tls"
"encoding/binary"
+ "fmt"
"io"
+ "io/ioutil"
"net"
+ "net/http"
+ "net/url"
"strings"
"time"
)
@@ -16,13 +20,13 @@ import (
const dnsTimeout time.Duration = 2 * time.Second
const tcpIdleTimeout time.Duration = 8 * time.Second
+const dohMimeType = "application/dns-udpwireformat"
+
// A Conn represents a connection to a DNS server.
type Conn struct {
net.Conn // a net.Conn holding the connection
UDPSize uint16 // minimum receive buffer for UDP messages
TsigSecret map[string]string // secret(s) for Tsig map[], zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
- rtt time.Duration
- t time.Time
tsigRequestMAC string
}
@@ -39,6 +43,7 @@ type Client struct {
DialTimeout time.Duration // net.DialTimeout, defaults to 2 seconds, or net.Dialer.Timeout if expiring earlier - overridden by Timeout when that value is non-zero
ReadTimeout time.Duration // net.Conn.SetReadTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
WriteTimeout time.Duration // net.Conn.SetWriteTimeout value for connections, defaults to 2 seconds - overridden by Timeout when that value is non-zero
+ HTTPClient *http.Client // The http.Client to use for DNS-over-HTTPS
TsigSecret map[string]string // secret(s) for Tsig map[], zonename must be in canonical form (lowercase, fqdn, see RFC 4034 Section 6.2)
SingleInflight bool // if true suppress multiple outstanding queries for the same Qname, Qtype and Qclass
group singleflight
@@ -136,6 +141,11 @@ func (c *Client) Dial(address string) (conn *Conn, err error) {
// attribute appropriately
func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, err error) {
if !c.SingleInflight {
+ if c.Net == "https" {
+ // TODO(tmthrgd): pipe timeouts into exchangeDOH
+ return c.exchangeDOH(context.TODO(), m, address)
+ }
+
return c.exchange(m, address)
}
@@ -148,6 +158,11 @@ func (c *Client) Exchange(m *Msg, address string) (r *Msg, rtt time.Duration, er
cl = cl1
}
r, rtt, err, shared := c.group.Do(m.Question[0].Name+t+cl, func() (*Msg, time.Duration, error) {
+ if c.Net == "https" {
+ // TODO(tmthrgd): pipe timeouts into exchangeDOH
+ return c.exchangeDOH(context.TODO(), m, address)
+ }
+
return c.exchange(m, address)
})
if r != nil && shared {
@@ -177,8 +192,9 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
}
co.TsigSecret = c.TsigSecret
+ t := time.Now()
// write with the appropriate write timeout
- co.SetWriteDeadline(time.Now().Add(c.getTimeoutForRequest(c.writeTimeout())))
+ co.SetWriteDeadline(t.Add(c.getTimeoutForRequest(c.writeTimeout())))
if err = co.WriteMsg(m); err != nil {
return nil, 0, err
}
@@ -188,7 +204,79 @@ func (c *Client) exchange(m *Msg, a string) (r *Msg, rtt time.Duration, err erro
if err == nil && r.Id != m.Id {
err = ErrId
}
- return r, co.rtt, err
+ rtt = time.Since(t)
+ return r, rtt, err
+}
+
+func (c *Client) exchangeDOH(ctx context.Context, m *Msg, a string) (r *Msg, rtt time.Duration, err error) {
+ p, err := m.Pack()
+ if err != nil {
+ return nil, 0, err
+ }
+
+ // TODO(tmthrgd): Allow the path to be customised?
+ u := &url.URL{
+ Scheme: "https",
+ Host: a,
+ Path: "/.well-known/dns-query",
+ }
+ if u.Port() == "443" {
+ u.Host = u.Hostname()
+ }
+
+ req, err := http.NewRequest(http.MethodPost, u.String(), bytes.NewReader(p))
+ if err != nil {
+ return nil, 0, err
+ }
+
+ req.Header.Set("Content-Type", dohMimeType)
+ req.Header.Set("Accept", dohMimeType)
+
+ t := time.Now()
+
+ hc := http.DefaultClient
+ if c.HTTPClient != nil {
+ hc = c.HTTPClient
+ }
+
+ if ctx != context.Background() && ctx != context.TODO() {
+ req = req.WithContext(ctx)
+ }
+
+ resp, err := hc.Do(req)
+ if err != nil {
+ return nil, 0, err
+ }
+ defer closeHTTPBody(resp.Body)
+
+ if resp.StatusCode != http.StatusOK {
+ return nil, 0, fmt.Errorf("dns: server returned HTTP %d error: %q", resp.StatusCode, resp.Status)
+ }
+
+ if ct := resp.Header.Get("Content-Type"); ct != dohMimeType {
+ return nil, 0, fmt.Errorf("dns: unexpected Content-Type %q; expected %q", ct, dohMimeType)
+ }
+
+ p, err = ioutil.ReadAll(resp.Body)
+ if err != nil {
+ return nil, 0, err
+ }
+
+ rtt = time.Since(t)
+
+ r = new(Msg)
+ if err := r.Unpack(p); err != nil {
+ return r, 0, err
+ }
+
+ // TODO: TSIG? Is it even supported over DoH?
+
+ return r, rtt, nil
+}
+
+func closeHTTPBody(r io.ReadCloser) error {
+ io.Copy(ioutil.Discard, io.LimitReader(r, 8<<20))
+ return r.Close()
}
// ReadMsg reads a message from the connection co.
@@ -240,7 +328,6 @@ func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) {
}
p = make([]byte, l)
n, err = tcpRead(r, p)
- co.rtt = time.Since(co.t)
default:
if co.UDPSize > MinMsgSize {
p = make([]byte, co.UDPSize)
@@ -248,7 +335,6 @@ func (co *Conn) ReadMsgHeader(hdr *Header) ([]byte, error) {
p = make([]byte, MinMsgSize)
}
n, err = co.Read(p)
- co.rtt = time.Since(co.t)
}
if err != nil {
@@ -361,7 +447,6 @@ func (co *Conn) WriteMsg(m *Msg) (err error) {
if err != nil {
return err
}
- co.t = time.Now()
if _, err = co.Write(out); err != nil {
return err
}
@@ -493,6 +578,10 @@ func DialTimeoutWithTLS(network, address string, tlsConfig *tls.Config, timeout
// 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 && c.Net == "https" {
+ return c.exchangeDOH(ctx, m, a)
+ }
+
var timeout time.Duration
if deadline, ok := ctx.Deadline(); !ok {
timeout = 0
@@ -501,6 +590,7 @@ func (c *Client) ExchangeContext(ctx context.Context, m *Msg, a string) (r *Msg,
}
// not passing the context to the underlying calls, as the API does not support
// context. For timeouts you should set up Client.Dialer and call Client.Exchange.
+ // TODO(tmthrgd): this is a race condition
c.Dialer = &net.Dialer{Timeout: timeout}
return c.Exchange(m, a)
}
diff --git a/vendor/github.com/miekg/dns/clientconfig.go b/vendor/github.com/miekg/dns/clientconfig.go
index a606ef696..f13cfa30c 100644
--- a/vendor/github.com/miekg/dns/clientconfig.go
+++ b/vendor/github.com/miekg/dns/clientconfig.go
@@ -91,7 +91,7 @@ func ClientConfigFromReader(resolvconf io.Reader) (*ClientConfig, error) {
n = 1
}
c.Timeout = n
- case len(s) >= 8 && s[:9] == "attempts:":
+ case len(s) >= 9 && s[:9] == "attempts:":
n, _ := strconv.Atoi(s[9:])
if n < 1 {
n = 1
diff --git a/vendor/github.com/miekg/dns/compress_generate.go b/vendor/github.com/miekg/dns/compress_generate.go
index 87fb36f68..9a136c414 100644
--- a/vendor/github.com/miekg/dns/compress_generate.go
+++ b/vendor/github.com/miekg/dns/compress_generate.go
@@ -101,7 +101,8 @@ Names:
// 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, "func compressionLenHelperType(c map[string]int, r RR, initLen int) int {\n")
+ fmt.Fprint(b, "currentLen := initLen\n")
fmt.Fprint(b, "switch x := r.(type) {\n")
for _, name := range domainTypes {
o := scope.Lookup(name)
@@ -109,7 +110,10 @@ Names:
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()) }
+ out := func(s string) {
+ fmt.Fprintf(b, "currentLen -= len(x.%s) + 1\n", st.Field(i).Name())
+ fmt.Fprintf(b, "currentLen += compressionLenHelper(c, x.%s, currentLen)\n", st.Field(i).Name())
+ }
if _, ok := st.Field(i).Type().(*types.Slice); ok {
switch st.Tag(i) {
@@ -118,8 +122,12 @@ Names:
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])
- }
+ currentLen -= len(x.%s[i]) + 1
+}
+`, st.Field(i).Name(), st.Field(i).Name())
+ fmt.Fprintf(b, `for i := range x.%s {
+ currentLen += compressionLenHelper(c, x.%s[i], currentLen)
+}
`, st.Field(i).Name(), st.Field(i).Name())
}
continue
@@ -133,11 +141,11 @@ Names:
}
}
}
- fmt.Fprintln(b, "}\n}\n\n")
+ fmt.Fprintln(b, "}\nreturn currentLen - initLen\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, "func compressionLenSearchType(c map[string]int, r RR) (int, bool, int) {\n")
fmt.Fprint(b, "switch x := r.(type) {\n")
for _, name := range cdomainTypes {
o := scope.Lookup(name)
@@ -147,7 +155,7 @@ Names:
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())
+ fmt.Fprintf(b, "k%d, ok%d, sz%d := compressionLenSearch(c, x.%s)\n", j, j, j, st.Field(i).Name())
}
// There are no slice types with names that can be compressed.
@@ -160,13 +168,15 @@ Names:
}
k := "k1"
ok := "ok1"
+ sz := "sz1"
for i := 2; i < j; i++ {
k += fmt.Sprintf(" + k%d", i)
ok += fmt.Sprintf(" && ok%d", i)
+ sz += fmt.Sprintf(" + sz%d", i)
}
- fmt.Fprintf(b, "return %s, %s\n", k, ok)
+ fmt.Fprintf(b, "return %s, %s, %s\n", k, ok, sz)
}
- fmt.Fprintln(b, "}\nreturn 0, false\n}\n\n")
+ fmt.Fprintln(b, "}\nreturn 0, false, 0\n}\n\n")
// gofmt
res, err := format.Source(b.Bytes())
diff --git a/vendor/github.com/miekg/dns/dns.go b/vendor/github.com/miekg/dns/dns.go
index 5133eac72..e7557f51a 100644
--- a/vendor/github.com/miekg/dns/dns.go
+++ b/vendor/github.com/miekg/dns/dns.go
@@ -55,16 +55,6 @@ func (h *RR_Header) Header() *RR_Header { return h }
// Just to implement the RR interface.
func (h *RR_Header) copy() RR { return nil }
-func (h *RR_Header) copyHeader() *RR_Header {
- r := new(RR_Header)
- r.Name = h.Name
- r.Rrtype = h.Rrtype
- r.Class = h.Class
- r.Ttl = h.Ttl
- r.Rdlength = h.Rdlength
- return r
-}
-
func (h *RR_Header) String() string {
var s string
diff --git a/vendor/github.com/miekg/dns/dnssec.go b/vendor/github.com/miekg/dns/dnssec.go
index ac9fdd45e..478cb1e90 100644
--- a/vendor/github.com/miekg/dns/dnssec.go
+++ b/vendor/github.com/miekg/dns/dnssec.go
@@ -73,6 +73,7 @@ var StringToAlgorithm = reverseInt8(AlgorithmToString)
// AlgorithmToHash is a map of algorithm crypto hash IDs to crypto.Hash's.
var AlgorithmToHash = map[uint8]crypto.Hash{
RSAMD5: crypto.MD5, // Deprecated in RFC 6725
+ DSA: crypto.SHA1,
RSASHA1: crypto.SHA1,
RSASHA1NSEC3SHA1: crypto.SHA1,
RSASHA256: crypto.SHA256,
@@ -239,7 +240,7 @@ func (k *DNSKEY) ToDS(h uint8) *DS {
// ToCDNSKEY converts a DNSKEY record to a CDNSKEY record.
func (k *DNSKEY) ToCDNSKEY() *CDNSKEY {
c := &CDNSKEY{DNSKEY: *k}
- c.Hdr = *k.Hdr.copyHeader()
+ c.Hdr = k.Hdr
c.Hdr.Rrtype = TypeCDNSKEY
return c
}
@@ -247,7 +248,7 @@ func (k *DNSKEY) ToCDNSKEY() *CDNSKEY {
// ToCDS converts a DS record to a CDS record.
func (d *DS) ToCDS() *CDS {
c := &CDS{DS: *d}
- c.Hdr = *d.Hdr.copyHeader()
+ c.Hdr = d.Hdr
c.Hdr.Rrtype = TypeCDS
return c
}
diff --git a/vendor/github.com/miekg/dns/doc.go b/vendor/github.com/miekg/dns/doc.go
index 1d8114744..0389d7248 100644
--- a/vendor/github.com/miekg/dns/doc.go
+++ b/vendor/github.com/miekg/dns/doc.go
@@ -73,11 +73,11 @@ and port to use for the connection:
Port: 12345,
Zone: "",
}
- d := net.Dialer{
+ c.Dialer := &net.Dialer{
Timeout: 200 * time.Millisecond,
LocalAddr: &laddr,
}
- in, rtt, err := c.ExchangeWithDialer(&d, m1, "8.8.8.8:53")
+ in, rtt, err := c.Exchange(m1, "8.8.8.8:53")
If these "advanced" features are not needed, a simple UDP query can be sent,
with:
diff --git a/vendor/github.com/miekg/dns/msg.go b/vendor/github.com/miekg/dns/msg.go
index 975dde781..dcd3b6a5e 100644
--- a/vendor/github.com/miekg/dns/msg.go
+++ b/vendor/github.com/miekg/dns/msg.go
@@ -595,6 +595,13 @@ func UnpackRR(msg []byte, off int) (rr RR, off1 int, err error) {
if err != nil {
return nil, len(msg), err
}
+
+ return UnpackRRWithHeader(h, msg, off)
+}
+
+// UnpackRRWithHeader unpacks the record type specific payload given an existing
+// RR_Header.
+func UnpackRRWithHeader(h RR_Header, msg []byte, off int) (rr RR, off1 int, err error) {
end := off + int(h.Rdlength)
if fn, known := typeToUnpack[h.Rrtype]; !known {
@@ -684,18 +691,20 @@ func (dns *Msg) Pack() (msg []byte, err error) {
return dns.PackBuffer(nil)
}
-// PackBuffer packs a Msg, using the given buffer buf. If buf is too small
-// a new buffer is allocated.
+// PackBuffer packs a Msg, using the given buffer buf. If buf is too small a new buffer is allocated.
func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
- // We use a similar function in tsig.go's stripTsig.
- var (
- dh Header
- compression map[string]int
- )
-
+ var compression map[string]int
if dns.Compress {
- compression = make(map[string]int) // Compression pointer mappings
+ compression = make(map[string]int) // Compression pointer mappings.
}
+ return dns.packBufferWithCompressionMap(buf, compression)
+}
+
+// packBufferWithCompressionMap packs a Msg, using the given buffer buf.
+func (dns *Msg) packBufferWithCompressionMap(buf []byte, compression map[string]int) (msg []byte, err error) {
+ // We use a similar function in tsig.go's stripTsig.
+
+ var dh Header
if dns.Rcode < 0 || dns.Rcode > 0xFFF {
return nil, ErrRcode
@@ -707,12 +716,11 @@ func (dns *Msg) PackBuffer(buf []byte) (msg []byte, err error) {
return nil, ErrExtendedRcode
}
opt.SetExtendedRcode(uint8(dns.Rcode >> 4))
- dns.Rcode &= 0xF
}
// Convert convenient Msg into wire-like Header.
dh.Id = dns.Id
- dh.Bits = uint16(dns.Opcode)<<11 | uint16(dns.Rcode)
+ dh.Bits = uint16(dns.Opcode)<<11 | uint16(dns.Rcode&0xF)
if dns.Response {
dh.Bits |= _QR
}
@@ -915,94 +923,138 @@ func (dns *Msg) String() string {
// than packing it, measuring the size and discarding the buffer.
func (dns *Msg) Len() int { return compressedLen(dns, dns.Compress) }
+func compressedLenWithCompressionMap(dns *Msg, compression map[string]int) int {
+ l := 12 // Message header is always 12 bytes
+ for _, r := range dns.Question {
+ compressionLenHelper(compression, r.Name, l)
+ l += r.len()
+ }
+ l += compressionLenSlice(l, compression, dns.Answer)
+ l += compressionLenSlice(l, compression, dns.Ns)
+ l += compressionLenSlice(l, compression, dns.Extra)
+ return l
+}
+
// compressedLen returns the message length when in compressed wire format
// when compress is true, otherwise the uncompressed length is returned.
func compressedLen(dns *Msg, compress bool) int {
// We always return one more than needed.
- l := 12 // Message header is always 12 bytes
if compress {
compression := map[string]int{}
- for _, r := range dns.Question {
+ return compressedLenWithCompressionMap(dns, compression)
+ }
+ l := 12 // Message header is always 12 bytes
+
+ for _, r := range dns.Question {
+ l += r.len()
+ }
+ for _, r := range dns.Answer {
+ if r != nil {
l += r.len()
- compressionLenHelper(compression, r.Name)
- }
- l += compressionLenSlice(compression, dns.Answer)
- l += compressionLenSlice(compression, dns.Ns)
- l += compressionLenSlice(compression, dns.Extra)
- } else {
- for _, r := range dns.Question {
- l += r.len()
- }
- for _, r := range dns.Answer {
- if r != nil {
- l += r.len()
- }
- }
- for _, r := range dns.Ns {
- if r != nil {
- l += r.len()
- }
- }
- for _, r := range dns.Extra {
- if r != nil {
- l += r.len()
- }
}
}
+ for _, r := range dns.Ns {
+ if r != nil {
+ l += r.len()
+ }
+ }
+ for _, r := range dns.Extra {
+ if r != nil {
+ l += r.len()
+ }
+ }
+
return l
}
-func compressionLenSlice(c map[string]int, rs []RR) int {
- var l int
+func compressionLenSlice(lenp int, c map[string]int, rs []RR) int {
+ initLen := lenp
for _, r := range rs {
if r == nil {
continue
}
- l += r.len()
- k, ok := compressionLenSearch(c, r.Header().Name)
+ // TmpLen is to track len of record at 14bits boudaries
+ tmpLen := lenp
+
+ x := r.len()
+ // track this length, and the global length in len, while taking compression into account for both.
+ k, ok, _ := compressionLenSearch(c, r.Header().Name)
if ok {
- l += 1 - k
+ // Size of x is reduced by k, but we add 1 since k includes the '.' and label descriptor take 2 bytes
+ // so, basically x:= x - k - 1 + 2
+ x += 1 - k
}
- compressionLenHelper(c, r.Header().Name)
- k, ok = compressionLenSearchType(c, r)
+
+ tmpLen += compressionLenHelper(c, r.Header().Name, tmpLen)
+ k, ok, _ = compressionLenSearchType(c, r)
if ok {
- l += 1 - k
+ x += 1 - k
}
- compressionLenHelperType(c, r)
+ lenp += x
+ tmpLen = lenp
+ tmpLen += compressionLenHelperType(c, r, tmpLen)
+
}
- return l
+ return lenp - initLen
}
-// Put the parts of the name in the compression map.
-func compressionLenHelper(c map[string]int, s string) {
+// Put the parts of the name in the compression map, return the size in bytes added in payload
+func compressionLenHelper(c map[string]int, s string, currentLen int) int {
+ if currentLen > maxCompressionOffset {
+ // We won't be able to add any label that could be re-used later anyway
+ return 0
+ }
+ if _, ok := c[s]; ok {
+ return 0
+ }
+ initLen := currentLen
pref := ""
+ prev := s
lbs := Split(s)
- for j := len(lbs) - 1; j >= 0; j-- {
+ for j := 0; j < len(lbs); j++ {
pref = s[lbs[j]:]
+ currentLen += len(prev) - len(pref)
+ prev = pref
if _, ok := c[pref]; !ok {
- c[pref] = len(pref)
+ // If first byte label is within the first 14bits, it might be re-used later
+ if currentLen < maxCompressionOffset {
+ c[pref] = currentLen
+ }
+ } else {
+ added := currentLen - initLen
+ if j > 0 {
+ // We added a new PTR
+ added += 2
+ }
+ return added
}
}
+ return currentLen - initLen
}
// Look for each part in the compression map and returns its length,
// keep on searching so we get the longest match.
-func compressionLenSearch(c map[string]int, s string) (int, bool) {
+// Will return the size of compression found, whether a match has been
+// found and the size of record if added in payload
+func compressionLenSearch(c map[string]int, s string) (int, bool, int) {
off := 0
end := false
if s == "" { // don't bork on bogus data
- return 0, false
+ return 0, false, 0
}
+ fullSize := 0
for {
if _, ok := c[s[off:]]; ok {
- return len(s[off:]), true
+ return len(s[off:]), true, fullSize + off
}
if end {
break
}
+ // Each label descriptor takes 2 bytes, add it
+ fullSize += 2
off, end = NextLabel(s, off)
}
- return 0, false
+ return 0, false, fullSize + len(s)
}
// Copy returns a new RR which is a deep-copy of r.
diff --git a/vendor/github.com/miekg/dns/privaterr.go b/vendor/github.com/miekg/dns/privaterr.go
index 6b08e6e95..41989e7ae 100644
--- a/vendor/github.com/miekg/dns/privaterr.go
+++ b/vendor/github.com/miekg/dns/privaterr.go
@@ -56,8 +56,7 @@ func (r *PrivateRR) len() int { return r.Hdr.len() + r.Data.Len() }
func (r *PrivateRR) copy() RR {
// make new RR like this:
rr := mkPrivateRR(r.Hdr.Rrtype)
- newh := r.Hdr.copyHeader()
- rr.Hdr = *newh
+ rr.Hdr = r.Hdr
err := r.Data.Copy(rr.Data)
if err != nil {
diff --git a/vendor/github.com/miekg/dns/scan_rr.go b/vendor/github.com/miekg/dns/scan_rr.go
index f4ccc8424..fb6f95d1d 100644
--- a/vendor/github.com/miekg/dns/scan_rr.go
+++ b/vendor/github.com/miekg/dns/scan_rr.go
@@ -1255,8 +1255,10 @@ func setNSEC3(h RR_Header, c chan lex, o, f string) (RR, *ParseError, string) {
if len(l.token) == 0 || l.err {
return nil, &ParseError{f, "bad NSEC3 Salt", l}, ""
}
- rr.SaltLength = uint8(len(l.token)) / 2
- rr.Salt = l.token
+ if l.token != "-" {
+ rr.SaltLength = uint8(len(l.token)) / 2
+ rr.Salt = l.token
+ }
<-c
l = <-c
@@ -1321,8 +1323,10 @@ func setNSEC3PARAM(h RR_Header, c chan lex, o, f string) (RR, *ParseError, strin
rr.Iterations = uint16(i)
<-c
l = <-c
- rr.SaltLength = uint8(len(l.token))
- rr.Salt = l.token
+ if l.token != "-" {
+ rr.SaltLength = uint8(len(l.token))
+ rr.Salt = l.token
+ }
return rr, nil, ""
}
diff --git a/vendor/github.com/miekg/dns/server.go b/vendor/github.com/miekg/dns/server.go
index 685753f43..2d98f1488 100644
--- a/vendor/github.com/miekg/dns/server.go
+++ b/vendor/github.com/miekg/dns/server.go
@@ -9,12 +9,19 @@ import (
"io"
"net"
"sync"
+ "sync/atomic"
"time"
)
-// Maximum number of TCP queries before we close the socket.
+// Default maximum number of TCP queries before we close the socket.
const maxTCPQueries = 128
+// Interval for stop worker if no load
+const idleWorkerTimeout = 10 * time.Second
+
+// Maximum number of workers
+const maxWorkersCount = 10000
+
// Handler is implemented by any value that implements ServeDNS.
type Handler interface {
ServeDNS(w ResponseWriter, r *Msg)
@@ -43,6 +50,7 @@ type ResponseWriter interface {
}
type response struct {
+ msg []byte
hijacked bool // connection has been hijacked by handler
tsigStatus error
tsigTimersOnly bool
@@ -51,7 +59,6 @@ type response struct {
udp *net.UDPConn // i/o connection if UDP was used
tcp net.Conn // i/o connection if TCP was used
udpSession *SessionUDP // oob data to get egress interface right
- remoteAddr net.Addr // address of the client
writer Writer // writer to output the raw DNS bits
}
@@ -296,12 +303,63 @@ type Server struct {
DecorateReader DecorateReader
// DecorateWriter is optional, allows customization of the process that writes raw DNS messages.
DecorateWriter DecorateWriter
+ // Maximum number of TCP queries before we close the socket. Default is maxTCPQueries (unlimited if -1).
+ MaxTCPQueries int
+ // UDP packet or TCP connection queue
+ queue chan *response
+ // Workers count
+ workersCount int32
// Shutdown handling
lock sync.RWMutex
started bool
}
+func (srv *Server) worker(w *response) {
+ srv.serve(w)
+
+ for {
+ count := atomic.LoadInt32(&srv.workersCount)
+ if count > maxWorkersCount {
+ return
+ }
+ if atomic.CompareAndSwapInt32(&srv.workersCount, count, count+1) {
+ break
+ }
+ }
+
+ defer atomic.AddInt32(&srv.workersCount, -1)
+
+ inUse := false
+ timeout := time.NewTimer(idleWorkerTimeout)
+ defer timeout.Stop()
+LOOP:
+ for {
+ select {
+ case w, ok := <-srv.queue:
+ if !ok {
+ break LOOP
+ }
+ inUse = true
+ srv.serve(w)
+ case <-timeout.C:
+ if !inUse {
+ break LOOP
+ }
+ inUse = false
+ timeout.Reset(idleWorkerTimeout)
+ }
+ }
+}
+
+func (srv *Server) spawnWorker(w *response) {
+ select {
+ case srv.queue <- w:
+ default:
+ go srv.worker(w)
+ }
+}
+
// ListenAndServe starts a nameserver on the configured address in *Server.
func (srv *Server) ListenAndServe() error {
srv.lock.Lock()
@@ -309,6 +367,7 @@ func (srv *Server) ListenAndServe() error {
if srv.started {
return &Error{err: "server already started"}
}
+
addr := srv.Addr
if addr == "" {
addr = ":domain"
@@ -316,6 +375,8 @@ func (srv *Server) ListenAndServe() error {
if srv.UDPSize == 0 {
srv.UDPSize = MinMsgSize
}
+ srv.queue = make(chan *response)
+ defer close(srv.queue)
switch srv.Net {
case "tcp", "tcp4", "tcp6":
a, err := net.ResolveTCPAddr(srv.Net, addr)
@@ -380,8 +441,11 @@ func (srv *Server) ActivateAndServe() error {
if srv.started {
return &Error{err: "server already started"}
}
+
pConn := srv.PacketConn
l := srv.Listener
+ srv.queue = make(chan *response)
+ defer close(srv.queue)
if pConn != nil {
if srv.UDPSize == 0 {
srv.UDPSize = MinMsgSize
@@ -439,7 +503,6 @@ func (srv *Server) getReadTimeout() time.Duration {
}
// serveTCP starts a TCP listener for the server.
-// Each request is handled in a separate goroutine.
func (srv *Server) serveTCP(l net.Listener) error {
defer l.Close()
@@ -447,17 +510,6 @@ func (srv *Server) serveTCP(l net.Listener) error {
srv.NotifyStartedFunc()
}
- reader := Reader(&defaultReader{srv})
- if srv.DecorateReader != nil {
- reader = srv.DecorateReader(reader)
- }
-
- handler := srv.Handler
- if handler == nil {
- handler = DefaultServeMux
- }
- rtimeout := srv.getReadTimeout()
- // deadline is not used here
for {
rw, err := l.Accept()
srv.lock.RLock()
@@ -472,19 +524,11 @@ func (srv *Server) serveTCP(l net.Listener) error {
}
return err
}
- go func() {
- m, err := reader.ReadTCP(rw, rtimeout)
- if err != nil {
- rw.Close()
- return
- }
- srv.serve(rw.RemoteAddr(), handler, m, nil, nil, rw)
- }()
+ srv.spawnWorker(&response{tsigSecret: srv.TsigSecret, tcp: rw})
}
}
// serveUDP starts a UDP listener for the server.
-// Each request is handled in a separate goroutine.
func (srv *Server) serveUDP(l *net.UDPConn) error {
defer l.Close()
@@ -497,10 +541,6 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
reader = srv.DecorateReader(reader)
}
- handler := srv.Handler
- if handler == nil {
- handler = DefaultServeMux
- }
rtimeout := srv.getReadTimeout()
// deadline is not used here
for {
@@ -520,80 +560,98 @@ func (srv *Server) serveUDP(l *net.UDPConn) error {
if len(m) < headerSize {
continue
}
- go srv.serve(s.RemoteAddr(), handler, m, l, s, nil)
+ srv.spawnWorker(&response{msg: m, tsigSecret: srv.TsigSecret, udp: l, udpSession: s})
}
}
-// Serve a new connection.
-func (srv *Server) serve(a net.Addr, h Handler, m []byte, u *net.UDPConn, s *SessionUDP, t net.Conn) {
- w := &response{tsigSecret: srv.TsigSecret, udp: u, tcp: t, remoteAddr: a, udpSession: s}
+func (srv *Server) serve(w *response) {
if srv.DecorateWriter != nil {
w.writer = srv.DecorateWriter(w)
} else {
w.writer = w
}
- q := 0 // counter for the amount of TCP queries we get
+ if w.udp != nil {
+ // serve UDP
+ srv.serveDNS(w)
+ return
+ }
reader := Reader(&defaultReader{srv})
if srv.DecorateReader != nil {
reader = srv.DecorateReader(reader)
}
-Redo:
+
+ defer func() {
+ if !w.hijacked {
+ w.Close()
+ }
+ }()
+
+ idleTimeout := tcpIdleTimeout
+ if srv.IdleTimeout != nil {
+ idleTimeout = srv.IdleTimeout()
+ }
+
+ timeout := srv.getReadTimeout()
+
+ limit := srv.MaxTCPQueries
+ if limit == 0 {
+ limit = maxTCPQueries
+ }
+
+ for q := 0; q < limit || limit == -1; q++ {
+ var err error
+ w.msg, err = reader.ReadTCP(w.tcp, timeout)
+ if err != nil {
+ // TODO(tmthrgd): handle error
+ break
+ }
+ srv.serveDNS(w)
+ if w.tcp == nil {
+ break // Close() was called
+ }
+ if w.hijacked {
+ break // client will call Close() themselves
+ }
+ // The first read uses the read timeout, the rest use the
+ // idle timeout.
+ timeout = idleTimeout
+ }
+}
+
+func (srv *Server) serveDNS(w *response) {
req := new(Msg)
- err := req.Unpack(m)
+ err := req.Unpack(w.msg)
if err != nil { // Send a FormatError back
x := new(Msg)
x.SetRcodeFormatError(req)
w.WriteMsg(x)
- goto Exit
+ return
}
if !srv.Unsafe && req.Response {
- goto Exit
+ return
}
w.tsigStatus = nil
if w.tsigSecret != nil {
if t := req.IsTsig(); t != nil {
- secret := t.Hdr.Name
- if _, ok := w.tsigSecret[secret]; !ok {
- w.tsigStatus = ErrKeyAlg
+ if secret, ok := w.tsigSecret[t.Hdr.Name]; ok {
+ w.tsigStatus = TsigVerify(w.msg, secret, "", false)
+ } else {
+ w.tsigStatus = ErrSecret
}
- w.tsigStatus = TsigVerify(m, w.tsigSecret[secret], "", false)
w.tsigTimersOnly = false
w.tsigRequestMAC = req.Extra[len(req.Extra)-1].(*TSIG).MAC
}
}
- h.ServeDNS(w, req) // Writes back to the client
-Exit:
- if w.tcp == nil {
- return
- }
- // TODO(miek): make this number configurable?
- if q > maxTCPQueries { // close socket after this many queries
- w.Close()
- return
+ handler := srv.Handler
+ if handler == nil {
+ handler = DefaultServeMux
}
- if w.hijacked {
- return // client calls Close()
- }
- if u != nil { // UDP, "close" and return
- w.Close()
- return
- }
- idleTimeout := tcpIdleTimeout
- if srv.IdleTimeout != nil {
- idleTimeout = srv.IdleTimeout()
- }
- m, err = reader.ReadTCP(w.tcp, idleTimeout)
- if err == nil {
- q++
- goto Redo
- }
- w.Close()
- return
+ handler.ServeDNS(w, req) // Writes back to the client
}
func (srv *Server) readTCP(conn net.Conn, timeout time.Duration) ([]byte, error) {
@@ -696,7 +754,12 @@ func (w *response) LocalAddr() net.Addr {
}
// RemoteAddr implements the ResponseWriter.RemoteAddr method.
-func (w *response) RemoteAddr() net.Addr { return w.remoteAddr }
+func (w *response) RemoteAddr() net.Addr {
+ if w.tcp != nil {
+ return w.tcp.RemoteAddr()
+ }
+ return w.udpSession.RemoteAddr()
+}
// TsigStatus implements the ResponseWriter.TsigStatus method.
func (w *response) TsigStatus() error { return w.tsigStatus }
diff --git a/vendor/github.com/miekg/dns/types_generate.go b/vendor/github.com/miekg/dns/types_generate.go
index 8703cce64..b8db4f361 100644
--- a/vendor/github.com/miekg/dns/types_generate.go
+++ b/vendor/github.com/miekg/dns/types_generate.go
@@ -226,7 +226,7 @@ func main() {
continue
}
fmt.Fprintf(b, "func (rr *%s) copy() RR {\n", name)
- fields := []string{"*rr.Hdr.copyHeader()"}
+ fields := []string{"rr.Hdr"}
for i := 1; i < st.NumFields(); i++ {
f := st.Field(i).Name()
if sl, ok := st.Field(i).Type().(*types.Slice); ok {
diff --git a/vendor/github.com/miekg/dns/udp.go b/vendor/github.com/miekg/dns/udp.go
index f3f31a7ac..a4826ee2f 100644
--- a/vendor/github.com/miekg/dns/udp.go
+++ b/vendor/github.com/miekg/dns/udp.go
@@ -9,6 +9,22 @@ import (
"golang.org/x/net/ipv6"
)
+// This is the required size of the OOB buffer to pass to ReadMsgUDP.
+var udpOOBSize = func() int {
+ // We can't know whether we'll get an IPv4 control message or an
+ // IPv6 control message ahead of time. To get around this, we size
+ // the buffer equal to the largest of the two.
+
+ oob4 := ipv4.NewControlMessage(ipv4.FlagDst | ipv4.FlagInterface)
+ oob6 := ipv6.NewControlMessage(ipv6.FlagDst | ipv6.FlagInterface)
+
+ if len(oob4) > len(oob6) {
+ return len(oob4)
+ }
+
+ return len(oob6)
+}()
+
// SessionUDP holds the remote address and the associated
// out-of-band data.
type SessionUDP struct {
@@ -22,7 +38,7 @@ 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)
+ oob := make([]byte, udpOOBSize)
n, oobn, _, raddr, err := conn.ReadMsgUDP(b, oob)
if err != nil {
return n, nil, err
@@ -53,18 +69,15 @@ func parseDstFromOOB(oob []byte) net.IP {
// Start with IPv6 and then fallback to IPv4
// TODO(fastest963): Figure out a way to prefer one or the other. Looking at
// the lvl of the header for a 0 or 41 isn't cross-platform.
- var dst net.IP
cm6 := new(ipv6.ControlMessage)
- if cm6.Parse(oob) == nil {
- dst = cm6.Dst
+ if cm6.Parse(oob) == nil && cm6.Dst != nil {
+ return cm6.Dst
}
- if dst == nil {
- cm4 := new(ipv4.ControlMessage)
- if cm4.Parse(oob) == nil {
- dst = cm4.Dst
- }
+ cm4 := new(ipv4.ControlMessage)
+ if cm4.Parse(oob) == nil && cm4.Dst != nil {
+ return cm4.Dst
}
- return dst
+ return nil
}
// correctSource takes oob data and returns new oob data with the Src equal to the Dst
diff --git a/vendor/github.com/miekg/dns/version.go b/vendor/github.com/miekg/dns/version.go
index e41d2b3ca..4f173d9d2 100644
--- a/vendor/github.com/miekg/dns/version.go
+++ b/vendor/github.com/miekg/dns/version.go
@@ -3,7 +3,7 @@ package dns
import "fmt"
// Version is current version of this library.
-var Version = V{1, 0, 4}
+var Version = V{1, 0, 7}
// V holds the version of this library.
type V struct {
diff --git a/vendor/github.com/miekg/dns/zcompress.go b/vendor/github.com/miekg/dns/zcompress.go
index c2503204d..a2c09dd48 100644
--- a/vendor/github.com/miekg/dns/zcompress.go
+++ b/vendor/github.com/miekg/dns/zcompress.go
@@ -2,117 +2,154 @@
package dns
-func compressionLenHelperType(c map[string]int, r RR) {
+func compressionLenHelperType(c map[string]int, r RR, initLen int) int {
+ currentLen := initLen
switch x := r.(type) {
case *AFSDB:
- compressionLenHelper(c, x.Hostname)
+ currentLen -= len(x.Hostname) + 1
+ currentLen += compressionLenHelper(c, x.Hostname, currentLen)
case *CNAME:
- compressionLenHelper(c, x.Target)
+ currentLen -= len(x.Target) + 1
+ currentLen += compressionLenHelper(c, x.Target, currentLen)
case *DNAME:
- compressionLenHelper(c, x.Target)
+ currentLen -= len(x.Target) + 1
+ currentLen += compressionLenHelper(c, x.Target, currentLen)
case *HIP:
for i := range x.RendezvousServers {
- compressionLenHelper(c, x.RendezvousServers[i])
+ currentLen -= len(x.RendezvousServers[i]) + 1
+ }
+ for i := range x.RendezvousServers {
+ currentLen += compressionLenHelper(c, x.RendezvousServers[i], currentLen)
}
case *KX:
- compressionLenHelper(c, x.Exchanger)
+ currentLen -= len(x.Exchanger) + 1
+ currentLen += compressionLenHelper(c, x.Exchanger, currentLen)
case *LP:
- compressionLenHelper(c, x.Fqdn)
+ currentLen -= len(x.Fqdn) + 1
+ currentLen += compressionLenHelper(c, x.Fqdn, currentLen)
case *MB:
- compressionLenHelper(c, x.Mb)
+ currentLen -= len(x.Mb) + 1
+ currentLen += compressionLenHelper(c, x.Mb, currentLen)
case *MD:
- compressionLenHelper(c, x.Md)
+ currentLen -= len(x.Md) + 1
+ currentLen += compressionLenHelper(c, x.Md, currentLen)
case *MF:
- compressionLenHelper(c, x.Mf)
+ currentLen -= len(x.Mf) + 1
+ currentLen += compressionLenHelper(c, x.Mf, currentLen)
case *MG:
- compressionLenHelper(c, x.Mg)
+ currentLen -= len(x.Mg) + 1
+ currentLen += compressionLenHelper(c, x.Mg, currentLen)
case *MINFO:
- compressionLenHelper(c, x.Rmail)
- compressionLenHelper(c, x.Email)
+ currentLen -= len(x.Rmail) + 1
+ currentLen += compressionLenHelper(c, x.Rmail, currentLen)
+ currentLen -= len(x.Email) + 1
+ currentLen += compressionLenHelper(c, x.Email, currentLen)
case *MR:
- compressionLenHelper(c, x.Mr)
+ currentLen -= len(x.Mr) + 1
+ currentLen += compressionLenHelper(c, x.Mr, currentLen)
case *MX:
- compressionLenHelper(c, x.Mx)
+ currentLen -= len(x.Mx) + 1
+ currentLen += compressionLenHelper(c, x.Mx, currentLen)
case *NAPTR:
- compressionLenHelper(c, x.Replacement)
+ currentLen -= len(x.Replacement) + 1
+ currentLen += compressionLenHelper(c, x.Replacement, currentLen)
case *NS:
- compressionLenHelper(c, x.Ns)
+ currentLen -= len(x.Ns) + 1
+ currentLen += compressionLenHelper(c, x.Ns, currentLen)
case *NSAPPTR:
- compressionLenHelper(c, x.Ptr)
+ currentLen -= len(x.Ptr) + 1
+ currentLen += compressionLenHelper(c, x.Ptr, currentLen)
case *NSEC:
- compressionLenHelper(c, x.NextDomain)
+ currentLen -= len(x.NextDomain) + 1
+ currentLen += compressionLenHelper(c, x.NextDomain, currentLen)
case *PTR:
- compressionLenHelper(c, x.Ptr)
+ currentLen -= len(x.Ptr) + 1
+ currentLen += compressionLenHelper(c, x.Ptr, currentLen)
case *PX:
- compressionLenHelper(c, x.Map822)
- compressionLenHelper(c, x.Mapx400)
+ currentLen -= len(x.Map822) + 1
+ currentLen += compressionLenHelper(c, x.Map822, currentLen)
+ currentLen -= len(x.Mapx400) + 1
+ currentLen += compressionLenHelper(c, x.Mapx400, currentLen)
case *RP:
- compressionLenHelper(c, x.Mbox)
- compressionLenHelper(c, x.Txt)
+ currentLen -= len(x.Mbox) + 1
+ currentLen += compressionLenHelper(c, x.Mbox, currentLen)
+ currentLen -= len(x.Txt) + 1
+ currentLen += compressionLenHelper(c, x.Txt, currentLen)
case *RRSIG:
- compressionLenHelper(c, x.SignerName)
+ currentLen -= len(x.SignerName) + 1
+ currentLen += compressionLenHelper(c, x.SignerName, currentLen)
case *RT:
- compressionLenHelper(c, x.Host)
+ currentLen -= len(x.Host) + 1
+ currentLen += compressionLenHelper(c, x.Host, currentLen)
case *SIG:
- compressionLenHelper(c, x.SignerName)
+ currentLen -= len(x.SignerName) + 1
+ currentLen += compressionLenHelper(c, x.SignerName, currentLen)
case *SOA:
- compressionLenHelper(c, x.Ns)
- compressionLenHelper(c, x.Mbox)
+ currentLen -= len(x.Ns) + 1
+ currentLen += compressionLenHelper(c, x.Ns, currentLen)
+ currentLen -= len(x.Mbox) + 1
+ currentLen += compressionLenHelper(c, x.Mbox, currentLen)
case *SRV:
- compressionLenHelper(c, x.Target)
+ currentLen -= len(x.Target) + 1
+ currentLen += compressionLenHelper(c, x.Target, currentLen)
case *TALINK:
- compressionLenHelper(c, x.PreviousName)
- compressionLenHelper(c, x.NextName)
+ currentLen -= len(x.PreviousName) + 1
+ currentLen += compressionLenHelper(c, x.PreviousName, currentLen)
+ currentLen -= len(x.NextName) + 1
+ currentLen += compressionLenHelper(c, x.NextName, currentLen)
case *TKEY:
- compressionLenHelper(c, x.Algorithm)
+ currentLen -= len(x.Algorithm) + 1
+ currentLen += compressionLenHelper(c, x.Algorithm, currentLen)
case *TSIG:
- compressionLenHelper(c, x.Algorithm)
+ currentLen -= len(x.Algorithm) + 1
+ currentLen += compressionLenHelper(c, x.Algorithm, currentLen)
}
+ return currentLen - initLen
}
-func compressionLenSearchType(c map[string]int, r RR) (int, bool) {
+func compressionLenSearchType(c map[string]int, r RR) (int, bool, int) {
switch x := r.(type) {
case *AFSDB:
- k1, ok1 := compressionLenSearch(c, x.Hostname)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Hostname)
+ return k1, ok1, sz1
case *CNAME:
- k1, ok1 := compressionLenSearch(c, x.Target)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Target)
+ return k1, ok1, sz1
case *MB:
- k1, ok1 := compressionLenSearch(c, x.Mb)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Mb)
+ return k1, ok1, sz1
case *MD:
- k1, ok1 := compressionLenSearch(c, x.Md)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Md)
+ return k1, ok1, sz1
case *MF:
- k1, ok1 := compressionLenSearch(c, x.Mf)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Mf)
+ return k1, ok1, sz1
case *MG:
- k1, ok1 := compressionLenSearch(c, x.Mg)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Mg)
+ return k1, ok1, sz1
case *MINFO:
- k1, ok1 := compressionLenSearch(c, x.Rmail)
- k2, ok2 := compressionLenSearch(c, x.Email)
- return k1 + k2, ok1 && ok2
+ k1, ok1, sz1 := compressionLenSearch(c, x.Rmail)
+ k2, ok2, sz2 := compressionLenSearch(c, x.Email)
+ return k1 + k2, ok1 && ok2, sz1 + sz2
case *MR:
- k1, ok1 := compressionLenSearch(c, x.Mr)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Mr)
+ return k1, ok1, sz1
case *MX:
- k1, ok1 := compressionLenSearch(c, x.Mx)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Mx)
+ return k1, ok1, sz1
case *NS:
- k1, ok1 := compressionLenSearch(c, x.Ns)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Ns)
+ return k1, ok1, sz1
case *PTR:
- k1, ok1 := compressionLenSearch(c, x.Ptr)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Ptr)
+ return k1, ok1, sz1
case *RT:
- k1, ok1 := compressionLenSearch(c, x.Host)
- return k1, ok1
+ k1, ok1, sz1 := compressionLenSearch(c, x.Host)
+ return k1, ok1, sz1
case *SOA:
- k1, ok1 := compressionLenSearch(c, x.Ns)
- k2, ok2 := compressionLenSearch(c, x.Mbox)
- return k1 + k2, ok1 && ok2
+ k1, ok1, sz1 := compressionLenSearch(c, x.Ns)
+ k2, ok2, sz2 := compressionLenSearch(c, x.Mbox)
+ return k1 + k2, ok1 && ok2, sz1 + sz2
}
- return 0, false
+ return 0, false, 0
}
diff --git a/vendor/github.com/miekg/dns/ztypes.go b/vendor/github.com/miekg/dns/ztypes.go
index abd75dd91..965753b11 100644
--- a/vendor/github.com/miekg/dns/ztypes.go
+++ b/vendor/github.com/miekg/dns/ztypes.go
@@ -649,215 +649,215 @@ func (rr *X25) len() int {
// copy() functions
func (rr *A) copy() RR {
- return &A{*rr.Hdr.copyHeader(), copyIP(rr.A)}
+ return &A{rr.Hdr, copyIP(rr.A)}
}
func (rr *AAAA) copy() RR {
- return &AAAA{*rr.Hdr.copyHeader(), copyIP(rr.AAAA)}
+ return &AAAA{rr.Hdr, copyIP(rr.AAAA)}
}
func (rr *AFSDB) copy() RR {
- return &AFSDB{*rr.Hdr.copyHeader(), rr.Subtype, rr.Hostname}
+ return &AFSDB{rr.Hdr, rr.Subtype, rr.Hostname}
}
func (rr *ANY) copy() RR {
- return &ANY{*rr.Hdr.copyHeader()}
+ return &ANY{rr.Hdr}
}
func (rr *AVC) copy() RR {
Txt := make([]string, len(rr.Txt))
copy(Txt, rr.Txt)
- return &AVC{*rr.Hdr.copyHeader(), Txt}
+ return &AVC{rr.Hdr, Txt}
}
func (rr *CAA) copy() RR {
- return &CAA{*rr.Hdr.copyHeader(), rr.Flag, rr.Tag, rr.Value}
+ return &CAA{rr.Hdr, rr.Flag, rr.Tag, rr.Value}
}
func (rr *CERT) copy() RR {
- return &CERT{*rr.Hdr.copyHeader(), rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate}
+ return &CERT{rr.Hdr, rr.Type, rr.KeyTag, rr.Algorithm, rr.Certificate}
}
func (rr *CNAME) copy() RR {
- return &CNAME{*rr.Hdr.copyHeader(), rr.Target}
+ return &CNAME{rr.Hdr, rr.Target}
}
func (rr *CSYNC) copy() RR {
TypeBitMap := make([]uint16, len(rr.TypeBitMap))
copy(TypeBitMap, rr.TypeBitMap)
- return &CSYNC{*rr.Hdr.copyHeader(), rr.Serial, rr.Flags, TypeBitMap}
+ return &CSYNC{rr.Hdr, rr.Serial, rr.Flags, TypeBitMap}
}
func (rr *DHCID) copy() RR {
- return &DHCID{*rr.Hdr.copyHeader(), rr.Digest}
+ return &DHCID{rr.Hdr, rr.Digest}
}
func (rr *DNAME) copy() RR {
- return &DNAME{*rr.Hdr.copyHeader(), rr.Target}
+ return &DNAME{rr.Hdr, rr.Target}
}
func (rr *DNSKEY) copy() RR {
- return &DNSKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
+ return &DNSKEY{rr.Hdr, rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
}
func (rr *DS) copy() RR {
- return &DS{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
+ return &DS{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
}
func (rr *EID) copy() RR {
- return &EID{*rr.Hdr.copyHeader(), rr.Endpoint}
+ return &EID{rr.Hdr, rr.Endpoint}
}
func (rr *EUI48) copy() RR {
- return &EUI48{*rr.Hdr.copyHeader(), rr.Address}
+ return &EUI48{rr.Hdr, rr.Address}
}
func (rr *EUI64) copy() RR {
- return &EUI64{*rr.Hdr.copyHeader(), rr.Address}
+ return &EUI64{rr.Hdr, rr.Address}
}
func (rr *GID) copy() RR {
- return &GID{*rr.Hdr.copyHeader(), rr.Gid}
+ return &GID{rr.Hdr, rr.Gid}
}
func (rr *GPOS) copy() RR {
- return &GPOS{*rr.Hdr.copyHeader(), rr.Longitude, rr.Latitude, rr.Altitude}
+ return &GPOS{rr.Hdr, rr.Longitude, rr.Latitude, rr.Altitude}
}
func (rr *HINFO) copy() RR {
- return &HINFO{*rr.Hdr.copyHeader(), rr.Cpu, rr.Os}
+ return &HINFO{rr.Hdr, rr.Cpu, rr.Os}
}
func (rr *HIP) copy() RR {
RendezvousServers := make([]string, len(rr.RendezvousServers))
copy(RendezvousServers, rr.RendezvousServers)
- return &HIP{*rr.Hdr.copyHeader(), rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers}
+ return &HIP{rr.Hdr, rr.HitLength, rr.PublicKeyAlgorithm, rr.PublicKeyLength, rr.Hit, rr.PublicKey, RendezvousServers}
}
func (rr *KX) copy() RR {
- return &KX{*rr.Hdr.copyHeader(), rr.Preference, rr.Exchanger}
+ return &KX{rr.Hdr, rr.Preference, rr.Exchanger}
}
func (rr *L32) copy() RR {
- return &L32{*rr.Hdr.copyHeader(), rr.Preference, copyIP(rr.Locator32)}
+ return &L32{rr.Hdr, rr.Preference, copyIP(rr.Locator32)}
}
func (rr *L64) copy() RR {
- return &L64{*rr.Hdr.copyHeader(), rr.Preference, rr.Locator64}
+ return &L64{rr.Hdr, rr.Preference, rr.Locator64}
}
func (rr *LOC) copy() RR {
- return &LOC{*rr.Hdr.copyHeader(), rr.Version, rr.Size, rr.HorizPre, rr.VertPre, rr.Latitude, rr.Longitude, rr.Altitude}
+ return &LOC{rr.Hdr, rr.Version, rr.Size, rr.HorizPre, rr.VertPre, rr.Latitude, rr.Longitude, rr.Altitude}
}
func (rr *LP) copy() RR {
- return &LP{*rr.Hdr.copyHeader(), rr.Preference, rr.Fqdn}
+ return &LP{rr.Hdr, rr.Preference, rr.Fqdn}
}
func (rr *MB) copy() RR {
- return &MB{*rr.Hdr.copyHeader(), rr.Mb}
+ return &MB{rr.Hdr, rr.Mb}
}
func (rr *MD) copy() RR {
- return &MD{*rr.Hdr.copyHeader(), rr.Md}
+ return &MD{rr.Hdr, rr.Md}
}
func (rr *MF) copy() RR {
- return &MF{*rr.Hdr.copyHeader(), rr.Mf}
+ return &MF{rr.Hdr, rr.Mf}
}
func (rr *MG) copy() RR {
- return &MG{*rr.Hdr.copyHeader(), rr.Mg}
+ return &MG{rr.Hdr, rr.Mg}
}
func (rr *MINFO) copy() RR {
- return &MINFO{*rr.Hdr.copyHeader(), rr.Rmail, rr.Email}
+ return &MINFO{rr.Hdr, rr.Rmail, rr.Email}
}
func (rr *MR) copy() RR {
- return &MR{*rr.Hdr.copyHeader(), rr.Mr}
+ return &MR{rr.Hdr, rr.Mr}
}
func (rr *MX) copy() RR {
- return &MX{*rr.Hdr.copyHeader(), rr.Preference, rr.Mx}
+ return &MX{rr.Hdr, rr.Preference, rr.Mx}
}
func (rr *NAPTR) copy() RR {
- return &NAPTR{*rr.Hdr.copyHeader(), rr.Order, rr.Preference, rr.Flags, rr.Service, rr.Regexp, rr.Replacement}
+ return &NAPTR{rr.Hdr, rr.Order, rr.Preference, rr.Flags, rr.Service, rr.Regexp, rr.Replacement}
}
func (rr *NID) copy() RR {
- return &NID{*rr.Hdr.copyHeader(), rr.Preference, rr.NodeID}
+ return &NID{rr.Hdr, rr.Preference, rr.NodeID}
}
func (rr *NIMLOC) copy() RR {
- return &NIMLOC{*rr.Hdr.copyHeader(), rr.Locator}
+ return &NIMLOC{rr.Hdr, rr.Locator}
}
func (rr *NINFO) copy() RR {
ZSData := make([]string, len(rr.ZSData))
copy(ZSData, rr.ZSData)
- return &NINFO{*rr.Hdr.copyHeader(), ZSData}
+ return &NINFO{rr.Hdr, ZSData}
}
func (rr *NS) copy() RR {
- return &NS{*rr.Hdr.copyHeader(), rr.Ns}
+ return &NS{rr.Hdr, rr.Ns}
}
func (rr *NSAPPTR) copy() RR {
- return &NSAPPTR{*rr.Hdr.copyHeader(), rr.Ptr}
+ return &NSAPPTR{rr.Hdr, rr.Ptr}
}
func (rr *NSEC) copy() RR {
TypeBitMap := make([]uint16, len(rr.TypeBitMap))
copy(TypeBitMap, rr.TypeBitMap)
- return &NSEC{*rr.Hdr.copyHeader(), rr.NextDomain, TypeBitMap}
+ return &NSEC{rr.Hdr, rr.NextDomain, TypeBitMap}
}
func (rr *NSEC3) copy() RR {
TypeBitMap := make([]uint16, len(rr.TypeBitMap))
copy(TypeBitMap, rr.TypeBitMap)
- return &NSEC3{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt, rr.HashLength, rr.NextDomain, TypeBitMap}
+ return &NSEC3{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt, rr.HashLength, rr.NextDomain, TypeBitMap}
}
func (rr *NSEC3PARAM) copy() RR {
- return &NSEC3PARAM{*rr.Hdr.copyHeader(), rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
+ return &NSEC3PARAM{rr.Hdr, rr.Hash, rr.Flags, rr.Iterations, rr.SaltLength, rr.Salt}
}
func (rr *OPENPGPKEY) copy() RR {
- return &OPENPGPKEY{*rr.Hdr.copyHeader(), rr.PublicKey}
+ return &OPENPGPKEY{rr.Hdr, rr.PublicKey}
}
func (rr *OPT) copy() RR {
Option := make([]EDNS0, len(rr.Option))
copy(Option, rr.Option)
- return &OPT{*rr.Hdr.copyHeader(), Option}
+ return &OPT{rr.Hdr, Option}
}
func (rr *PTR) copy() RR {
- return &PTR{*rr.Hdr.copyHeader(), rr.Ptr}
+ return &PTR{rr.Hdr, rr.Ptr}
}
func (rr *PX) copy() RR {
- return &PX{*rr.Hdr.copyHeader(), rr.Preference, rr.Map822, rr.Mapx400}
+ return &PX{rr.Hdr, rr.Preference, rr.Map822, rr.Mapx400}
}
func (rr *RFC3597) copy() RR {
- return &RFC3597{*rr.Hdr.copyHeader(), rr.Rdata}
+ return &RFC3597{rr.Hdr, rr.Rdata}
}
func (rr *RKEY) copy() RR {
- return &RKEY{*rr.Hdr.copyHeader(), rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
+ return &RKEY{rr.Hdr, rr.Flags, rr.Protocol, rr.Algorithm, rr.PublicKey}
}
func (rr *RP) copy() RR {
- return &RP{*rr.Hdr.copyHeader(), rr.Mbox, rr.Txt}
+ return &RP{rr.Hdr, rr.Mbox, rr.Txt}
}
func (rr *RRSIG) copy() RR {
- return &RRSIG{*rr.Hdr.copyHeader(), rr.TypeCovered, rr.Algorithm, rr.Labels, rr.OrigTtl, rr.Expiration, rr.Inception, rr.KeyTag, rr.SignerName, rr.Signature}
+ return &RRSIG{rr.Hdr, rr.TypeCovered, rr.Algorithm, rr.Labels, rr.OrigTtl, rr.Expiration, rr.Inception, rr.KeyTag, rr.SignerName, rr.Signature}
}
func (rr *RT) copy() RR {
- return &RT{*rr.Hdr.copyHeader(), rr.Preference, rr.Host}
+ return &RT{rr.Hdr, rr.Preference, rr.Host}
}
func (rr *SMIMEA) copy() RR {
- return &SMIMEA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
+ return &SMIMEA{rr.Hdr, rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
}
func (rr *SOA) copy() RR {
- return &SOA{*rr.Hdr.copyHeader(), rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl}
+ return &SOA{rr.Hdr, rr.Ns, rr.Mbox, rr.Serial, rr.Refresh, rr.Retry, rr.Expire, rr.Minttl}
}
func (rr *SPF) copy() RR {
Txt := make([]string, len(rr.Txt))
copy(Txt, rr.Txt)
- return &SPF{*rr.Hdr.copyHeader(), Txt}
+ return &SPF{rr.Hdr, Txt}
}
func (rr *SRV) copy() RR {
- return &SRV{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Port, rr.Target}
+ return &SRV{rr.Hdr, rr.Priority, rr.Weight, rr.Port, rr.Target}
}
func (rr *SSHFP) copy() RR {
- return &SSHFP{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Type, rr.FingerPrint}
+ return &SSHFP{rr.Hdr, rr.Algorithm, rr.Type, rr.FingerPrint}
}
func (rr *TA) copy() RR {
- return &TA{*rr.Hdr.copyHeader(), rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
+ return &TA{rr.Hdr, rr.KeyTag, rr.Algorithm, rr.DigestType, rr.Digest}
}
func (rr *TALINK) copy() RR {
- return &TALINK{*rr.Hdr.copyHeader(), rr.PreviousName, rr.NextName}
+ return &TALINK{rr.Hdr, rr.PreviousName, rr.NextName}
}
func (rr *TKEY) copy() RR {
- return &TKEY{*rr.Hdr.copyHeader(), rr.Algorithm, rr.Inception, rr.Expiration, rr.Mode, rr.Error, rr.KeySize, rr.Key, rr.OtherLen, rr.OtherData}
+ return &TKEY{rr.Hdr, rr.Algorithm, rr.Inception, rr.Expiration, rr.Mode, rr.Error, rr.KeySize, rr.Key, rr.OtherLen, rr.OtherData}
}
func (rr *TLSA) copy() RR {
- return &TLSA{*rr.Hdr.copyHeader(), rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
+ return &TLSA{rr.Hdr, rr.Usage, rr.Selector, rr.MatchingType, rr.Certificate}
}
func (rr *TSIG) copy() RR {
- return &TSIG{*rr.Hdr.copyHeader(), rr.Algorithm, rr.TimeSigned, rr.Fudge, rr.MACSize, rr.MAC, rr.OrigId, rr.Error, rr.OtherLen, rr.OtherData}
+ return &TSIG{rr.Hdr, rr.Algorithm, rr.TimeSigned, rr.Fudge, rr.MACSize, rr.MAC, rr.OrigId, rr.Error, rr.OtherLen, rr.OtherData}
}
func (rr *TXT) copy() RR {
Txt := make([]string, len(rr.Txt))
copy(Txt, rr.Txt)
- return &TXT{*rr.Hdr.copyHeader(), Txt}
+ return &TXT{rr.Hdr, Txt}
}
func (rr *UID) copy() RR {
- return &UID{*rr.Hdr.copyHeader(), rr.Uid}
+ return &UID{rr.Hdr, rr.Uid}
}
func (rr *UINFO) copy() RR {
- return &UINFO{*rr.Hdr.copyHeader(), rr.Uinfo}
+ return &UINFO{rr.Hdr, rr.Uinfo}
}
func (rr *URI) copy() RR {
- return &URI{*rr.Hdr.copyHeader(), rr.Priority, rr.Weight, rr.Target}
+ return &URI{rr.Hdr, rr.Priority, rr.Weight, rr.Target}
}
func (rr *X25) copy() RR {
- return &X25{*rr.Hdr.copyHeader(), rr.PSDNAddress}
+ return &X25{rr.Hdr, rr.PSDNAddress}
}
diff --git a/vendor/vendor.json b/vendor/vendor.json
index 152539269..6b1c1830d 100644
--- a/vendor/vendor.json
+++ b/vendor/vendor.json
@@ -84,7 +84,7 @@
{"path":"github.com/joyent/triton-go/errors","checksumSHA1":"d/Py6j/uMgOAFNFGpsQrNnSsO+k=","revision":"7283d1d02f7a297bf2f068178a084c5bd090002c","revisionTime":"2018-04-27T15:22:50Z"},
{"path":"github.com/mattn/go-isatty","checksumSHA1":"xZuhljnmBysJPta/lMyYmJdujCg=","revision":"66b8e73f3f5cda9f96b69efd03dd3d7fc4a5cdb8","revisionTime":"2016-08-06T12:27:52Z"},
{"path":"github.com/matttproud/golang_protobuf_extensions/pbutil","checksumSHA1":"bKMZjd2wPw13VwoE7mBeSv5djFA=","revision":"c12348ce28de40eed0136aa2b644d0ee0650e56c","revisionTime":"2016-04-24T11:30:07Z"},
- {"path":"github.com/miekg/dns","checksumSHA1":"XTeOihCDhjG6ltUKExoJ2uEzShk=","revision":"5364553f1ee9cddc7ac8b62dce148309c386695b","revisionTime":"2018-01-25T10:38:03Z","version":"v1.0.4","versionExact":"v1.0.4"},
+ {"path":"github.com/miekg/dns","checksumSHA1":"ybBd9oDdeJEZj9YmIKGqaBVqZok=","revision":"e57bf427e68187a27e22adceac868350d7a7079b","revisionTime":"2018-05-16T07:59:02Z","version":"v1.0.7","versionExact":"v1.0.7"},
{"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/go-homedir","checksumSHA1":"V/quM7+em2ByJbWBLOsEwnY3j/Q=","revision":"b8bc1bf767474819792c23f32d8286a45736f1c6","revisionTime":"2016-12-03T19:45:07Z"},
From 7e8878df0beb4b11dcd98b59135eb674e0c4870d Mon Sep 17 00:00:00 2001
From: Pierre Souchay
Date: Wed, 16 May 2018 11:00:51 +0200
Subject: [PATCH 2/8] Re-Enable compression while computing Len(), so we can
send more answers
This will fix https://github.com/hashicorp/consul/issues/4071
---
agent/dns.go | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/agent/dns.go b/agent/dns.go
index f1c0d8bda..2cc015a42 100644
--- a/agent/dns.go
+++ b/agent/dns.go
@@ -745,9 +745,6 @@ func (d *DNSServer) trimTCPResponse(req, resp *dns.Msg) (trimmed bool) {
hasExtra := len(resp.Extra) > 0
// There is some overhead, 65535 does not work
maxSize := 65533 // 64k - 2 bytes
- // In order to compute properly, we have to avoid compress first
- compressed := resp.Compress
- resp.Compress = false
// We avoid some function calls and allocations by only handling the
// extra data when necessary.
@@ -790,8 +787,6 @@ func (d *DNSServer) trimTCPResponse(req, resp *dns.Msg) (trimmed bool) {
req.Question,
len(resp.Answer), originalNumRecords, resp.Len(), originalSize)
}
- // Restore compression if any
- resp.Compress = compressed
return truncated
}
@@ -821,7 +816,10 @@ func trimUDPResponse(req, resp *dns.Msg, udpAnswerLimit int) (trimmed bool) {
// This cuts UDP responses to a useful but limited number of responses.
maxAnswers := lib.MinInt(maxUDPAnswerLimit, udpAnswerLimit)
+ compress := resp.Compress
if maxSize == defaultMaxUDPSize && numAnswers > maxAnswers {
+ // We disable computation of Len ONLY for non-eDNS request (512 bytes)
+ resp.Compress = false
resp.Answer = resp.Answer[:maxAnswers]
if hasExtra {
syncExtra(index, resp)
@@ -834,9 +832,9 @@ func trimUDPResponse(req, resp *dns.Msg, udpAnswerLimit int) (trimmed bool) {
// that will not exceed 512 bytes uncompressed, which is more conservative and
// will allow our responses to be compliant even if some downstream server
// uncompresses them.
- compress := resp.Compress
- resp.Compress = false
- for len(resp.Answer) > 0 && resp.Len() > maxSize {
+ // Even when size is too big for one single record, try to send it anyway
+ // (usefull for 512 bytes messages)
+ for len(resp.Answer) > 1 && resp.Len() > maxSize {
// More than 100 bytes, find with a binary search
if resp.Len()-maxSize > 100 {
bestIndex := dnsBinaryTruncate(resp, maxSize, index, hasExtra)
@@ -848,6 +846,8 @@ func trimUDPResponse(req, resp *dns.Msg, udpAnswerLimit int) (trimmed bool) {
syncExtra(index, resp)
}
}
+ // For 512 non-eDNS responses, while we compute size non-compressed,
+ // we send result compressed
resp.Compress = compress
return len(resp.Answer) < numAnswers
From 5f529c9ea7baa639bd3951c492d106eacf5b866c Mon Sep 17 00:00:00 2001
From: Pierre Souchay
Date: Wed, 16 May 2018 12:11:49 +0200
Subject: [PATCH 3/8] Fixed unit tests and updated limits
---
agent/dns.go | 4 ++--
agent/dns_test.go | 55 ++++++++++++++++++++++++++---------------------
2 files changed, 33 insertions(+), 26 deletions(-)
diff --git a/agent/dns.go b/agent/dns.go
index 2cc015a42..879f177f8 100644
--- a/agent/dns.go
+++ b/agent/dns.go
@@ -755,9 +755,9 @@ func (d *DNSServer) trimTCPResponse(req, resp *dns.Msg) (trimmed bool) {
// Beyond 2500 records, performance gets bad
// Limit the number of records at once, anyway, it won't fit in 64k
// For SRV Records, the max is around 500 records, for A, less than 2k
- truncateAt := 2048
+ truncateAt := 4096
if req.Question[0].Qtype == dns.TypeSRV {
- truncateAt = 640
+ truncateAt = 1024
}
if len(resp.Answer) > truncateAt {
resp.Answer = resp.Answer[:truncateAt]
diff --git a/agent/dns_test.go b/agent/dns_test.go
index 0770c92a0..1fc31bbba 100644
--- a/agent/dns_test.go
+++ b/agent/dns_test.go
@@ -3080,32 +3080,39 @@ func TestDNS_TCP_and_UDP_Truncate(t *testing.T) {
"tcp",
"udp",
}
- for _, qType := range []uint16{dns.TypeANY, dns.TypeA, dns.TypeSRV} {
- for _, question := range questions {
- for _, protocol := range protocols {
- for _, compress := range []bool{true, false} {
- t.Run(fmt.Sprintf("lookup %s %s (qType:=%d) compressed=%v", question, protocol, qType, compress), func(t *testing.T) {
- m := new(dns.Msg)
- m.SetQuestion(question, dns.TypeANY)
- if protocol == "udp" {
- m.SetEdns0(8192, true)
- }
- c := new(dns.Client)
- c.Net = protocol
- m.Compress = compress
- in, out, err := c.Exchange(m, a.DNSAddr())
- if err != nil && err != dns.ErrTruncated {
- t.Fatalf("err: %v", err)
- }
- // Check for the truncate bit
- shouldBeTruncated := numServices > 5000
+ for _, maxSize := range []uint16{8192, 65535} {
+ for _, qType := range []uint16{dns.TypeANY, dns.TypeA, dns.TypeSRV} {
+ for _, question := range questions {
+ for _, protocol := range protocols {
+ for _, compress := range []bool{true, false} {
+ t.Run(fmt.Sprintf("lookup %s %s (qType:=%d) compressed=%v", question, protocol, qType, compress), func(t *testing.T) {
+ m := new(dns.Msg)
+ m.SetQuestion(question, dns.TypeANY)
+ maxSz := maxSize
+ if protocol == "udp" {
+ maxSz = 8192
+ }
+ m.SetEdns0(uint16(maxSz), true)
+ c := new(dns.Client)
+ c.Net = protocol
+ m.Compress = compress
+ in, _, err := c.Exchange(m, a.DNSAddr())
+ if err != nil && err != dns.ErrTruncated {
+ t.Fatalf("err: %v", err)
+ }
- if shouldBeTruncated != in.Truncated || len(in.Answer) > 2000 || len(in.Answer) < 1 || in.Len() > 65535 {
+ // Check for the truncate bit
+ buf, err := m.Pack()
info := fmt.Sprintf("service %s question:=%s (%s) (%d total records) sz:= %d in %v",
- service, question, protocol, numServices, len(in.Answer), out)
- t.Fatalf("Should have truncated:=%v for %s", shouldBeTruncated, info)
- }
- })
+ service, question, protocol, numServices, len(in.Answer), in)
+ if err != nil {
+ t.Fatalf("Error while packing: %v ; info:=%s", err, info)
+ }
+ if len(buf) > int(maxSz) {
+ t.Fatalf("len(buf) := %d > maxSz=%d for %v", len(buf), maxSz, info)
+ }
+ })
+ }
}
}
}
From 74cbe5ac8540c3933367ededa6533413562cb14a Mon Sep 17 00:00:00 2001
From: Pierre Souchay
Date: Wed, 16 May 2018 12:47:35 +0200
Subject: [PATCH 4/8] Ensure to never send messages more than 64k
---
agent/dns.go | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/agent/dns.go b/agent/dns.go
index 879f177f8..85c977768 100644
--- a/agent/dns.go
+++ b/agent/dns.go
@@ -744,7 +744,7 @@ func dnsBinaryTruncate(resp *dns.Msg, maxSize int, index map[string]dns.RR, hasE
func (d *DNSServer) trimTCPResponse(req, resp *dns.Msg) (trimmed bool) {
hasExtra := len(resp.Extra) > 0
// There is some overhead, 65535 does not work
- maxSize := 65533 // 64k - 2 bytes
+ maxSize := 65523 // 64k - 12 bytes DNS raw overhead
// We avoid some function calls and allocations by only handling the
// extra data when necessary.
@@ -769,7 +769,7 @@ func (d *DNSServer) trimTCPResponse(req, resp *dns.Msg) (trimmed bool) {
truncated := false
// This enforces the given limit on 64k, the max limit for DNS messages
- for len(resp.Answer) > 0 && resp.Len() > maxSize {
+ for len(resp.Answer) > 1 && resp.Len() > maxSize {
truncated = true
// More than 100 bytes, find with a binary search
if resp.Len()-maxSize > 100 {
From b3d4b9d8005b72b838248e0b2f36335f14e3a80c Mon Sep 17 00:00:00 2001
From: Pierre Souchay
Date: Wed, 16 May 2018 13:09:50 +0200
Subject: [PATCH 5/8] Certificate for Alice was too old, updating it for tests
---
test/hostname/Alice.crt | 32 +++++++++++------------
test/hostname/Alice.key | 55 ++++++++++++++++++++--------------------
test/hostname/certindex | 1 +
test/hostname/serialfile | 2 +-
4 files changed, 46 insertions(+), 44 deletions(-)
diff --git a/test/hostname/Alice.crt b/test/hostname/Alice.crt
index 1d2e9a758..cd9be35c7 100644
--- a/test/hostname/Alice.crt
+++ b/test/hostname/Alice.crt
@@ -1,23 +1,23 @@
-----BEGIN CERTIFICATE-----
-MIIDyTCCArGgAwIBAgIBGDANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
+MIIDyTCCArGgAwIBAgIBGTANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
EzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC0xvcyBBbmdlbGVzMRkwFwYD
VQQKExBIYWhpQ29ycCBUZXN0IENBMQ0wCwYDVQQLEwRUZXN0MREwDwYDVQQDEwhD
ZXJ0QXV0aDEiMCAGCSqGSIb3DQEJARYTamFtZXNAaGFzaGljb3JwLmNvbTAeFw0x
-NzA1MTIwNjE1NDhaFw0xODA1MTIwNjE1NDhaMHwxDjAMBgNVBAMMBUFsaWNlMRMw
+ODA1MTYxMTA4NDZaFw0xOTA1MTYxMTA4NDZaMHwxDjAMBgNVBAMMBUFsaWNlMRMw
EQYDVQQIDApDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzEiMCAGCSqGSIb3DQEJARYT
amFtZXNAaGFzaGljb3JwLmNvbTESMBAGA1UECgwJRW5kIFBvaW50MRAwDgYDVQQL
-DAdUZXN0aW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvDVBeQvC
-7hVijs6jjWzgD2c2whjBvDDqAzUOs2Xk1JfD2TT+eVPP47cuK4ufB3EbfYwrgq/J
-v1NRvstEDXp1Croof8E3oBWbR3sXVK8BAiwwRVLuY95ApvqL8VkxXTSkp7hcE+dK
-AGJH3+m4T+0nxgasHhWYJO2wsJy9/dVL3cQN+tXvgzo7PZCX83dmiTDh2M9A+Uo8
-lSWb5YAhf8n2b3C4K+qLNhtGRpO33GfQ5XNkuRMTLbwu7eUP0IjYdrt8LmUpgrWB
-WyGaQDUutisi5kv47yuK1d4o6q1LVHjvaFRtKKpiFQVZJCJMmdB9SI6QiOqFuyVC
-EM4MgzRtkRW4UwIDAQABozgwNjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAcBgNV
-HREEFTATghFzZXJ2ZXIuZGMxLmNvbnN1bDANBgkqhkiG9w0BAQUFAAOCAQEAJsFF
-Bj7rz0z/GDGtaAth5SIsRG9dmA9Lkyfpbjz351jp8kmFCma/rVBBP3yQ/O4FcvbY
-DImmqEnotS/o5CcJI1jtjFcqW+QllFCWhY1ovkkEmyAFE9g5gLGKXxPX/uuvdVly
-LgLNu7wgE2SHcUpDGPRt/xfon7syb/ZWUDU43xNkGFmgZyb9xTIWkmxYDuXYSPUY
-Zb5YS2GWrX28HOrkkm4DY/Gf71w7eM4FKe/q/8hXQqkDooHPYE1aFZX2mgLhnr+Y
-cdLsR5AlF7PgE4WmOHWVm0WyH1c8Df39AlgFXPyZEOl6Zt00m6PWbqHnkojcaaNj
-jq7ykWgpRkdSgQSa+Q==
+DAdUZXN0aW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwWOMeMou
+mi9RWzYqRTVFpES4jP5BhC71aMZxiQ912OVeFqnDfOyK2BNjoq2rk39vxkBXFn9o
+HkLh+6ITR/4waslF6zVhRrIHD/f3LrXzIL0KI0lkM8EJso+TG9AjTd4A9+/fKQ5C
+iIoFVggQfIKZ1thYC2vnQIUo3OZT+Awqbu0rBUuRUw+h8jOMk6DOsIrwTTCR1erw
+FyYWalTR4GMbaNiBb7rjuj0cbU1FFl80u+h5k1QrmYBklWR01fl33b9BLemSSVyX
+URU9Zxid7koarGI60PqwU1R/i3KJ4HoBEatZp72qsmiDWIE8bifBQAnpaTCNu7wI
+H63glOPzWmckwwIDAQABozgwNjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAcBgNV
+HREEFTATghFzZXJ2ZXIuZGMxLmNvbnN1bDANBgkqhkiG9w0BAQUFAAOCAQEAWCFW
+fkLO7BaMNpDA/0CAZsIol6eGBvcs96Cm2rUqKSsT/vNNY+HSk3Meq3YX9qUWEN/3
+Fy2i83cxW/+2OGcueg4cifk2j65Hl7D3e4KKny4Hgrfsx129+omlT7fsEfJfEeAk
+OYgi//We+0y7Acg2fMjxDIX8GWv7R2RmbdXfB0FHq7BKDwGNhArOa7EHImcn5GGW
+NS2jb/jvsQyRE7dIJfrWtbb4hzm9fSvZDa1aZ7k8QGGeDpRWnWw9lA7twE8mmo3+
+vLigpIfabIOkd0I3FxiRzDOnP0kaGppXfcL3s+rHA3GWkjOU5itUQ+WP+9+5N6re
+/DMUgsI/xzvxi5+dWg==
-----END CERTIFICATE-----
diff --git a/test/hostname/Alice.key b/test/hostname/Alice.key
index db4ab769d..834b4017b 100644
--- a/test/hostname/Alice.key
+++ b/test/hostname/Alice.key
@@ -1,27 +1,28 @@
------BEGIN RSA PRIVATE KEY-----
-MIIEpQIBAAKCAQEAvDVBeQvC7hVijs6jjWzgD2c2whjBvDDqAzUOs2Xk1JfD2TT+
-eVPP47cuK4ufB3EbfYwrgq/Jv1NRvstEDXp1Croof8E3oBWbR3sXVK8BAiwwRVLu
-Y95ApvqL8VkxXTSkp7hcE+dKAGJH3+m4T+0nxgasHhWYJO2wsJy9/dVL3cQN+tXv
-gzo7PZCX83dmiTDh2M9A+Uo8lSWb5YAhf8n2b3C4K+qLNhtGRpO33GfQ5XNkuRMT
-Lbwu7eUP0IjYdrt8LmUpgrWBWyGaQDUutisi5kv47yuK1d4o6q1LVHjvaFRtKKpi
-FQVZJCJMmdB9SI6QiOqFuyVCEM4MgzRtkRW4UwIDAQABAoIBAQCPfFqKGjlmoc8d
-6NQwAg1gMORCXfV1sCT4hP7MLqainYGmmwxXG1qm1QTSFgQL/GNk9/REEhjRUIhF
-2VnsnKuWng46N+hcl5xmhqVm3nT6Xw3+DBfK86p+ow0F12YXFQdjBt7MHc0BNext
-/RWTec6U3olh9jykCsJmI1mFp5PLYVg4OjJz6v0GdnkBv6CCuwv0Talz8vEX4js9
-AZvPAlCFR2rqmdAwpeHV/dk4x4ls04Hv8g1L40EhToBetfKOeT4PWA3Svg/71uGg
-6QqQi642quWXZQL255fP9crMYfj12AUbFe4+ET6/3wZkpFeNgifAbLY1lOfEhjD3
-ey7OjNhhAoGBAPUyoEpu8KDYgHM2b68yykmEjHXgpNGizsOrAV5kFbk7lTRYqoju
-jKDROzOOH79OU+emCz9WlVatCrSXZoVMEfCIVtSsuL19z492sk2eX3qGz0fRN6Os
-/z8K9QZ1fIAw+8W1QnwRRqZhRd7SiFLKrGY7huoq9KL8hqHx2Jw9KSlPAoGBAMR/
-5ERVShxS+ADfFtRoUMEd9kcFEleQiq4tWosyAxB27+f+Q8lAIKNjmVNE1F1RC/Fi
-h6BeQBbM6n9j5Q8+r8st7OYBpEu260teAKiE8GlB8s1D2s4oDvB5usvWnsl53gTU
-WdpP5/M2Ioze5fl/8dZXshGPb6gHMXqwSNPr+fe9AoGAG9yn2C1pDG3tkqnx4O+d
-iuMT7uUa9XNRmWxaGHa4/TZnCu60WiD5O+DqoD4bH2rwH9d/WbAmAhZhrAm0LZtq
-QnHLpBkIWQftyPiM5EMFyG9/KEL+1ot26Zv+IcDB5/Mo+NtS9bQk2g0dmmdD9Fxx
-YKCNARjmeYrGZaqMmZxdjAMCgYEAhXE8uVMaYyXNGfpmbJTy0lLgntZI4IJeS26t
-YH30Ksg6n9fCfPc5svu+chf6B+00KRb6d+PJrjI2xZA3TCUMCPUFPiW7R1fPbn1G
-AStWgISyuMbt3rbBfnmMa0UyzCwgpDL5WhKNuFL5H6V3k/pZZ3Bikx5Pe1J3PZRd
-wN0uAhkCgYEAm6PvhIWY8dtOIJZOKB+GcuSfFKJrvfWPL7Lb6gfq45ojsl7EoMiW
-h/uetqAYaAr4kQCZApSfrtwc5GeB8o93Xl6gFqM3Qo32wCITMaSrNRMuEtq1G9AX
-Q+rGXgPFsMMA8nV3QOMftBNWan5O74w24+4LDu4WQex7EAaiH8J+jkk=
------END RSA PRIVATE KEY-----
+-----BEGIN PRIVATE KEY-----
+MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBY4x4yi6aL1Fb
+NipFNUWkRLiM/kGELvVoxnGJD3XY5V4WqcN87IrYE2OirauTf2/GQFcWf2geQuH7
+ohNH/jBqyUXrNWFGsgcP9/cutfMgvQojSWQzwQmyj5Mb0CNN3gD3798pDkKIigVW
+CBB8gpnW2FgLa+dAhSjc5lP4DCpu7SsFS5FTD6HyM4yToM6wivBNMJHV6vAXJhZq
+VNHgYxto2IFvuuO6PRxtTUUWXzS76HmTVCuZgGSVZHTV+Xfdv0Et6ZJJXJdRFT1n
+GJ3uShqsYjrQ+rBTVH+LcongegERq1mnvaqyaINYgTxuJ8FACelpMI27vAgfreCU
+4/NaZyTDAgMBAAECggEBAJJhDYSoVNn0EvqdZyV3iz0pnx9pnKG3AZ7LBkkeYK9J
+/gvdd9DpIrcnBfWuyv4cKbjAHqsyyNaO/YqARWPq7S8HJltAzl66hkn6ASlkI6GW
+NUQ8WxIpfXOg5VLaGr7n2YfSEvJ6jrXW8u8Jr6DvIg7TNuF+TU4y/Jkn5ksMulm2
+7lDM0ccemYPt6EGS8CNh9UxGGEuDFpz5C+FOYNu0l2TEP7dyxBBsQgKQ/ni53EVS
+mfSKFB42XqVp6uNFl4nuQGaRfJQTz+HoqM9yvGXx+4VbCwpvbWStuoPM9SSOjilG
+9sZrsT4BWfaN+k4bF6vkiPFTG9re8UXw7KuwldZWUrECgYEA3wLGp28GDZ4jdhhJ
+CU8PD4xqrJxGp/thGPL8PPeJK1ESdwePNcG8ejsDZtixgk6lkOuZaW0ISXTC2mCO
+YYCesass9zVfWkM3DgLWFO1DMlOLdu+qSHNA1/TaDG2P1C4q4C48Nlg7P6bvRv5q
+0lhzMe5HHxGY02LaHAaFgeeV3l0CgYEA3f8DsAT15LKmh9VWtZuvdd/ai6NV2WbM
+CQDtlF9X0kxqC0vOG+BemhcGVI5JUR8ajl5dhcLuV7xGJ6CxdDp6xG8rBx0cezs3
+kGwDeP368AeONudcJv6vHmOkWCkRMlQx1gTUt+rRIEV0WkvNYFIX73wBcaXHHkti
+am/596mPnZ8CgYBbJ6NTpQnwXwdXqi2QZIRfcqHX1Dj9SL8zl36K3RNwZT8K8EgV
+TQ9hVuXZEBHelY8PYX3fnfWZMOTEplsMd6pmLPXARkyndHn4fChNfX3OAGAtSWFt
+I88Jdsf59H6p2AUmhT+PZxkwt2duuWeoewb7Dc58YJD7Npi4g+Hma2bS8QKBgE/M
+iYDOZ62L4nzVXVPu4MWYcDDdx9BcOV/LK5u4IhOAUGY7G529q4PsXuQqOYSlj6A5
+n5ijl5WGIhnAk8lZ9COEao0mE8TgZnrNuPnXIksCDEcEJ4YE6uIbo0nliT70MO3j
+0qtCB2Z4UPjcYrkLCXuWsdYuZ0MmifwEwHAcTXm1AoGAW5OQ6WYm6dtfoO6XeGt7
+tphAIiKwtiIm2iyWr/wPOHF15F57X5RTq2G5QYvXLu6WVe6NIKY0/LT7Aa6h+E98
+bFk7yX/JgMIA8o81sFTeyjHrukl0JvlvyqO2y5KuQq8omMDoiGV83T+dJuD77HpF
+cZA3Drn6DYCB/ApOVxRIQYM=
+-----END PRIVATE KEY-----
diff --git a/test/hostname/certindex b/test/hostname/certindex
index a84dae079..764b6477a 100644
--- a/test/hostname/certindex
+++ b/test/hostname/certindex
@@ -1 +1,2 @@
V 180512061548Z 18 unknown /CN=Alice/ST=California/C=US/emailAddress=james@hashicorp.com/O=End Point/OU=Testing
+V 190516110846Z 19 unknown /CN=Alice/ST=California/C=US/emailAddress=james@hashicorp.com/O=End Point/OU=Testing
diff --git a/test/hostname/serialfile b/test/hostname/serialfile
index d6b24041c..268de3f3e 100644
--- a/test/hostname/serialfile
+++ b/test/hostname/serialfile
@@ -1 +1 @@
-19
+1A
From 5c1c9cde3491b7b80aa454c6b4fde74973cb188d Mon Sep 17 00:00:00 2001
From: Pierre Souchay
Date: Wed, 16 May 2018 14:10:35 +0200
Subject: [PATCH 6/8] Test fix, trying to pass Travis tests
---
agent/dns_test.go | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/agent/dns_test.go b/agent/dns_test.go
index 1fc31bbba..e5421fc41 100644
--- a/agent/dns_test.go
+++ b/agent/dns_test.go
@@ -3039,7 +3039,7 @@ func TestDNS_TCP_and_UDP_Truncate(t *testing.T) {
args := &structs.RegisterRequest{
Datacenter: "dc1",
Node: fmt.Sprintf("%s-%d.acme.com", service, i),
- Address: fmt.Sprintf("127.%d.%d.%d", index, (i / 255), i%255),
+ Address: fmt.Sprintf("127.%d.%d.%d", 0, (i / 255), i%255),
Service: &structs.NodeService{
Service: service,
Port: 8000,
From 5b6367f3e95c143f737c280c14bbd96952df5b52 Mon Sep 17 00:00:00 2001
From: Pierre Souchay
Date: Wed, 16 May 2018 18:59:57 +0200
Subject: [PATCH 7/8] Revert "Certificate for Alice was too old, updating it
for tests"
This reverts commit aeac0580acd4b5de977a4024417753a67f64820e.
---
test/hostname/Alice.crt | 32 +++++++++++------------
test/hostname/Alice.key | 55 ++++++++++++++++++++--------------------
test/hostname/certindex | 1 -
test/hostname/serialfile | 2 +-
4 files changed, 44 insertions(+), 46 deletions(-)
diff --git a/test/hostname/Alice.crt b/test/hostname/Alice.crt
index cd9be35c7..1d2e9a758 100644
--- a/test/hostname/Alice.crt
+++ b/test/hostname/Alice.crt
@@ -1,23 +1,23 @@
-----BEGIN CERTIFICATE-----
-MIIDyTCCArGgAwIBAgIBGTANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
+MIIDyTCCArGgAwIBAgIBGDANBgkqhkiG9w0BAQUFADCBmTELMAkGA1UEBhMCVVMx
EzARBgNVBAgTCkNhbGlmb3JuaWExFDASBgNVBAcTC0xvcyBBbmdlbGVzMRkwFwYD
VQQKExBIYWhpQ29ycCBUZXN0IENBMQ0wCwYDVQQLEwRUZXN0MREwDwYDVQQDEwhD
ZXJ0QXV0aDEiMCAGCSqGSIb3DQEJARYTamFtZXNAaGFzaGljb3JwLmNvbTAeFw0x
-ODA1MTYxMTA4NDZaFw0xOTA1MTYxMTA4NDZaMHwxDjAMBgNVBAMMBUFsaWNlMRMw
+NzA1MTIwNjE1NDhaFw0xODA1MTIwNjE1NDhaMHwxDjAMBgNVBAMMBUFsaWNlMRMw
EQYDVQQIDApDYWxpZm9ybmlhMQswCQYDVQQGEwJVUzEiMCAGCSqGSIb3DQEJARYT
amFtZXNAaGFzaGljb3JwLmNvbTESMBAGA1UECgwJRW5kIFBvaW50MRAwDgYDVQQL
-DAdUZXN0aW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwWOMeMou
-mi9RWzYqRTVFpES4jP5BhC71aMZxiQ912OVeFqnDfOyK2BNjoq2rk39vxkBXFn9o
-HkLh+6ITR/4waslF6zVhRrIHD/f3LrXzIL0KI0lkM8EJso+TG9AjTd4A9+/fKQ5C
-iIoFVggQfIKZ1thYC2vnQIUo3OZT+Awqbu0rBUuRUw+h8jOMk6DOsIrwTTCR1erw
-FyYWalTR4GMbaNiBb7rjuj0cbU1FFl80u+h5k1QrmYBklWR01fl33b9BLemSSVyX
-URU9Zxid7koarGI60PqwU1R/i3KJ4HoBEatZp72qsmiDWIE8bifBQAnpaTCNu7wI
-H63glOPzWmckwwIDAQABozgwNjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAcBgNV
-HREEFTATghFzZXJ2ZXIuZGMxLmNvbnN1bDANBgkqhkiG9w0BAQUFAAOCAQEAWCFW
-fkLO7BaMNpDA/0CAZsIol6eGBvcs96Cm2rUqKSsT/vNNY+HSk3Meq3YX9qUWEN/3
-Fy2i83cxW/+2OGcueg4cifk2j65Hl7D3e4KKny4Hgrfsx129+omlT7fsEfJfEeAk
-OYgi//We+0y7Acg2fMjxDIX8GWv7R2RmbdXfB0FHq7BKDwGNhArOa7EHImcn5GGW
-NS2jb/jvsQyRE7dIJfrWtbb4hzm9fSvZDa1aZ7k8QGGeDpRWnWw9lA7twE8mmo3+
-vLigpIfabIOkd0I3FxiRzDOnP0kaGppXfcL3s+rHA3GWkjOU5itUQ+WP+9+5N6re
-/DMUgsI/xzvxi5+dWg==
+DAdUZXN0aW5nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvDVBeQvC
+7hVijs6jjWzgD2c2whjBvDDqAzUOs2Xk1JfD2TT+eVPP47cuK4ufB3EbfYwrgq/J
+v1NRvstEDXp1Croof8E3oBWbR3sXVK8BAiwwRVLuY95ApvqL8VkxXTSkp7hcE+dK
+AGJH3+m4T+0nxgasHhWYJO2wsJy9/dVL3cQN+tXvgzo7PZCX83dmiTDh2M9A+Uo8
+lSWb5YAhf8n2b3C4K+qLNhtGRpO33GfQ5XNkuRMTLbwu7eUP0IjYdrt8LmUpgrWB
+WyGaQDUutisi5kv47yuK1d4o6q1LVHjvaFRtKKpiFQVZJCJMmdB9SI6QiOqFuyVC
+EM4MgzRtkRW4UwIDAQABozgwNjAJBgNVHRMEAjAAMAsGA1UdDwQEAwIF4DAcBgNV
+HREEFTATghFzZXJ2ZXIuZGMxLmNvbnN1bDANBgkqhkiG9w0BAQUFAAOCAQEAJsFF
+Bj7rz0z/GDGtaAth5SIsRG9dmA9Lkyfpbjz351jp8kmFCma/rVBBP3yQ/O4FcvbY
+DImmqEnotS/o5CcJI1jtjFcqW+QllFCWhY1ovkkEmyAFE9g5gLGKXxPX/uuvdVly
+LgLNu7wgE2SHcUpDGPRt/xfon7syb/ZWUDU43xNkGFmgZyb9xTIWkmxYDuXYSPUY
+Zb5YS2GWrX28HOrkkm4DY/Gf71w7eM4FKe/q/8hXQqkDooHPYE1aFZX2mgLhnr+Y
+cdLsR5AlF7PgE4WmOHWVm0WyH1c8Df39AlgFXPyZEOl6Zt00m6PWbqHnkojcaaNj
+jq7ykWgpRkdSgQSa+Q==
-----END CERTIFICATE-----
diff --git a/test/hostname/Alice.key b/test/hostname/Alice.key
index 834b4017b..db4ab769d 100644
--- a/test/hostname/Alice.key
+++ b/test/hostname/Alice.key
@@ -1,28 +1,27 @@
------BEGIN PRIVATE KEY-----
-MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDBY4x4yi6aL1Fb
-NipFNUWkRLiM/kGELvVoxnGJD3XY5V4WqcN87IrYE2OirauTf2/GQFcWf2geQuH7
-ohNH/jBqyUXrNWFGsgcP9/cutfMgvQojSWQzwQmyj5Mb0CNN3gD3798pDkKIigVW
-CBB8gpnW2FgLa+dAhSjc5lP4DCpu7SsFS5FTD6HyM4yToM6wivBNMJHV6vAXJhZq
-VNHgYxto2IFvuuO6PRxtTUUWXzS76HmTVCuZgGSVZHTV+Xfdv0Et6ZJJXJdRFT1n
-GJ3uShqsYjrQ+rBTVH+LcongegERq1mnvaqyaINYgTxuJ8FACelpMI27vAgfreCU
-4/NaZyTDAgMBAAECggEBAJJhDYSoVNn0EvqdZyV3iz0pnx9pnKG3AZ7LBkkeYK9J
-/gvdd9DpIrcnBfWuyv4cKbjAHqsyyNaO/YqARWPq7S8HJltAzl66hkn6ASlkI6GW
-NUQ8WxIpfXOg5VLaGr7n2YfSEvJ6jrXW8u8Jr6DvIg7TNuF+TU4y/Jkn5ksMulm2
-7lDM0ccemYPt6EGS8CNh9UxGGEuDFpz5C+FOYNu0l2TEP7dyxBBsQgKQ/ni53EVS
-mfSKFB42XqVp6uNFl4nuQGaRfJQTz+HoqM9yvGXx+4VbCwpvbWStuoPM9SSOjilG
-9sZrsT4BWfaN+k4bF6vkiPFTG9re8UXw7KuwldZWUrECgYEA3wLGp28GDZ4jdhhJ
-CU8PD4xqrJxGp/thGPL8PPeJK1ESdwePNcG8ejsDZtixgk6lkOuZaW0ISXTC2mCO
-YYCesass9zVfWkM3DgLWFO1DMlOLdu+qSHNA1/TaDG2P1C4q4C48Nlg7P6bvRv5q
-0lhzMe5HHxGY02LaHAaFgeeV3l0CgYEA3f8DsAT15LKmh9VWtZuvdd/ai6NV2WbM
-CQDtlF9X0kxqC0vOG+BemhcGVI5JUR8ajl5dhcLuV7xGJ6CxdDp6xG8rBx0cezs3
-kGwDeP368AeONudcJv6vHmOkWCkRMlQx1gTUt+rRIEV0WkvNYFIX73wBcaXHHkti
-am/596mPnZ8CgYBbJ6NTpQnwXwdXqi2QZIRfcqHX1Dj9SL8zl36K3RNwZT8K8EgV
-TQ9hVuXZEBHelY8PYX3fnfWZMOTEplsMd6pmLPXARkyndHn4fChNfX3OAGAtSWFt
-I88Jdsf59H6p2AUmhT+PZxkwt2duuWeoewb7Dc58YJD7Npi4g+Hma2bS8QKBgE/M
-iYDOZ62L4nzVXVPu4MWYcDDdx9BcOV/LK5u4IhOAUGY7G529q4PsXuQqOYSlj6A5
-n5ijl5WGIhnAk8lZ9COEao0mE8TgZnrNuPnXIksCDEcEJ4YE6uIbo0nliT70MO3j
-0qtCB2Z4UPjcYrkLCXuWsdYuZ0MmifwEwHAcTXm1AoGAW5OQ6WYm6dtfoO6XeGt7
-tphAIiKwtiIm2iyWr/wPOHF15F57X5RTq2G5QYvXLu6WVe6NIKY0/LT7Aa6h+E98
-bFk7yX/JgMIA8o81sFTeyjHrukl0JvlvyqO2y5KuQq8omMDoiGV83T+dJuD77HpF
-cZA3Drn6DYCB/ApOVxRIQYM=
------END PRIVATE KEY-----
+-----BEGIN RSA PRIVATE KEY-----
+MIIEpQIBAAKCAQEAvDVBeQvC7hVijs6jjWzgD2c2whjBvDDqAzUOs2Xk1JfD2TT+
+eVPP47cuK4ufB3EbfYwrgq/Jv1NRvstEDXp1Croof8E3oBWbR3sXVK8BAiwwRVLu
+Y95ApvqL8VkxXTSkp7hcE+dKAGJH3+m4T+0nxgasHhWYJO2wsJy9/dVL3cQN+tXv
+gzo7PZCX83dmiTDh2M9A+Uo8lSWb5YAhf8n2b3C4K+qLNhtGRpO33GfQ5XNkuRMT
+Lbwu7eUP0IjYdrt8LmUpgrWBWyGaQDUutisi5kv47yuK1d4o6q1LVHjvaFRtKKpi
+FQVZJCJMmdB9SI6QiOqFuyVCEM4MgzRtkRW4UwIDAQABAoIBAQCPfFqKGjlmoc8d
+6NQwAg1gMORCXfV1sCT4hP7MLqainYGmmwxXG1qm1QTSFgQL/GNk9/REEhjRUIhF
+2VnsnKuWng46N+hcl5xmhqVm3nT6Xw3+DBfK86p+ow0F12YXFQdjBt7MHc0BNext
+/RWTec6U3olh9jykCsJmI1mFp5PLYVg4OjJz6v0GdnkBv6CCuwv0Talz8vEX4js9
+AZvPAlCFR2rqmdAwpeHV/dk4x4ls04Hv8g1L40EhToBetfKOeT4PWA3Svg/71uGg
+6QqQi642quWXZQL255fP9crMYfj12AUbFe4+ET6/3wZkpFeNgifAbLY1lOfEhjD3
+ey7OjNhhAoGBAPUyoEpu8KDYgHM2b68yykmEjHXgpNGizsOrAV5kFbk7lTRYqoju
+jKDROzOOH79OU+emCz9WlVatCrSXZoVMEfCIVtSsuL19z492sk2eX3qGz0fRN6Os
+/z8K9QZ1fIAw+8W1QnwRRqZhRd7SiFLKrGY7huoq9KL8hqHx2Jw9KSlPAoGBAMR/
+5ERVShxS+ADfFtRoUMEd9kcFEleQiq4tWosyAxB27+f+Q8lAIKNjmVNE1F1RC/Fi
+h6BeQBbM6n9j5Q8+r8st7OYBpEu260teAKiE8GlB8s1D2s4oDvB5usvWnsl53gTU
+WdpP5/M2Ioze5fl/8dZXshGPb6gHMXqwSNPr+fe9AoGAG9yn2C1pDG3tkqnx4O+d
+iuMT7uUa9XNRmWxaGHa4/TZnCu60WiD5O+DqoD4bH2rwH9d/WbAmAhZhrAm0LZtq
+QnHLpBkIWQftyPiM5EMFyG9/KEL+1ot26Zv+IcDB5/Mo+NtS9bQk2g0dmmdD9Fxx
+YKCNARjmeYrGZaqMmZxdjAMCgYEAhXE8uVMaYyXNGfpmbJTy0lLgntZI4IJeS26t
+YH30Ksg6n9fCfPc5svu+chf6B+00KRb6d+PJrjI2xZA3TCUMCPUFPiW7R1fPbn1G
+AStWgISyuMbt3rbBfnmMa0UyzCwgpDL5WhKNuFL5H6V3k/pZZ3Bikx5Pe1J3PZRd
+wN0uAhkCgYEAm6PvhIWY8dtOIJZOKB+GcuSfFKJrvfWPL7Lb6gfq45ojsl7EoMiW
+h/uetqAYaAr4kQCZApSfrtwc5GeB8o93Xl6gFqM3Qo32wCITMaSrNRMuEtq1G9AX
+Q+rGXgPFsMMA8nV3QOMftBNWan5O74w24+4LDu4WQex7EAaiH8J+jkk=
+-----END RSA PRIVATE KEY-----
diff --git a/test/hostname/certindex b/test/hostname/certindex
index 764b6477a..a84dae079 100644
--- a/test/hostname/certindex
+++ b/test/hostname/certindex
@@ -1,2 +1 @@
V 180512061548Z 18 unknown /CN=Alice/ST=California/C=US/emailAddress=james@hashicorp.com/O=End Point/OU=Testing
-V 190516110846Z 19 unknown /CN=Alice/ST=California/C=US/emailAddress=james@hashicorp.com/O=End Point/OU=Testing
diff --git a/test/hostname/serialfile b/test/hostname/serialfile
index 268de3f3e..d6b24041c 100644
--- a/test/hostname/serialfile
+++ b/test/hostname/serialfile
@@ -1 +1 @@
-1A
+19
From 544acdf04eba759fee0aaa19dbcc500ea6e13963 Mon Sep 17 00:00:00 2001
From: Pierre Souchay
Date: Thu, 31 May 2018 18:15:52 +0200
Subject: [PATCH 8/8] Fixed comments for max DNS records returned as requested
by @mkeeler
---
agent/dns.go | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/agent/dns.go b/agent/dns.go
index 85c977768..524f99581 100644
--- a/agent/dns.go
+++ b/agent/dns.go
@@ -752,11 +752,12 @@ func (d *DNSServer) trimTCPResponse(req, resp *dns.Msg) (trimmed bool) {
originalSize := resp.Len()
originalNumRecords := len(resp.Answer)
- // Beyond 2500 records, performance gets bad
- // Limit the number of records at once, anyway, it won't fit in 64k
- // For SRV Records, the max is around 500 records, for A, less than 2k
+ // It is not possible to return more than 4k records even with compression
+ // Since we are performing binary search it is not a big deal, but it
+ // improves a bit performance, even with binary search
truncateAt := 4096
if req.Question[0].Qtype == dns.TypeSRV {
+ // More than 1024 SRV records do not fit in 64k
truncateAt = 1024
}
if len(resp.Answer) > truncateAt {