Skip to content

Commit 8b734b8

Browse files
authored
Merge pull request #64 from blinklabs-io/feat/lookup-nameserver-record
feat: answer direct queries for nameservers
2 parents 3faaa67 + f403a03 commit 8b734b8

File tree

2 files changed

+72
-0
lines changed

2 files changed

+72
-0
lines changed

internal/dns/dns.go

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,45 @@ func handleQuery(w dns.ResponseWriter, r *dns.Msg) {
6262
}
6363
}
6464

65+
// Check for known record for domain nameserver
66+
records, err := state.GetState().LookupNameserverRecord(
67+
strings.TrimSuffix(r.Question[0].Name, "."),
68+
)
69+
if err != nil {
70+
logger.Errorf("failed to lookup record in state: %s", err)
71+
return
72+
}
73+
if records != nil {
74+
// Assemble response
75+
m.SetReply(r)
76+
for k, v := range records {
77+
k = dns.Fqdn(k)
78+
address := net.ParseIP(v)
79+
// A or AAAA record
80+
if address.To4() != nil {
81+
// IPv4
82+
a := &dns.A{
83+
Hdr: dns.RR_Header{Name: k, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: 999},
84+
A: address,
85+
}
86+
m.Answer = append(m.Answer, a)
87+
} else {
88+
// IPv6
89+
aaaa := &dns.AAAA{
90+
Hdr: dns.RR_Header{Name: k, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: 999},
91+
AAAA: address,
92+
}
93+
m.Answer = append(m.Answer, aaaa)
94+
}
95+
}
96+
// Send response
97+
if err := w.WriteMsg(m); err != nil {
98+
logger.Errorf("failed to write response: %s", err)
99+
}
100+
// We found our answer, to return from handler
101+
return
102+
}
103+
65104
nameserverDomain, nameservers, err := findNameserversForDomain(
66105
r.Question[0].Name,
67106
)

internal/state/state.go

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,39 @@ func (s *State) LookupDomain(domainName string) (map[string]string, error) {
127127
return ret, nil
128128
}
129129

130+
// LookupNameserverRecord searches the domain nameserver entries for one matching the requested record
131+
func (s *State) LookupNameserverRecord(recordName string) (map[string]string, error) {
132+
ret := map[string]string{}
133+
err := s.db.View(func(txn *badger.Txn) error {
134+
opts := badger.DefaultIteratorOptions
135+
// Makes key scans faster
136+
opts.PrefetchValues = false
137+
it := txn.NewIterator(opts)
138+
defer it.Close()
139+
for it.Rewind(); it.Valid(); it.Next() {
140+
item := it.Item()
141+
k := item.Key()
142+
if strings.HasSuffix(string(k), fmt.Sprintf("_nameserver_%s", recordName)) {
143+
err := item.Value(func(v []byte) error {
144+
ret[recordName] = string(v)
145+
return nil
146+
})
147+
if err != nil {
148+
return err
149+
}
150+
}
151+
}
152+
return nil
153+
})
154+
if err != nil {
155+
return nil, err
156+
}
157+
if len(ret) == 0 {
158+
return nil, nil
159+
}
160+
return ret, nil
161+
}
162+
130163
func GetState() *State {
131164
return globalState
132165
}

0 commit comments

Comments
 (0)