Skip to content

Commit

Permalink
feat: Adds functions to check for errors and response in header flags…
Browse files Browse the repository at this point in the history
… and adds tests for that.
  • Loading branch information
Harsh-2909 committed Jul 21, 2024
1 parent c09c66c commit f74c64a
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 12 deletions.
5 changes: 0 additions & 5 deletions dns/dns_message_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,4 @@ func TestDNSMessage(t *testing.T) {
}
assert.Equal(t, DNSMessage, *DNSMessageFromBytes(DNSMessageBytes))
})

// TODO: Write tests and code checks for the following in all the test files:
// - Whether the Header Flag parsed from response has proper flag to denote that it is a response
// - Whether the Header Flag parsed from response has proper flag to denote that it does not have an error
// - Whether the Resource Record checks for the type of record and parses it accordingly
}
18 changes: 18 additions & 0 deletions dns/header_flag.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,21 @@ func HeaderFlagFromBytes(b []byte) *HeaderFlag {

return HeaderFlagFromUint16(flag)
}

// HasError returns whether the HeaderFlag has an error.
// It checks the value of the RCode field.
func (hf *HeaderFlag) HasError() bool {
return hf.RCode != RCodeNoError
}

// IsQuery returns whether the HeaderFlag is a query.
// It checks the value of the QR field.
func (hf *HeaderFlag) IsQuery() bool {
return !hf.QR
}

// IsResponse returns whether the HeaderFlag is a response.
// It checks the value of the QR field.
func (hf *HeaderFlag) IsResponse() bool {
return hf.QR
}
24 changes: 24 additions & 0 deletions dns/header_flag_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,28 @@ func TestHeaderFlag(t *testing.T) {
expected := NewHeaderFlag(false, 0, false, false, true, false, 0, 0)
assert.Equal(t, expected, HeaderFlagFromBytes(flagBytes))
})

t.Run("Should check if the header flag has an error", func(t *testing.T) {
flag := NewHeaderFlag(false, 0, false, false, true, false, 0, 0)
assert.False(t, flag.HasError())

flag = NewHeaderFlag(false, 0, false, false, true, false, 0, 1)
assert.True(t, flag.HasError())
})

t.Run("Should check if the header flag is a query", func(t *testing.T) {
flag := NewHeaderFlag(false, 0, false, false, true, false, 0, 0)
assert.True(t, flag.IsQuery())

flag = NewHeaderFlag(true, 0, false, false, true, false, 0, 1)
assert.False(t, flag.IsQuery())
})

t.Run("Should check if the header flag is a response", func(t *testing.T) {
flag := NewHeaderFlag(false, 0, false, false, true, false, 0, 0)
assert.False(t, flag.IsResponse())

flag = NewHeaderFlag(true, 0, false, false, true, false, 0, 1)
assert.True(t, flag.IsResponse())
})
}
24 changes: 18 additions & 6 deletions network/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"dns-resolver-go/dns"
"fmt"
"net"
"os"
"time"
)

Expand Down Expand Up @@ -112,6 +113,18 @@ func Resolve(domain string, questionType uint16) string {
return ""
}
parsedResponse = dns.DNSMessageFromBytes(response)
fmt.Printf("parsedResponse:\n %+v\n\n", parsedResponse)
flags := dns.HeaderFlagFromUint16(parsedResponse.Header.Flags)

if flags.HasError() {
fmt.Printf("The DNS server returned an error: %s\n", parsedResponse.Answers[0].RDataParsed)
os.Exit(1)
}

if flags.IsQuery() {
fmt.Printf("The returned DNS message is not a response.\n")
os.Exit(1)
}

if parsedResponse.Header.ANCount > 0 {
fmt.Printf("\nNon-authoritative answer:\n")
Expand All @@ -125,19 +138,18 @@ func Resolve(domain string, questionType uint16) string {
}
}
break
}

if parsedResponse.Header.ARCount > 0 {
} else if parsedResponse.Header.ARCount > 0 {
if ip := getRecord(parsedResponse.AdditionalRRs); ip != "" {
dnsServerIP = ip
}
continue
}

if parsedResponse.Header.NSCount > 0 {
} else if parsedResponse.Header.NSCount > 0 {
if nsDomain := getRecord(parsedResponse.AuthorityRRs); nsDomain != "" {
dnsServerIP = Resolve(nsDomain, dns.TypeA)
}
} else {
fmt.Printf("No answers found for %s\n", domain)
os.Exit(1)
}
}
return parsedResponse.Answers[0].RDataParsed
Expand Down
2 changes: 1 addition & 1 deletion network/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func TestClient(t *testing.T) {
t.Run("Should create a client", func(t *testing.T) {
t.Run("Should check if the IDs match", func(t *testing.T) {
queryMessage, _ := hex.DecodeString("00160100000100000000000003646e7306676f6f676c6503636f6d0000010001")
response, _ := hex.DecodeString("00168080000100020000000003646e7306676f6f676c6503636f6d0000010001c00c0001000100000214000408080808c00c0001000100000214000408080404")
wrongResponse := []byte{0, 20}
Expand Down

0 comments on commit f74c64a

Please sign in to comment.