aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGravatar Miek Gieben <miek@miek.nl> 2018-08-29 12:26:22 +0100
committerGravatar GitHub <noreply@github.com> 2018-08-29 12:26:22 +0100
commitba1efee4f1c2258e43b1bd8035ac6d1208675b95 (patch)
tree17ec11d7616120357c2828b6374d02ab081c5e42
parenteb51e8bac90fac86d34c9e1cb89b04ea0936b034 (diff)
downloadcoredns-ba1efee4f1c2258e43b1bd8035ac6d1208675b95.tar.gz
coredns-ba1efee4f1c2258e43b1bd8035ac6d1208675b95.tar.zst
coredns-ba1efee4f1c2258e43b1bd8035ac6d1208675b95.zip
Default to scrubbing replies in the server (#2012)
Every plugin needs to deal with EDNS0 and should call Scrub to make a message fit the client's buffer. Move this functionality into the server and wrapping the ResponseWriter into a ScrubWriter that handles these bits for us. Result: Less code and faster, because multiple chained plugins could all be calling scrub and SizeAndDo - now there is just one place. Most tests in file/* and dnssec/* needed adjusting because in those unit tests you don't see OPT RRs anymore. The DNSSEC signer was also looking at the returned OPT RR to see if it needed to sign - as those are now added by the server (and thus later), this needed to change slightly. Scrub itself still exist (for backward compat reasons), but has been made a noop. Scrub has been renamed to scrub as it should not be used by external plugins. Fixes: #2010 Signed-off-by: Miek Gieben <miek@miek.nl>
-rw-r--r--core/dnsserver/server.go3
-rw-r--r--plugin/auto/auto.go2
-rw-r--r--plugin/cache/handler.go2
-rw-r--r--plugin/dnssec/dnssec.go21
-rw-r--r--plugin/dnssec/handler.go8
-rw-r--r--plugin/dnssec/handler_test.go14
-rw-r--r--plugin/dnssec/responsewriter.go12
-rw-r--r--plugin/etcd/handler.go2
-rw-r--r--plugin/etcd/stub_handler.go2
-rw-r--r--plugin/etcd/stub_test.go1
-rw-r--r--plugin/federation/federation.go5
-rw-r--r--plugin/file/delegation_test.go22
-rw-r--r--plugin/file/dname_test.go8
-rw-r--r--plugin/file/dnssec_test.go18
-rw-r--r--plugin/file/ent_test.go1
-rw-r--r--plugin/file/file.go2
-rw-r--r--plugin/file/glue_test.go5
-rw-r--r--plugin/file/wildcard_test.go4
-rw-r--r--plugin/forward/forward.go6
-rw-r--r--plugin/hosts/hosts.go2
-rw-r--r--plugin/kubernetes/handler.go2
-rw-r--r--plugin/proxy/dns.go4
-rw-r--r--plugin/route53/route53.go2
-rw-r--r--plugin/template/template.go2
-rw-r--r--request/request.go26
-rw-r--r--request/request_test.go25
-rw-r--r--request/writer.go20
27 files changed, 65 insertions, 156 deletions
diff --git a/core/dnsserver/server.go b/core/dnsserver/server.go
index 5242a6d2d..21a52f22c 100644
--- a/core/dnsserver/server.go
+++ b/core/dnsserver/server.go
@@ -237,6 +237,9 @@ func (s *Server) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
var dshandler *Config
+ // Wrap the response writer in a ScrubWriter so we automatically make the reply fit in the client's buffer.
+ w = request.NewScrubWriter(r, w)
+
for {
l := len(q[off:])
for i := 0; i < l; i++ {
diff --git a/plugin/auto/auto.go b/plugin/auto/auto.go
index f2d1ab97c..0092e6e00 100644
--- a/plugin/auto/auto.go
+++ b/plugin/auto/auto.go
@@ -84,8 +84,6 @@ func (a Auto) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i
return dns.RcodeServerFailure, nil
}
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
diff --git a/plugin/cache/handler.go b/plugin/cache/handler.go
index 11e1323f6..a44a4ec3b 100644
--- a/plugin/cache/handler.go
+++ b/plugin/cache/handler.go
@@ -31,8 +31,6 @@ func (c *Cache) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
if i != nil && found {
resp := i.toMsg(r, now)
- state.SizeAndDo(resp)
- resp, _ = state.Scrub(resp)
w.WriteMsg(resp)
if c.prefetch > 0 {
diff --git a/plugin/dnssec/dnssec.go b/plugin/dnssec/dnssec.go
index 3baea569c..1ebcb13af 100644
--- a/plugin/dnssec/dnssec.go
+++ b/plugin/dnssec/dnssec.go
@@ -46,21 +46,6 @@ func (d Dnssec) Sign(state request.Request, now time.Time, server string) *dns.M
mt, _ := response.Typify(req, time.Now().UTC()) // TODO(miek): need opt record here?
if mt == response.Delegation {
- // This reverts 11203e44. Reverting with git revert leads to conflicts in dnskey.go, and I'm
- // not sure yet if we just should fiddle with inserting DSs or not.
- // Easy way to, see #1211 for discussion.
- /*
- ttl := req.Ns[0].Header().Ttl
-
- ds := []dns.RR{}
- for i := range d.keys {
- ds = append(ds, d.keys[i].D)
- }
- if sigs, err := d.sign(ds, zone, ttl, incep, expir); err == nil {
- req.Ns = append(req.Ns, ds...)
- req.Ns = append(req.Ns, sigs...)
- }
- */
return req
}
@@ -98,7 +83,7 @@ func (d Dnssec) Sign(state request.Request, now time.Time, server string) *dns.M
for _, r := range rrSets(req.Extra) {
ttl := r[0].Header().Ttl
if sigs, err := d.sign(r, state.Zone, ttl, incep, expir, server); err == nil {
- req.Extra = append(sigs, req.Extra...) // prepend to leave OPT alone
+ req.Extra = append(req.Extra, sigs...)
}
}
return req
@@ -125,9 +110,7 @@ func (d Dnssec) sign(rrs []dns.RR, signerName string, ttl, incep, expir uint32,
return sigs.([]dns.RR), err
}
-func (d Dnssec) set(key uint32, sigs []dns.RR) {
- d.cache.Add(key, sigs)
-}
+func (d Dnssec) set(key uint32, sigs []dns.RR) { d.cache.Add(key, sigs) }
func (d Dnssec) get(key uint32, server string) ([]dns.RR, bool) {
if s, ok := d.cache.Get(key); ok {
diff --git a/plugin/dnssec/handler.go b/plugin/dnssec/handler.go
index 159c19533..573f7371d 100644
--- a/plugin/dnssec/handler.go
+++ b/plugin/dnssec/handler.go
@@ -41,8 +41,12 @@ func (d Dnssec) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
}
}
- drr := &ResponseWriter{w, d, server}
- return plugin.NextOrFailure(d.Name(), d.Next, ctx, drr, r)
+ if do {
+ drr := &ResponseWriter{w, d, server}
+ return plugin.NextOrFailure(d.Name(), d.Next, ctx, drr, r)
+ }
+
+ return plugin.NextOrFailure(d.Name(), d.Next, ctx, w, r)
}
var (
diff --git a/plugin/dnssec/handler_test.go b/plugin/dnssec/handler_test.go
index a1c35c635..ed9ddc5a5 100644
--- a/plugin/dnssec/handler_test.go
+++ b/plugin/dnssec/handler_test.go
@@ -56,7 +56,6 @@ var dnsTestCases = []test.Case{
test.NS("miek.nl. 1800 IN NS linode.atoom.net."),
test.RRSIG("miek.nl. 1800 IN RRSIG NS 13 2 3600 20161217114912 20161209084912 18512 miek.nl. ad9gA8VWgF1H8ze9/0Rk2Q=="),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
Qname: "www.miek.nl.", Qtype: dns.TypeAAAA, Do: true,
@@ -70,7 +69,6 @@ var dnsTestCases = []test.Case{
test.NS("miek.nl. 1800 IN NS linode.atoom.net."),
test.RRSIG("miek.nl. 1800 IN RRSIG NS 13 2 3600 20161217114912 20161209084912 18512 miek.nl. ad9gA8VWgF1H8ze9/0Rk2Q=="),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
Qname: "wwwww.miek.nl.", Qtype: dns.TypeAAAA, Do: true,
@@ -80,7 +78,6 @@ var dnsTestCases = []test.Case{
test.NSEC("wwwww.miek.nl. 1800 IN NSEC \\000.wwwww.miek.nl. A HINFO TXT LOC SRV CERT SSHFP RRSIG NSEC TLSA HIP OPENPGPKEY SPF"),
test.RRSIG("wwwww.miek.nl. 1800 IN RRSIG NSEC 13 3 3600 20171220135446 20171212105446 18512 miek.nl. cVUQWs8xw=="),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
Qname: "miek.nl.", Qtype: dns.TypeHINFO, Do: true,
@@ -90,12 +87,10 @@ var dnsTestCases = []test.Case{
test.RRSIG("miek.nl. 1800 IN RRSIG SOA 13 2 3600 20171220141741 20171212111741 18512 miek.nl. 8bLTReqmuQtw=="),
test.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
Qname: "www.example.org.", Qtype: dns.TypeAAAA, Do: true,
Rcode: dns.RcodeServerFailure,
- // Extra: []dns.RR{test.OPT(4096, true)}, // test.ErrorHandler is a simple handler that does not do EDNS on ServerFailure
},
}
@@ -110,20 +105,18 @@ func TestLookupZone(t *testing.T) {
defer rm2()
c := cache.New(defaultCap)
dh := New([]string{"miek.nl."}, []*DNSKEY{dnskey}, fm, c)
- ctx := context.TODO()
for _, tc := range dnsTestCases {
m := tc.Msg()
rec := dnstest.NewRecorder(&test.ResponseWriter{})
- _, err := dh.ServeDNS(ctx, rec, m)
+ _, err := dh.ServeDNS(context.TODO(), rec, m)
if err != nil {
t.Errorf("Expected no error, got %v\n", err)
return
}
- resp := rec.Msg
- test.SortAndCheck(t, resp, tc)
+ test.SortAndCheck(t, rec.Msg, tc)
}
}
@@ -133,13 +126,12 @@ func TestLookupDNSKEY(t *testing.T) {
defer rm2()
c := cache.New(defaultCap)
dh := New([]string{"miek.nl."}, []*DNSKEY{dnskey}, test.ErrorHandler(), c)
- ctx := context.TODO()
for _, tc := range dnssecTestCases {
m := tc.Msg()
rec := dnstest.NewRecorder(&test.ResponseWriter{})
- _, err := dh.ServeDNS(ctx, rec, m)
+ _, err := dh.ServeDNS(context.TODO(), rec, m)
if err != nil {
t.Errorf("Expected no error, got %v\n", err)
return
diff --git a/plugin/dnssec/responsewriter.go b/plugin/dnssec/responsewriter.go
index 0e4af8d1c..852e6f58f 100644
--- a/plugin/dnssec/responsewriter.go
+++ b/plugin/dnssec/responsewriter.go
@@ -28,12 +28,9 @@ func (d *ResponseWriter) WriteMsg(res *dns.Msg) error {
}
state.Zone = zone
- if state.Do() {
- res = d.d.Sign(state, time.Now().UTC(), d.server)
-
- cacheSize.WithLabelValues(d.server, "signature").Set(float64(d.d.cache.Len()))
- }
- state.SizeAndDo(res)
+ res = d.d.Sign(state, time.Now().UTC(), d.server)
+ cacheSize.WithLabelValues(d.server, "signature").Set(float64(d.d.cache.Len()))
+ // No need for EDNS0 trickery, as that is handled by the server.
return d.ResponseWriter.WriteMsg(res)
}
@@ -44,6 +41,3 @@ func (d *ResponseWriter) Write(buf []byte) (int, error) {
n, err := d.ResponseWriter.Write(buf)
return n, err
}
-
-// Hijack implements the dns.ResponseWriter interface.
-func (d *ResponseWriter) Hijack() { d.ResponseWriter.Hijack() }
diff --git a/plugin/etcd/handler.go b/plugin/etcd/handler.go
index b70684165..6a85c3473 100644
--- a/plugin/etcd/handler.go
+++ b/plugin/etcd/handler.go
@@ -86,8 +86,6 @@ func (e *Etcd) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
m.Answer = append(m.Answer, records...)
m.Extra = append(m.Extra, extra...)
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
diff --git a/plugin/etcd/stub_handler.go b/plugin/etcd/stub_handler.go
index 300e0a350..963554975 100644
--- a/plugin/etcd/stub_handler.go
+++ b/plugin/etcd/stub_handler.go
@@ -33,8 +33,6 @@ func (s Stub) ServeDNS(ctx context.Context, w dns.ResponseWriter, req *dns.Msg)
return dns.RcodeServerFailure, e
}
m.RecursionAvailable = true
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
diff --git a/plugin/etcd/stub_test.go b/plugin/etcd/stub_test.go
index c4a262b86..c01100bdf 100644
--- a/plugin/etcd/stub_test.go
+++ b/plugin/etcd/stub_test.go
@@ -83,6 +83,5 @@ var dnsTestCasesStub = []test.Case{
{
Qname: "example.net.", Qtype: dns.TypeA,
Answer: []dns.RR{test.A("example.net. 86400 IN A 93.184.216.34")},
- Extra: []dns.RR{test.OPT(4096, false)}, // This will have an EDNS0 section, because *we* added our local stub forward to detect loops.
},
}
diff --git a/plugin/federation/federation.go b/plugin/federation/federation.go
index 2e98875b9..e968aa668 100644
--- a/plugin/federation/federation.go
+++ b/plugin/federation/federation.go
@@ -85,8 +85,6 @@ func (f *Federation) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.
a.Header().Name = qname
}
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
w.WriteMsg(m)
return dns.RcodeSuccess, nil
@@ -107,10 +105,7 @@ func (f *Federation) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.
m.Answer = []dns.RR{service.NewCNAME(state.QName(), service.Host)}
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
w.WriteMsg(m)
-
return dns.RcodeSuccess, nil
}
diff --git a/plugin/file/delegation_test.go b/plugin/file/delegation_test.go
index 116b6b244..e51a600d7 100644
--- a/plugin/file/delegation_test.go
+++ b/plugin/file/delegation_test.go
@@ -73,8 +73,7 @@ var delegationTestCases = []test.Case{
var secureDelegationTestCases = []test.Case{
{
- Qname: "a.delegated.example.org.", Qtype: dns.TypeTXT,
- Do: true,
+ Qname: "a.delegated.example.org.", Qtype: dns.TypeTXT, Do: true,
Ns: []dns.RR{
test.DS("delegated.example.org. 1800 IN DS 10056 5 1 EE72CABD1927759CDDA92A10DBF431504B9E1F13"),
test.DS("delegated.example.org. 1800 IN DS 10056 5 2 E4B05F87725FA86D9A64F1E53C3D0E6250946599DFE639C45955B0ED416CDDFA"),
@@ -83,14 +82,12 @@ var secureDelegationTestCases = []test.Case{
test.RRSIG("delegated.example.org. 1800 IN RRSIG DS 13 3 1800 20161129153240 20161030153240 49035 example.org. rlNNzcUmtbjLSl02ZzQGUbWX75yCUx0Mug1jHtKVqRq1hpPE2S3863tIWSlz+W9wz4o19OI4jbznKKqk+DGKog=="),
},
Extra: []dns.RR{
- test.OPT(4096, true),
test.A("a.delegated.example.org. 1800 IN A 139.162.196.78"),
test.AAAA("a.delegated.example.org. 1800 IN AAAA 2a01:7e00::f03c:91ff:fef1:6735"),
},
},
{
- Qname: "delegated.example.org.", Qtype: dns.TypeNS,
- Do: true,
+ Qname: "delegated.example.org.", Qtype: dns.TypeNS, Do: true,
Ns: []dns.RR{
test.DS("delegated.example.org. 1800 IN DS 10056 5 1 EE72CABD1927759CDDA92A10DBF431504B9E1F13"),
test.DS("delegated.example.org. 1800 IN DS 10056 5 2 E4B05F87725FA86D9A64F1E53C3D0E6250946599DFE639C45955B0ED416CDDFA"),
@@ -99,14 +96,12 @@ var secureDelegationTestCases = []test.Case{
test.RRSIG("delegated.example.org. 1800 IN RRSIG DS 13 3 1800 20161129153240 20161030153240 49035 example.org. rlNNzcUmtbjLSl02ZzQGUbWX75yCUx0Mug1jHtKVqRq1hpPE2S3863tIWSlz+W9wz4o19OI4jbznKKqk+DGKog=="),
},
Extra: []dns.RR{
- test.OPT(4096, true),
test.A("a.delegated.example.org. 1800 IN A 139.162.196.78"),
test.AAAA("a.delegated.example.org. 1800 IN AAAA 2a01:7e00::f03c:91ff:fef1:6735"),
},
},
{
- Qname: "foo.delegated.example.org.", Qtype: dns.TypeA,
- Do: true,
+ Qname: "foo.delegated.example.org.", Qtype: dns.TypeA, Do: true,
Ns: []dns.RR{
test.DS("delegated.example.org. 1800 IN DS 10056 5 1 EE72CABD1927759CDDA92A10DBF431504B9E1F13"),
test.DS("delegated.example.org. 1800 IN DS 10056 5 2 E4B05F87725FA86D9A64F1E53C3D0E6250946599DFE639C45955B0ED416CDDFA"),
@@ -115,14 +110,12 @@ var secureDelegationTestCases = []test.Case{
test.RRSIG("delegated.example.org. 1800 IN RRSIG DS 13 3 1800 20161129153240 20161030153240 49035 example.org. rlNNzcUmtbjLSl02ZzQGUbWX75yCUx0Mug1jHtKVqRq1hpPE2S3863tIWSlz+W9wz4o19OI4jbznKKqk+DGKog=="),
},
Extra: []dns.RR{
- test.OPT(4096, true),
test.A("a.delegated.example.org. 1800 IN A 139.162.196.78"),
test.AAAA("a.delegated.example.org. 1800 IN AAAA 2a01:7e00::f03c:91ff:fef1:6735"),
},
},
{
- Qname: "foo.delegated.example.org.", Qtype: dns.TypeDS,
- Do: true,
+ Qname: "foo.delegated.example.org.", Qtype: dns.TypeDS, Do: true,
Ns: []dns.RR{
test.DS("delegated.example.org. 1800 IN DS 10056 5 1 EE72CABD1927759CDDA92A10DBF431504B9E1F13"),
test.DS("delegated.example.org. 1800 IN DS 10056 5 2 E4B05F87725FA86D9A64F1E53C3D0E6250946599DFE639C45955B0ED416CDDFA"),
@@ -131,14 +124,12 @@ var secureDelegationTestCases = []test.Case{
test.RRSIG("delegated.example.org. 1800 IN RRSIG DS 13 3 1800 20161129153240 20161030153240 49035 example.org. rlNNzcUmtbjLSl02ZzQGUbWX75yCUx0Mug1jHtKVqRq1hpPE2S3863tIWSlz+W9wz4o19OI4jbznKKqk+DGKog=="),
},
Extra: []dns.RR{
- test.OPT(4096, true),
test.A("a.delegated.example.org. 1800 IN A 139.162.196.78"),
test.AAAA("a.delegated.example.org. 1800 IN AAAA 2a01:7e00::f03c:91ff:fef1:6735"),
},
},
{
- Qname: "delegated.example.org.", Qtype: dns.TypeDS,
- Do: true,
+ Qname: "delegated.example.org.", Qtype: dns.TypeDS, Do: true,
Answer: []dns.RR{
test.DS("delegated.example.org. 1800 IN DS 10056 5 1 EE72CABD1927759CDDA92A10DBF431504B9E1F13"),
test.DS("delegated.example.org. 1800 IN DS 10056 5 2 E4B05F87725FA86D9A64F1E53C3D0E6250946599DFE639C45955B0ED416CDDFA"),
@@ -149,9 +140,6 @@ var secureDelegationTestCases = []test.Case{
test.NS("example.org. 1800 IN NS b.iana-servers.net."),
test.RRSIG("example.org. 1800 IN RRSIG NS 13 2 1800 20161129153240 20161030153240 49035 example.org. llrHoIuw="),
},
- Extra: []dns.RR{
- test.OPT(4096, true),
- },
},
}
diff --git a/plugin/file/dname_test.go b/plugin/file/dname_test.go
index 9dd2c2e24..85dc9d360 100644
--- a/plugin/file/dname_test.go
+++ b/plugin/file/dname_test.go
@@ -122,23 +122,19 @@ var dnameDnssecTestCases = []test.Case{
},
},
{
- Qname: "dname.example.org.", Qtype: dns.TypeDNAME,
- Do: true,
+ Qname: "dname.example.org.", Qtype: dns.TypeDNAME, Do: true,
Answer: []dns.RR{
test.DNAME("dname.example.org. 1800 IN DNAME test.example.org."),
test.RRSIG("dname.example.org. 1800 IN RRSIG DNAME 5 3 1800 20170702091734 20170602091734 54282 example.org. HvXtiBM="),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
- Qname: "a.dname.example.org.", Qtype: dns.TypeA,
- Do: true,
+ Qname: "a.dname.example.org.", Qtype: dns.TypeA, Do: true,
Answer: []dns.RR{
test.CNAME("a.dname.example.org. 1800 IN CNAME a.test.example.org."),
test.DNAME("dname.example.org. 1800 IN DNAME test.example.org."),
test.RRSIG("dname.example.org. 1800 IN RRSIG DNAME 5 3 1800 20170702091734 20170602091734 54282 example.org. HvXtiBM="),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
}
diff --git a/plugin/file/dnssec_test.go b/plugin/file/dnssec_test.go
index 29cd9a61e..fee39a37a 100644
--- a/plugin/file/dnssec_test.go
+++ b/plugin/file/dnssec_test.go
@@ -11,6 +11,7 @@ import (
"github.com/miekg/dns"
)
+// All OPT RR are added in server.go, so we don't specify them in the unit tests.
var dnssecTestCases = []test.Case{
{
Qname: "miek.nl.", Qtype: dns.TypeSOA, Do: true,
@@ -18,8 +19,7 @@ var dnssecTestCases = []test.Case{
test.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="),
test.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
},
- Ns: auth,
- Extra: []dns.RR{test.OPT(4096, true)},
+ Ns: auth,
},
{
Qname: "miek.nl.", Qtype: dns.TypeAAAA, Do: true,
@@ -27,8 +27,7 @@ var dnssecTestCases = []test.Case{
test.AAAA("miek.nl. 1800 IN AAAA 2a01:7e00::f03c:91ff:fef1:6735"),
test.RRSIG("miek.nl. 1800 IN RRSIG AAAA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. SsRT="),
},
- Ns: auth,
- Extra: []dns.RR{test.OPT(4096, true)},
+ Ns: auth,
},
{
Qname: "miek.nl.", Qtype: dns.TypeNS, Do: true,
@@ -39,7 +38,6 @@ var dnssecTestCases = []test.Case{
test.NS("miek.nl. 1800 IN NS omval.tednet.nl."),
test.RRSIG("miek.nl. 1800 IN RRSIG NS 8 2 1800 20160426031301 20160327031301 12051 miek.nl. ZLtsQhwaz+lHfNpztFoR1Vxs="),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
Qname: "miek.nl.", Qtype: dns.TypeMX, Do: true,
@@ -51,8 +49,7 @@ var dnssecTestCases = []test.Case{
test.MX("miek.nl. 1800 IN MX 5 alt2.aspmx.l.google.com."),
test.RRSIG("miek.nl. 1800 IN RRSIG MX 8 2 1800 20160426031301 20160327031301 12051 miek.nl. kLqG+iOr="),
},
- Ns: auth,
- Extra: []dns.RR{test.OPT(4096, true)},
+ Ns: auth,
},
{
Qname: "www.miek.nl.", Qtype: dns.TypeA, Do: true,
@@ -63,9 +60,6 @@ var dnssecTestCases = []test.Case{
test.RRSIG("www.miek.nl. 1800 RRSIG CNAME 8 3 1800 20160426031301 20160327031301 12051 miek.nl. NVZmMJaypS+wDL2Lar4Zw1zF"),
},
Ns: auth,
- Extra: []dns.RR{
- test.OPT(4096, true),
- },
},
{
// NoData
@@ -76,7 +70,6 @@ var dnssecTestCases = []test.Case{
test.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="),
test.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
Qname: "b.miek.nl.", Qtype: dns.TypeA, Do: true,
@@ -89,7 +82,6 @@ var dnssecTestCases = []test.Case{
test.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="),
test.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
Qname: "b.blaat.miek.nl.", Qtype: dns.TypeA, Do: true,
@@ -102,7 +94,6 @@ var dnssecTestCases = []test.Case{
test.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="),
test.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
Qname: "b.a.miek.nl.", Qtype: dns.TypeA, Do: true,
@@ -114,7 +105,6 @@ var dnssecTestCases = []test.Case{
test.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160426031301 20160327031301 12051 miek.nl. FIrzy07acBbtyQczy1dc="),
test.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
}
diff --git a/plugin/file/ent_test.go b/plugin/file/ent_test.go
index 496d1a727..4ff95f330 100644
--- a/plugin/file/ent_test.go
+++ b/plugin/file/ent_test.go
@@ -26,7 +26,6 @@ var entTestCases = []test.Case{
test.RRSIG("miek.nl. 1800 IN RRSIG SOA 8 2 1800 20160502144311 20160402144311 12051 miek.nl. KegoBxA3Tbrhlc4cEdkRiteIkOfsq"),
test.SOA("miek.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1282630057 14400 3600 604800 14400"),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
}
diff --git a/plugin/file/file.go b/plugin/file/file.go
index f2294fa53..5c13042cb 100644
--- a/plugin/file/file.go
+++ b/plugin/file/file.go
@@ -98,8 +98,6 @@ func (f File) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (i
return dns.RcodeServerFailure, nil
}
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
diff --git a/plugin/file/glue_test.go b/plugin/file/glue_test.go
index 9cb71a993..e6f1e027f 100644
--- a/plugin/file/glue_test.go
+++ b/plugin/file/glue_test.go
@@ -11,8 +11,7 @@ import (
"github.com/miekg/dns"
)
-// another personal zone (helps in testing as my secondary is NSD
-// atoom = atom in English.
+// another personal zone (helps in testing as my secondary is NSD, atoom = atom in English.
var atoomTestCases = []test.Case{
{
Qname: atoom, Qtype: dns.TypeNS, Do: true,
@@ -23,7 +22,7 @@ var atoomTestCases = []test.Case{
test.RRSIG("atoom.net. 1800 IN RRSIG NS 8 2 1800 20170112031301 20161213031301 53289 atoom.net. DLe+G1 jlw="),
},
Extra: []dns.RR{
- test.OPT(4096, true),
+ // test.OPT(4096, true), // added by server, not test in this unit test.
test.A("linode.atoom.net. 1800 IN A 176.58.119.54"),
test.AAAA("linode.atoom.net. 1800 IN AAAA 2a01:7e00::f03c:91ff:fe79:234c"),
test.RRSIG("linode.atoom.net. 1800 IN RRSIG A 8 3 1800 20170112031301 20161213031301 53289 atoom.net. Z4Ka4OLDoyxj72CL vkI="),
diff --git a/plugin/file/wildcard_test.go b/plugin/file/wildcard_test.go
index 8f73d1543..314b699c6 100644
--- a/plugin/file/wildcard_test.go
+++ b/plugin/file/wildcard_test.go
@@ -11,6 +11,7 @@ import (
"github.com/miekg/dns"
)
+// these examples don't have an additional opt RR set, because that's gets added by the server.
var wildcardTestCases = []test.Case{
{
Qname: "wild.dnssex.nl.", Qtype: dns.TypeTXT,
@@ -36,7 +37,6 @@ var wildcardTestCases = []test.Case{
test.NSEC("a.dnssex.nl. 14400 IN NSEC www.dnssex.nl. A AAAA RRSIG NSEC"),
test.RRSIG("a.dnssex.nl. 14400 IN RRSIG NSEC 8 3 14400 20160428190224 20160329190224 14460 dnssex.nl. S+UMs2ySgRaaRY"),
}, dnssexAuth...),
- Extra: []dns.RR{test.OPT(4096, true)},
},
{
Qname: "a.wild.dnssex.nl.", Qtype: dns.TypeTXT, Do: true,
@@ -48,7 +48,6 @@ var wildcardTestCases = []test.Case{
test.NSEC("a.dnssex.nl. 14400 IN NSEC www.dnssex.nl. A AAAA RRSIG NSEC"),
test.RRSIG("a.dnssex.nl. 14400 IN RRSIG NSEC 8 3 14400 20160428190224 20160329190224 14460 dnssex.nl. S+UMs2ySgRaaRY"),
}, dnssexAuth...),
- Extra: []dns.RR{test.OPT(4096, true)},
},
// nodata responses
{
@@ -66,7 +65,6 @@ var wildcardTestCases = []test.Case{
test.RRSIG(`dnssex.nl. 1800 IN RRSIG SOA 8 2 1800 20160428190224 20160329190224 14460 dnssex.nl. CA/Y3m9hCOiKC/8ieSOv8SeP964Bq++lyH8BZJcTaabAsERs4xj5PRtcxicwQXZiF8fYUCpROlUS0YR8Cdw=`),
test.SOA(`dnssex.nl. 1800 IN SOA linode.atoom.net. miek.miek.nl. 1459281744 14400 3600 604800 14400`),
},
- Extra: []dns.RR{test.OPT(4096, true)},
},
}
diff --git a/plugin/forward/forward.go b/plugin/forward/forward.go
index 8e64831f4..2b6a3f705 100644
--- a/plugin/forward/forward.go
+++ b/plugin/forward/forward.go
@@ -148,13 +148,7 @@ func (f *Forward) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
return 0, nil
}
- // When using force_tcp the upstream can send a message that is too big for
- // the udp buffer, hence we need to truncate the message to at least make it
- // fit the udp buffer.
- ret, _ = state.Scrub(ret)
-
w.WriteMsg(ret)
-
return 0, nil
}
diff --git a/plugin/hosts/hosts.go b/plugin/hosts/hosts.go
index c9ce163c9..4041b384c 100644
--- a/plugin/hosts/hosts.go
+++ b/plugin/hosts/hosts.go
@@ -66,8 +66,6 @@ func (h Hosts) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (
m.Authoritative, m.RecursionAvailable = true, true
m.Answer = answers
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
diff --git a/plugin/kubernetes/handler.go b/plugin/kubernetes/handler.go
index c02bdedf9..bf69c7521 100644
--- a/plugin/kubernetes/handler.go
+++ b/plugin/kubernetes/handler.go
@@ -78,8 +78,6 @@ func (k Kubernetes) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.M
m.Answer = append(m.Answer, records...)
m.Extra = append(m.Extra, extra...)
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
diff --git a/plugin/proxy/dns.go b/plugin/proxy/dns.go
index d3153bdff..c1aa7f190 100644
--- a/plugin/proxy/dns.go
+++ b/plugin/proxy/dns.go
@@ -64,10 +64,6 @@ func (d *dnsEx) Exchange(ctx context.Context, addr string, state request.Request
return nil, err
}
reply.Id = state.Req.Id
- // When using force_tcp the upstream can send a message that is too big for
- // the udp buffer, hence we need to truncate the message to at least make it
- // fit the udp buffer.
- reply, _ = state.Scrub(reply)
return reply, nil
}
diff --git a/plugin/route53/route53.go b/plugin/route53/route53.go
index f5c574e01..9629e2787 100644
--- a/plugin/route53/route53.go
+++ b/plugin/route53/route53.go
@@ -63,8 +63,6 @@ func (rr Route53) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
m.Authoritative, m.RecursionAvailable = true, true
m.Answer = answers
- state.SizeAndDo(m)
- m, _ = state.Scrub(m)
w.WriteMsg(m)
return dns.RcodeSuccess, nil
}
diff --git a/plugin/template/template.go b/plugin/template/template.go
index 0bec0000f..c25a0d242 100644
--- a/plugin/template/template.go
+++ b/plugin/template/template.go
@@ -104,8 +104,6 @@ func (h Handler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg)
msg.Ns = append(msg.Ns, rr)
}
- state.SizeAndDo(msg)
- state.Scrub(msg)
w.WriteMsg(msg)
return template.rcode, nil
}
diff --git a/request/request.go b/request/request.go
index bcf6570be..c4e4eea3c 100644
--- a/request/request.go
+++ b/request/request.go
@@ -226,19 +226,11 @@ func (r *Request) SizeAndDo(m *dns.Msg) bool {
return true
}
-// Result is the result of Scrub.
-type Result int
-
-const (
- // ScrubIgnored is returned when Scrub did nothing to the message.
- ScrubIgnored Result = iota
- // ScrubExtra is returned when the reply has been scrubbed by removing RRs from the additional section.
- ScrubExtra
- // ScrubAnswer is returned when the reply has been scrubbed by removing RRs from the answer section.
- ScrubAnswer
-)
+// Scrub is a noop function, added for backwards compatibility reasons. The original Scrub is now called
+// automatically by the server on writing the reply. See ScrubWriter.
+func (r *Request) Scrub(reply *dns.Msg) (*dns.Msg, int) { return reply, 0 }
-// Scrub scrubs the reply message so that it will fit the client's buffer. It will first
+// scrub scrubs the reply message so that it will fit the client's buffer. It will first
// check if the reply fits without compression and then *with* compression.
// Scrub will then use binary search to find a save cut off point in the additional section.
// If even *without* the additional section the reply still doesn't fit we
@@ -246,19 +238,19 @@ const (
// we set the TC bit on the reply; indicating the client should retry over TCP.
// Note, the TC bit will be set regardless of protocol, even TCP message will
// get the bit, the client should then retry with pigeons.
-func (r *Request) Scrub(reply *dns.Msg) (*dns.Msg, Result) {
+func (r *Request) scrub(reply *dns.Msg) *dns.Msg {
size := r.Size()
reply.Compress = false
rl := reply.Len()
if size >= rl {
- return reply, ScrubIgnored
+ return reply
}
reply.Compress = true
rl = reply.Len()
if size >= rl {
- return reply, ScrubIgnored
+ return reply
}
// Account for the OPT record that gets added in SizeAndDo(), subtract that length.
@@ -298,7 +290,7 @@ func (r *Request) Scrub(reply *dns.Msg) (*dns.Msg, Result) {
if rl < size {
r.SizeAndDo(reply)
- return reply, ScrubExtra
+ return reply
}
ra := len(reply.Answer)
@@ -330,7 +322,7 @@ func (r *Request) Scrub(reply *dns.Msg) (*dns.Msg, Result) {
r.SizeAndDo(reply)
reply.Truncated = true
- return reply, ScrubAnswer
+ return reply
}
// Type returns the type of the question as a string. If the request is malformed the empty string is returned.
diff --git a/request/request_test.go b/request/request_test.go
index cad2dce0d..6685ad3b3 100644
--- a/request/request_test.go
+++ b/request/request_test.go
@@ -73,10 +73,7 @@ func TestRequestScrubAnswer(t *testing.T) {
fmt.Sprintf("large.example.com. 10 IN SRV 0 0 80 10-0-0-%d.default.pod.k8s.example.com.", i)))
}
- _, got := req.Scrub(reply)
- if want := ScrubAnswer; want != got {
- t.Errorf("Want scrub result %d, got %d", want, got)
- }
+ req.scrub(reply)
if want, got := req.Size(), reply.Len(); want < got {
t.Errorf("Want scrub to reduce message length below %d bytes, got %d bytes", want, got)
}
@@ -97,10 +94,7 @@ func TestRequestScrubExtra(t *testing.T) {
fmt.Sprintf("large.example.com. 10 IN SRV 0 0 80 10-0-0-%d.default.pod.k8s.example.com.", i)))
}
- _, got := req.Scrub(reply)
- if want := ScrubExtra; want != got {
- t.Errorf("Want scrub result %d, got %d", want, got)
- }
+ req.scrub(reply)
if want, got := req.Size(), reply.Len(); want < got {
t.Errorf("Want scrub to reduce message length below %d bytes, got %d bytes", want, got)
}
@@ -122,10 +116,7 @@ func TestRequestScrubExtraEdns0(t *testing.T) {
fmt.Sprintf("large.example.com. 10 IN SRV 0 0 80 10-0-0-%d.default.pod.k8s.example.com.", i)))
}
- _, got := req.Scrub(reply)
- if want := ScrubExtra; want != got {
- t.Errorf("Want scrub result %d, got %d", want, got)
- }
+ req.scrub(reply)
if want, got := req.Size(), reply.Len(); want < got {
t.Errorf("Want scrub to reduce message length below %d bytes, got %d bytes", want, got)
}
@@ -155,10 +146,7 @@ func TestRequestScrubExtraRegression(t *testing.T) {
fmt.Sprintf("10-0-0-%d.default.pod.k8s.example.com. 10 IN A 10.0.0.%d", i, i)))
}
- _, got := req.Scrub(reply)
- if want := ScrubExtra; want != got {
- t.Errorf("Want scrub result %d, got %d", want, got)
- }
+ reply = req.scrub(reply)
if want, got := req.Size(), reply.Len(); want < got {
t.Errorf("Want scrub to reduce message length below %d bytes, got %d bytes", want, got)
}
@@ -183,10 +171,7 @@ func TestRequestScrubAnswerExact(t *testing.T) {
reply.Answer = append(reply.Answer, test.A(fmt.Sprintf("large.example.com. 10 IN A 127.0.0.%d", i)))
}
- _, got := req.Scrub(reply)
- if want := ScrubAnswer; want != got {
- t.Errorf("Want scrub result %d, got %d", want, got)
- }
+ req.scrub(reply)
if want, got := req.Size(), reply.Len(); want < got {
t.Errorf("Want scrub to reduce message length below %d bytes, got %d bytes", want, got)
}
diff --git a/request/writer.go b/request/writer.go
new file mode 100644
index 000000000..ef0c14417
--- /dev/null
+++ b/request/writer.go
@@ -0,0 +1,20 @@
+package request
+
+import "github.com/miekg/dns"
+
+// ScrubWriter will, when writing the message, call scrub to make it fit the client's buffer.
+type ScrubWriter struct {
+ dns.ResponseWriter
+ req *dns.Msg // original request
+}
+
+// NewScrubWriter returns a new and initialized ScrubWriter.
+func NewScrubWriter(req *dns.Msg, w dns.ResponseWriter) *ScrubWriter { return &ScrubWriter{w, req} }
+
+// WriteMsg overrides the default implementation of the underlaying dns.ResponseWriter and calls
+// scrub on the message m and will then write it to the client.
+func (s *ScrubWriter) WriteMsg(m *dns.Msg) error {
+ state := Request{Req: s.req, W: s.ResponseWriter}
+ new, _ := state.Scrub(m)
+ return s.ResponseWriter.WriteMsg(new)
+}