wgengine/tsdns: fix error response marshaling, improve bad query logs

Updates #995

Signed-off-by: Brad Fitzpatrick <bradfitz@tailscale.com>
This commit is contained in:
Brad Fitzpatrick 2020-12-16 22:14:36 -08:00 committed by Brad Fitzpatrick
parent 554a20becb
commit 741c513e51
2 changed files with 28 additions and 10 deletions

View File

@ -381,22 +381,26 @@ func marshalResponse(resp *response) ([]byte, error) {
builder := dns.NewBuilder(nil, resp.Header)
err := builder.StartQuestions()
if err != nil {
return nil, err
}
isSuccess := resp.Header.RCode == dns.RCodeSuccess
err = builder.Question(resp.Question)
if err != nil {
return nil, err
if resp.Question.Type != 0 || isSuccess {
err := builder.StartQuestions()
if err != nil {
return nil, err
}
err = builder.Question(resp.Question)
if err != nil {
return nil, err
}
}
// Only successful responses contain answers.
if resp.Header.RCode != dns.RCodeSuccess {
if !isSuccess {
return builder.Finish()
}
err = builder.StartAnswers()
err := builder.StartAnswers()
if err != nil {
return nil, err
}
@ -576,7 +580,11 @@ func (r *Resolver) respond(query []byte) ([]byte, error) {
err := parseQuery(query, resp)
// We will not return this error: it is the sender's fault.
if err != nil {
r.logf("parsing query: %v", err)
if errors.Is(err, dns.ErrSectionDone) {
r.logf("parseQuery(%02x): no DNS questions", query)
} else {
r.logf("parseQuery(%02x): %v", query, err)
}
resp.Header.RCode = dns.RCodeFormatError
return marshalResponse(resp)
}

View File

@ -748,3 +748,13 @@ func BenchmarkFull(b *testing.B) {
})
}
}
func TestMarshalResponseFormatError(t *testing.T) {
resp := new(response)
resp.Header.RCode = dns.RCodeFormatError
v, err := marshalResponse(resp)
if err != nil {
t.Errorf("marshal error: %v", err)
}
t.Logf("response: %q", v)
}