Return remaining records (answers: 0, authorities: 1)

- We return the remaining records (e.g. SRV, HINFO). The behavior is the
  same for an A/AAAA record that is not found, i.e. no answers, 1
  authority.
This commit is contained in:
Brian Cunnie
2020-10-02 11:48:11 -04:00
parent c3f96b8890
commit 5b1e9986c0
2 changed files with 60 additions and 2 deletions

View File

@@ -174,9 +174,9 @@ func processQuestion(q dnsmessage.Question, b *dnsmessage.Builder) error {
} }
case dnsmessage.TypeALL: case dnsmessage.TypeALL:
{ {
// We don't implement type ANY, so return "NotImplemented" like CloudFlare // We don't implement type ANY, so return "NotImplemented" like CloudFlare (1.1.1.1)
// https://blog.cloudflare.com/rfc8482-saying-goodbye-to-any/ // https://blog.cloudflare.com/rfc8482-saying-goodbye-to-any/
// Google (8.8.8.8) returns A & AAAA records. // Google (8.8.8.8) returns every record they can find (A, AAAA, SOA, NS, MX, ...).
return &DNSError{RCode: dnsmessage.RCodeNotImplemented} return &DNSError{RCode: dnsmessage.RCodeNotImplemented}
} }
case dnsmessage.TypeMX: case dnsmessage.TypeMX:
@@ -230,6 +230,25 @@ func processQuestion(q dnsmessage.Question, b *dnsmessage.Builder) error {
return err return err
} }
} }
default:
{
// default is the same case as an A/AAAA record which is not found,
// i.e. we return no answers, but we return an authority section
err := b.StartAuthorities()
if err != nil {
return err
}
err = b.SOAResource(dnsmessage.ResourceHeader{
Name: q.Name,
Type: dnsmessage.TypeSOA,
Class: dnsmessage.ClassINET,
TTL: 604800, // 60 * 60 * 24 * 7 == 1 week; it's not gonna change
Length: 0,
}, SOAResource(q.Name.String()))
if err != nil {
return err
}
}
} }
return nil return nil
} }

View File

@@ -214,6 +214,45 @@ var _ = Describe("Xip", func() {
Expect(len(response.Additionals)).To(Equal(0)) Expect(len(response.Additionals)).To(Equal(0))
}) })
}) })
When("a record is requested but there's no record to return (e.g. SRV, HINFO)", func() {
BeforeEach(func() {
name = "no-srv-record.sslip.io."
nameArray = [255]byte{} // zero-out the array otherwise tests will fail with leftovers from longer "name"s
copy(nameArray[:], name)
queryType = dnsmessage.TypeSRV
expectedSOA := xip.SOAResource(name)
expectedAuthority := dnsmessage.Resource{
Header: dnsmessage.ResourceHeader{
Name: dnsmessage.Name{
Data: nameArray,
Length: uint8(len(name)),
},
Type: dnsmessage.TypeSOA,
Class: dnsmessage.ClassINET,
TTL: 604800,
Length: 36,
},
Body: &expectedSOA,
}
expectedResponse.Authorities = append(expectedResponse.Authorities, expectedAuthority)
})
It("responds with no answers but with an authority", func() {
Expect(err).ToNot(HaveOccurred())
Expect(len(response.Questions)).To(Equal(1))
Expect(response.Questions[0]).To(Equal(question))
// break test down for easier debugging
Expect(len(response.Answers)).To(Equal(0))
Expect(len(response.Authorities)).To(Equal(1))
Expect(response.Authorities[0].Header.Name).To(Equal(expectedResponse.Authorities[0].Header.Name))
Expect(response.Authorities[0].Header).To(Equal(expectedResponse.Authorities[0].Header))
Expect(response.Authorities[0].Body).To(Equal(expectedResponse.Authorities[0].Body))
Expect(response.Authorities[0]).To(Equal(expectedResponse.Authorities[0]))
// I've made a decision to not populate the Additionals section because it's too much work
// (And I don't think it's necessary)
Expect(len(response.Additionals)).To(Equal(0))
})
})
}) })
Describe("ResponseHeader()", func() { Describe("ResponseHeader()", func() {