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 +// 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 } -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 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) +}