From 447519948102c96313390857dc743346491ec45a Mon Sep 17 00:00:00 2001 From: Ben Schwartz Date: Thu, 25 Jun 2020 20:47:55 -0400 Subject: [PATCH 1/2] Fix query construction error Queries weren't setting the "RD" bit, so they were not actually traversing the recursive resolver as intended. --- choir_test.go | 6 ++++++ client.go | 1 + example/example_client.go | 21 ++++++++++++++++++++- 3 files changed, 27 insertions(+), 1 deletion(-) diff --git a/choir_test.go b/choir_test.go index 1015648..c58f726 100644 --- a/choir_test.go +++ b/choir_test.go @@ -288,6 +288,12 @@ func TestFormat(t *testing.T) { if err := msg.Unpack(query); err != nil { t.Fatal(err) } + if msg.Header.OpCode != 0 { + t.Error("Message is not a question") + } + if !msg.Header.RecursionDesired { + t.Error("Query doesn't request recursion") + } question := msg.Questions[0] expectedQuestion := dnsmessage.Question{ Name: dnsmessage.MustNewName(name + "."), diff --git a/client.go b/client.go index f88fb92..76e0a90 100644 --- a/client.go +++ b/client.go @@ -153,6 +153,7 @@ func formatQuery(name string) ([]byte, error) { binary.BigEndian.PutUint16(ecsPayload[2:], ecsPrefixLength) msg := &dnsmessage.Message{ + Header: dnsmessage.Header{RecursionDesired: true}, Questions: []dnsmessage.Question{{ Name: n, Type: dnsmessage.TypeTXT, diff --git a/example/example_client.go b/example/example_client.go index 325d5ef..34197c7 100644 --- a/example/example_client.go +++ b/example/example_client.go @@ -85,7 +85,26 @@ func (s udpDNSReportSender) Send(r choir.Report) error { if err != nil { log.Fatal("Failed to reach resolver:", err) } - c.Write(query) + if _, err := c.Write(query); err != nil { + log.Printf("Warning: Query failed: %v", err) + } else { + var buf [4096]byte + c.SetReadDeadline(time.Now().Add(5 * time.Second)) + n, err := c.Read(buf[:]) + if err != nil { + log.Printf("Reading response failed: %v", err) + } else { + var msg dnsmessage.Message + if err := msg.Unpack(buf[:n]); err != nil { + log.Printf("Bad response: %v", err) + } else if msg.Header.RCode != dnsmessage.RCodeNameError { + // We expect an NXDOMAIN response. Anything else is surprising. + log.Printf("Unexpected response: %v", msg.Header.RCode) + } else { + log.Printf("Report complete") + } + } + } c.Close() return nil } From 55db4689eb71b8b12222c66a8262f63eee179bec Mon Sep 17 00:00:00 2001 From: Ben Schwartz Date: Fri, 26 Jun 2020 12:46:40 -0400 Subject: [PATCH 2/2] Reduce nesting in the client example --- example/example_client.go | 42 ++++++++++++++++++++------------------- 1 file changed, 22 insertions(+), 20 deletions(-) diff --git a/example/example_client.go b/example/example_client.go index 34197c7..9d6fbe3 100644 --- a/example/example_client.go +++ b/example/example_client.go @@ -83,29 +83,31 @@ func (s udpDNSReportSender) Send(r choir.Report) error { log.Printf("Querying %s via %s\n", name, s.serverAddress) c, err := net.Dial("udp", s.serverAddress) if err != nil { - log.Fatal("Failed to reach resolver:", err) + return fmt.Errorf("Failed to reach resolver: %w", err) } + defer c.Close() + if _, err := c.Write(query); err != nil { - log.Printf("Warning: Query failed: %v", err) - } else { - var buf [4096]byte - c.SetReadDeadline(time.Now().Add(5 * time.Second)) - n, err := c.Read(buf[:]) - if err != nil { - log.Printf("Reading response failed: %v", err) - } else { - var msg dnsmessage.Message - if err := msg.Unpack(buf[:n]); err != nil { - log.Printf("Bad response: %v", err) - } else if msg.Header.RCode != dnsmessage.RCodeNameError { - // We expect an NXDOMAIN response. Anything else is surprising. - log.Printf("Unexpected response: %v", msg.Header.RCode) - } else { - log.Printf("Report complete") - } - } + return fmt.Errorf("Query failed: %w", err) } - c.Close() + + var buf [4096]byte + c.SetReadDeadline(time.Now().Add(5 * time.Second)) + n, err := c.Read(buf[:]) + if err != nil { + return fmt.Errorf("Reading response failed: %w", err) + } + + var response dnsmessage.Message + if err := response.Unpack(buf[:n]); err != nil { + return fmt.Errorf("Bad response: %w", err) + } + if response.Header.RCode != dnsmessage.RCodeNameError { + // We expect an NXDOMAIN response. Anything else is surprising. + return fmt.Errorf("Unexpected response: %v", response.Header.RCode) + } + + log.Printf("Report complete") return nil }