Skip to content

Commit

Permalink
working iterative resolver with caching. woo!
Browse files Browse the repository at this point in the history
  • Loading branch information
phillip-stephens committed Mar 29, 2024
1 parent 90be93a commit 47d2861
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 14 deletions.
34 changes: 28 additions & 6 deletions pkg/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,42 @@ import (
// TODO PHillip, remove this file, just for testing

func main() {
fmt.Println("Hello, World!")
r, err := zdns.NewExternalResolver()
iterativeRes, err := zdns.NewIterativeResolver(nil)
if err != nil {
log.Fatal("Error creating resolver: %w", err)
log.Fatal("Error creating iterative resolver: %w", err)
}
iterativeRes.ShouldTrace(true)
externalRes, err := zdns.NewExternalResolver()
if err != nil {
log.Fatal("Error creating external resolver: %w", err)
}
externalRes = externalRes.WithNameServers([]string{"1.1.1.1:53"}).ShouldTrace(true)
q := zdns.Question{
Name: "www.google.com",
Type: dns.TypeA,
Class: dns.ClassINET,
}
res, err := r.Lookup(&q)
q1 := zdns.Question{
Name: "www.yahoo.com",
Type: dns.TypeA,
Class: dns.ClassINET,
}
res, err := externalRes.Lookup(&q)
if err != nil {
log.Fatalf("Error resolving: %w", err)
}
fmt.Printf("External: %v\n", res)

res, err = iterativeRes.Lookup(&q)
if err != nil {
log.Fatalf("Error resolving: %w", err)
}
fmt.Printf("Iterative: %v\n", res)

res, err = iterativeRes.Lookup(&q1)
if err != nil {
log.Fatal("Error resolving: %w", err)
log.Fatalf("Error resolving: %w", err)
}
fmt.Println(res)
fmt.Printf("Iterative: %v\n", res)

}
2 changes: 1 addition & 1 deletion pkg/zdns/a_lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ func (r *Resolver) recursiveIPLookup(name string, nameServer string, dnsType uin
var miekgResult interface{}
var status Status
var err error
miekgResult, trace, status, err = r.lookupClient.ProtocolLookup(r, Question{Name: name, Type: dnsType}, nameServer)
miekgResult, trace, status, err = r.lookupClient.DoSingleNameserverLookup(r, Question{Name: name, Type: dnsType}, nameServer)
if status != STATUS_NOERROR || err != nil {
return nil, trace, status, err
}
Expand Down
6 changes: 3 additions & 3 deletions pkg/zdns/lookup.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,12 @@ func GetDNSServers(path string) ([]string, error) {

// Lookup client interface for help in mocking
type Lookuper interface {
ProtocolLookup(r *Resolver, q Question, nameServer string) (SingleQueryResult, Trace, Status, error)
DoSingleNameserverLookup(r *Resolver, q Question, nameServer string) (SingleQueryResult, Trace, Status, error)
}

type LookupClient struct{}

func (lc LookupClient) ProtocolLookup(r *Resolver, q Question, nameServer string) (SingleQueryResult, Trace, Status, error) {
func (lc LookupClient) DoSingleNameserverLookup(r *Resolver, q Question, nameServer string) (SingleQueryResult, Trace, Status, error) {
return r.doSingleNameServerLookup(q, nameServer)
}

Expand Down Expand Up @@ -74,7 +74,7 @@ func (r *Resolver) doLookupAllNameservers(q Question, nameServer string) (*Combi
ips := append(nserver.IPv4Addresses, nserver.IPv6Addresses...)
for _, ip := range ips {
curServer = net.JoinHostPort(ip, "53")
res, trace, status, err := r.lookupClient.ProtocolLookup(r, q, curServer)
res, trace, status, err := r.lookupClient.DoSingleNameserverLookup(r, q, curServer)

fullTrace = append(fullTrace, trace...)
tmpRes = SingleQueryResult{}
Expand Down
5 changes: 3 additions & 2 deletions pkg/zdns/zdns_test.go → pkg/zdns/lookup_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,12 @@
package zdns

import (
"github.com/stretchr/testify/assert"
"net"
"reflect"
"testing"

"github.com/stretchr/testify/assert"

"github.com/zmap/dns"
)

Expand All @@ -39,7 +40,7 @@ var protocolStatus = make(map[domain_ns]Status)

type MockLookupClient struct{}

func (mc MockLookupClient) ProtocolLookup(r *Resolver, q Question, nameServer string) (SingleQueryResult, Trace, Status, error) {
func (mc MockLookupClient) DoSingleNameserverLookup(r *Resolver, q Question, nameServer string) (SingleQueryResult, Trace, Status, error) {
cur_domain_ns := domain_ns{domain: q.Name, ns: nameServer}
if res, ok := mockResults[cur_domain_ns]; ok {
var status = STATUS_NOERROR
Expand Down
17 changes: 15 additions & 2 deletions pkg/zdns/zdns.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,10 +28,13 @@ import (
)

const (
googleDNSResolverAddr = "8.8.8.8:53"
defaultNameServerConfigFile = "/etc/resolv.conf"

defaultTimeout = 15 * time.Second
defaultCacheSize = 10000

// TODO Phillip - probably should put all defaults up here from the two constructors and the newResolver function
)

// TODO Phillip - Probably want to rename this
Expand Down Expand Up @@ -101,6 +104,8 @@ func NewIterativeResolver(cache *Cache) (*Resolver, error) {
r.cache.Init(defaultCacheSize)
}
r.isIterative = true
r.iterativeTimeout = 4 * time.Second
r.maxDepth = 10
// use the set of 13 root name servers
r.nameServers = RootServers[:]
return r, nil
Expand All @@ -119,7 +124,7 @@ func (r *Resolver) Lookup(q *Question) (*Result, error) {
return nil, fmt.Errorf("error resolving name %v for all name servers based on initial server %v: %w", q.Name, ns, err)
}
} else {
res, fullTrace, status, err = r.lookupClient.ProtocolLookup(r, *q, ns)
res, fullTrace, status, err = r.lookupClient.DoSingleNameserverLookup(r, *q, ns)
if err != nil {
return nil, fmt.Errorf("error resolving name %v for a single name server %v: %w", q.Name, ns, err)
}
Expand All @@ -136,6 +141,11 @@ func (r *Resolver) WithNameServers(nameServers []string) *Resolver {
return r
}

func (r *Resolver) ShouldTrace(shouldTrace bool) *Resolver {
r.shouldTrace = shouldTrace
return r
}

func (r *Resolver) WithLookuper(lu Lookuper) *Resolver {
r.lookupClient = lu
return r
Expand All @@ -153,13 +163,16 @@ func newResolver() (*Resolver, error) {

blacklist: blacklist.New(),
blMu: sync.Mutex{},
retries: 1,

ipv4Lookup: false,
ipv6Lookup: false,
}
// TODO - Phillip make this changeable
log.SetLevel(log.DebugLevel)
// set-up persistent TCP/UDP connections and conn for UDP socket re-use
// Step 1: get the local address
conn, err := net.Dial("udp", "8.8.8.8:53")
conn, err := net.Dial("udp", googleDNSResolverAddr)
if err != nil {
return nil, fmt.Errorf("unable to find default IP address to open socket: %w", err)
}
Expand Down

0 comments on commit 47d2861

Please sign in to comment.