2022-11-03 18:39:37 +01:00
|
|
|
package dns
|
|
|
|
|
|
|
|
import (
|
2022-11-23 13:39:42 +01:00
|
|
|
"fmt"
|
2022-11-03 18:39:37 +01:00
|
|
|
"github.com/miekg/dns"
|
|
|
|
nbdns "github.com/netbirdio/netbird/dns"
|
|
|
|
log "github.com/sirupsen/logrus"
|
|
|
|
"sync"
|
|
|
|
)
|
|
|
|
|
2023-03-17 10:37:27 +01:00
|
|
|
type registrationMap map[string]struct{}
|
|
|
|
|
2022-11-03 18:39:37 +01:00
|
|
|
type localResolver struct {
|
|
|
|
registeredMap registrationMap
|
|
|
|
records sync.Map
|
|
|
|
}
|
|
|
|
|
|
|
|
// ServeDNS handles a DNS request
|
|
|
|
func (d *localResolver) ServeDNS(w dns.ResponseWriter, r *dns.Msg) {
|
2022-11-26 13:29:50 +01:00
|
|
|
log.Tracef("received question: %#v\n", r.Question[0])
|
2022-11-03 18:39:37 +01:00
|
|
|
replyMessage := &dns.Msg{}
|
|
|
|
replyMessage.SetReply(r)
|
2022-11-23 13:39:42 +01:00
|
|
|
replyMessage.RecursionAvailable = true
|
|
|
|
replyMessage.Rcode = dns.RcodeSuccess
|
|
|
|
|
|
|
|
response := d.lookupRecord(r)
|
|
|
|
if response != nil {
|
|
|
|
replyMessage.Answer = append(replyMessage.Answer, response)
|
|
|
|
}
|
2022-11-03 18:39:37 +01:00
|
|
|
|
|
|
|
err := w.WriteMsg(replyMessage)
|
|
|
|
if err != nil {
|
|
|
|
log.Debugf("got an error while writing the local resolver response, error: %v", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *localResolver) lookupRecord(r *dns.Msg) dns.RR {
|
2022-11-23 13:39:42 +01:00
|
|
|
question := r.Question[0]
|
|
|
|
record, found := d.records.Load(buildRecordKey(question.Name, question.Qclass, question.Qtype))
|
2022-11-03 18:39:37 +01:00
|
|
|
if !found {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
return record.(dns.RR)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *localResolver) registerRecord(record nbdns.SimpleRecord) error {
|
|
|
|
fullRecord, err := dns.NewRR(record.String())
|
|
|
|
if err != nil {
|
|
|
|
return err
|
|
|
|
}
|
|
|
|
|
2022-11-23 13:39:42 +01:00
|
|
|
fullRecord.Header().Rdlength = record.Len()
|
|
|
|
|
|
|
|
header := fullRecord.Header()
|
|
|
|
d.records.Store(buildRecordKey(header.Name, header.Class, header.Rrtype), fullRecord)
|
2022-11-03 18:39:37 +01:00
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (d *localResolver) deleteRecord(recordKey string) {
|
|
|
|
d.records.Delete(dns.Fqdn(recordKey))
|
|
|
|
}
|
2022-11-23 13:39:42 +01:00
|
|
|
|
|
|
|
func buildRecordKey(name string, class, qType uint16) string {
|
|
|
|
key := fmt.Sprintf("%s_%d_%d", name, class, qType)
|
|
|
|
return key
|
|
|
|
}
|