forked from coredns/coredns
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Added minimal-responses plugin (coredns#4417)
* Added minimal-responses plugin Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com> * Removed unnecessary comments * Updated tests Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com> * Reformated imports Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com> * Updated package name Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com> * Removed unnecessary comments Co-authored-by: Miek Gieben <miek@miek.nl> * Added changes Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com> * updated Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com> * Updated comment for NextOrFailure Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com> * Updated to test.Case for testing Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com> * Formated imports using goimports Signed-off-by: Soumya Ghosh Dastidar <gdsoumya@gmail.com> Co-authored-by: Miek Gieben <miek@miek.nl>
- Loading branch information
Showing
9 changed files
with
289 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
# minimal | ||
|
||
## Name | ||
|
||
*minimal* - minimizes size of the DNS response message whenever possible. | ||
|
||
## Description | ||
|
||
The *minimal* plugin tries to minimize the size of the response. Depending on the response type it | ||
removes resource records from the AUTHORITY and ADDITIONAL sections. | ||
|
||
Specifically this plugin looks at successful responses (this excludes negative responses, i.e. | ||
nodata or name error). If the successful response isn't a delegation only the RRs in the answer | ||
section are written to the client. | ||
|
||
## Syntax | ||
|
||
~~~ txt | ||
minimal | ||
~~~ | ||
|
||
## Examples | ||
|
||
Enable minimal responses: | ||
|
||
~~~ corefile | ||
example.org { | ||
whoami | ||
forward . 8.8.8.8 | ||
minimal | ||
} | ||
~~~ | ||
|
||
## See Also | ||
|
||
[BIND 9 Configuration Reference](https://bind9.readthedocs.io/en/latest/reference.html#boolean-options) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package minimal | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"time" | ||
|
||
"github.com/coredns/coredns/plugin" | ||
"github.com/coredns/coredns/plugin/pkg/nonwriter" | ||
"github.com/coredns/coredns/plugin/pkg/response" | ||
"github.com/miekg/dns" | ||
) | ||
|
||
// minimalHandler implements the plugin.Handler interface. | ||
type minimalHandler struct { | ||
Next plugin.Handler | ||
} | ||
|
||
func (m *minimalHandler) Name() string { return "minimal" } | ||
|
||
func (m *minimalHandler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { | ||
nw := nonwriter.New(w) | ||
|
||
rcode, err := plugin.NextOrFailure(m.Name(), m.Next, ctx, nw, r) | ||
if err != nil { | ||
return rcode, err | ||
} | ||
|
||
ty, _ := response.Typify(nw.Msg, time.Now().UTC()) | ||
cl := response.Classify(ty) | ||
|
||
// if response is Denial or Error pass through also if the type is Delegation pass through | ||
if cl == response.Denial || cl == response.Error || ty == response.Delegation { | ||
w.WriteMsg(nw.Msg) | ||
return 0, nil | ||
} | ||
if ty != response.NoError { | ||
w.WriteMsg(nw.Msg) | ||
return 0, plugin.Error("minimal", fmt.Errorf("unhandled response type %q for %q", ty, nw.Msg.Question[0].Name)) | ||
} | ||
|
||
// copy over the original Msg params, deep copy not required as RRs are not modified | ||
d := &dns.Msg{ | ||
MsgHdr: nw.Msg.MsgHdr, | ||
Compress: nw.Msg.Compress, | ||
Question: nw.Msg.Question, | ||
Answer: nw.Msg.Answer, | ||
Ns: nil, | ||
Extra: nil, | ||
} | ||
|
||
w.WriteMsg(d) | ||
return 0, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,152 @@ | ||
package minimal | ||
|
||
import ( | ||
"context" | ||
"testing" | ||
|
||
"github.com/coredns/coredns/plugin" | ||
"github.com/coredns/coredns/plugin/pkg/dnstest" | ||
"github.com/coredns/coredns/plugin/test" | ||
"github.com/miekg/dns" | ||
) | ||
|
||
// testHandler implements plugin.Handler and will be used to create a stub handler for the test | ||
type testHandler struct { | ||
Response *test.Case | ||
Next plugin.Handler | ||
} | ||
|
||
func (t *testHandler) Name() string { return "test-handler" } | ||
|
||
func (t *testHandler) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg) (int, error) { | ||
d := new(dns.Msg) | ||
d.SetReply(r) | ||
if t.Response != nil { | ||
d.Answer = t.Response.Answer | ||
d.Ns = t.Response.Ns | ||
d.Extra = t.Response.Extra | ||
d.Rcode = t.Response.Rcode | ||
} | ||
w.WriteMsg(d) | ||
return 0, nil | ||
} | ||
|
||
func TestMinimizeResponse(t *testing.T) { | ||
baseAnswer := []dns.RR{ | ||
test.A("example.com. 293 IN A 142.250.76.46"), | ||
} | ||
baseNs := []dns.RR{ | ||
test.NS("example.com. 157127 IN NS ns2.example.com."), | ||
test.NS("example.com. 157127 IN NS ns1.example.com."), | ||
test.NS("example.com. 157127 IN NS ns3.example.com."), | ||
test.NS("example.com. 157127 IN NS ns4.example.com."), | ||
} | ||
|
||
baseExtra := []dns.RR{ | ||
test.A("ns2.example.com. 316273 IN A 216.239.34.10"), | ||
test.AAAA("ns2.example.com. 157127 IN AAAA 2001:4860:4802:34::a"), | ||
test.A("ns3.example.com. 316274 IN A 216.239.36.10"), | ||
test.AAAA("ns3.example.com. 157127 IN AAAA 2001:4860:4802:36::a"), | ||
test.A("ns1.example.com. 165555 IN A 216.239.32.10"), | ||
test.AAAA("ns1.example.com. 165555 IN AAAA 2001:4860:4802:32::a"), | ||
test.A("ns4.example.com. 190188 IN A 216.239.38.10"), | ||
test.AAAA("ns4.example.com. 157127 IN AAAA 2001:4860:4802:38::a"), | ||
} | ||
|
||
tests := []struct { | ||
active bool | ||
original test.Case | ||
minimal test.Case | ||
}{ | ||
{ // minimization possible NoError case | ||
original: test.Case{ | ||
Answer: baseAnswer, | ||
Ns: nil, | ||
Extra: baseExtra, | ||
Rcode: 0, | ||
}, | ||
minimal: test.Case{ | ||
Answer: baseAnswer, | ||
Ns: nil, | ||
Extra: nil, | ||
Rcode: 0, | ||
}, | ||
}, | ||
{ // delegate response case | ||
original: test.Case{ | ||
Answer: nil, | ||
Ns: baseNs, | ||
Extra: baseExtra, | ||
Rcode: 0, | ||
}, | ||
minimal: test.Case{ | ||
Answer: nil, | ||
Ns: baseNs, | ||
Extra: baseExtra, | ||
Rcode: 0, | ||
}, | ||
}, { // negative response case | ||
original: test.Case{ | ||
Answer: baseAnswer, | ||
Ns: baseNs, | ||
Extra: baseExtra, | ||
Rcode: 2, | ||
}, | ||
minimal: test.Case{ | ||
Answer: baseAnswer, | ||
Ns: baseNs, | ||
Extra: baseExtra, | ||
Rcode: 2, | ||
}, | ||
}, | ||
} | ||
|
||
for i, tc := range tests { | ||
req := new(dns.Msg) | ||
req.SetQuestion("example.com", dns.TypeA) | ||
|
||
tHandler := &testHandler{ | ||
Response: &tc.original, | ||
Next: nil, | ||
} | ||
o := &minimalHandler{Next: tHandler} | ||
rec := dnstest.NewRecorder(&test.ResponseWriter{}) | ||
_, err := o.ServeDNS(context.TODO(), rec, req) | ||
|
||
if err != nil { | ||
t.Errorf("Expected no error, but got %q", err) | ||
} | ||
|
||
if len(tc.minimal.Answer) != len(rec.Msg.Answer) { | ||
t.Errorf("Test %d: Expected %d Answer, but got %d", i, len(tc.minimal.Answer), len(req.Answer)) | ||
continue | ||
} | ||
if len(tc.minimal.Ns) != len(rec.Msg.Ns) { | ||
t.Errorf("Test %d: Expected %d Ns, but got %d", i, len(tc.minimal.Ns), len(req.Ns)) | ||
continue | ||
} | ||
|
||
if len(tc.minimal.Extra) != len(rec.Msg.Extra) { | ||
t.Errorf("Test %d: Expected %d Extras, but got %d", i, len(tc.minimal.Extra), len(req.Extra)) | ||
continue | ||
} | ||
|
||
for j, a := range rec.Msg.Answer { | ||
if tc.minimal.Answer[j].String() != a.String() { | ||
t.Errorf("Test %d: Expected Answer %d to be %v, but got %v", i, j, tc.minimal.Answer[j], a) | ||
} | ||
} | ||
|
||
for j, a := range rec.Msg.Ns { | ||
if tc.minimal.Ns[j].String() != a.String() { | ||
t.Errorf("Test %d: Expected NS %d to be %v, but got %v", i, j, tc.minimal.Ns[j], a) | ||
} | ||
} | ||
|
||
for j, a := range rec.Msg.Extra { | ||
if tc.minimal.Extra[j].String() != a.String() { | ||
t.Errorf("Test %d: Expected Extra %d to be %v, but got %v", i, j, tc.minimal.Extra[j], a) | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
package minimal | ||
|
||
import ( | ||
"github.com/coredns/caddy" | ||
"github.com/coredns/coredns/core/dnsserver" | ||
"github.com/coredns/coredns/plugin" | ||
) | ||
|
||
func init() { | ||
plugin.Register("minimal", setup) | ||
} | ||
|
||
func setup(c *caddy.Controller) error { | ||
c.Next() | ||
if c.NextArg() { | ||
return plugin.Error("minimal", c.ArgErr()) | ||
} | ||
|
||
dnsserver.GetConfig(c).AddPlugin(func(next plugin.Handler) plugin.Handler { | ||
return &minimalHandler{Next: next} | ||
}) | ||
|
||
return nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
package minimal | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/coredns/caddy" | ||
) | ||
|
||
func TestSetup(t *testing.T) { | ||
c := caddy.NewTestController("dns", `minimal-response`) | ||
if err := setup(c); err != nil { | ||
t.Fatalf("Expected no errors, but got: %v", err) | ||
} | ||
|
||
c = caddy.NewTestController("dns", `minimal-response example.org`) | ||
if err := setup(c); err == nil { | ||
t.Fatalf("Expected errors, but got: %v", err) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters