RFC 1996 allows SOA in answer in notify (#900)

* RFC 1996 allows SOA in answer in notify

The answer section of a notify can contain a SOA record that we should
not ignore in the DefaultAcceptFunc.

* End sentence

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben 2019-01-12 10:11:11 +00:00 committed by GitHub
parent 5beb962416
commit 5c2ec9f7e4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 39 additions and 4 deletions

View File

@ -10,7 +10,7 @@ type MsgAcceptFunc func(dh Header) MsgAcceptAction
// * opcode isn't OpcodeQuery or OpcodeNotify
// * Zero bit isn't zero
// * has more than 1 question in the question section
// * has more than 0 RRs in the Answer section
// * has more than 1 RR in the Answer section
// * has more than 0 RRs in the Authority section
// * has more than 2 RRs in the Additional section
var DefaultMsgAcceptFunc MsgAcceptFunc = defaultMsgAcceptFunc
@ -41,11 +41,11 @@ func defaultMsgAcceptFunc(dh Header) MsgAcceptAction {
if dh.Qdcount != 1 {
return MsgReject
}
if dh.Ancount != 0 {
// NOTIFY requests can have a SOA in the ANSWER section. See RFC 1996 Section 3.7 and 3.11.
if dh.Ancount > 1 {
return MsgReject
}
// IXFR request could have one SOA RR in the NS section
// RFC 1995, section 3
// IXFR request could have one SOA RR in the NS section. See RFC 1995, section 3.
if dh.Nscount > 1 {
return MsgReject
}

35
acceptfunc_test.go Normal file
View File

@ -0,0 +1,35 @@
package dns
import (
"testing"
)
func TestAcceptNotify(t *testing.T) {
HandleFunc("example.org.", handleNotify)
s, addrstr, err := RunLocalUDPServer(":0")
if err != nil {
t.Fatalf("unable to run test server: %v", err)
}
defer s.Shutdown()
m := new(Msg)
m.SetNotify("example.org.")
// Set a SOA hint in the answer section, this is allowed according to RFC 1996.
soa, _ := NewRR("example.org. IN SOA sns.dns.icann.org. noc.dns.icann.org. 2018112827 7200 3600 1209600 3600")
m.Answer = []RR{soa}
c := new(Client)
resp, _, err := c.Exchange(m, addrstr)
if err != nil {
t.Errorf("failed to exchange: %v", err)
}
if resp.Rcode != RcodeSuccess {
t.Errorf("expected %s, got %s", RcodeToString[RcodeSuccess], RcodeToString[resp.Rcode])
}
}
func handleNotify(w ResponseWriter, req *Msg) {
m := new(Msg)
m.SetReply(req)
w.WriteMsg(m)
}