mirror of https://github.com/subgraph/fw-daemon
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
69 lines
1.4 KiB
69 lines
1.4 KiB
package main
|
|
|
|
import (
|
|
"net"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/subgraph/fw-daemon/nfqueue"
|
|
)
|
|
|
|
type dnsCache struct {
|
|
ipMap map[string]string
|
|
lock sync.Mutex
|
|
done chan struct{}
|
|
}
|
|
|
|
func NewDnsCache() *dnsCache {
|
|
return &dnsCache{
|
|
ipMap: make(map[string]string),
|
|
done: make(chan struct{}),
|
|
}
|
|
}
|
|
|
|
func (dc *dnsCache) processDNS(pkt *nfqueue.Packet) {
|
|
dns := &dnsMsg{}
|
|
if !dns.Unpack(pkt.Payload) {
|
|
log.Warning("Failed to Unpack DNS message")
|
|
return
|
|
}
|
|
if !dns.response {
|
|
return
|
|
}
|
|
if len(dns.question) != 1 {
|
|
log.Warning("Length of DNS Question section is not 1 as expected: %d", len(dns.question))
|
|
return
|
|
}
|
|
q := dns.question[0]
|
|
if q.Qtype == dnsTypeA {
|
|
dc.processRecordA(q.Name, dns.answer)
|
|
return
|
|
}
|
|
log.Info("Unhandled DNS message: %v", dns)
|
|
|
|
}
|
|
|
|
func (dc *dnsCache) processRecordA(name string, answers []dnsRR) {
|
|
dc.lock.Lock()
|
|
defer dc.lock.Unlock()
|
|
for _, rr := range answers {
|
|
switch rec := rr.(type) {
|
|
case *dnsRR_A:
|
|
ip := net.IPv4(byte(rec.A>>24), byte(rec.A>>16), byte(rec.A>>8), byte(rec.A)).String()
|
|
if strings.HasSuffix(name, ".") {
|
|
name = name[:len(name)-1]
|
|
}
|
|
dc.ipMap[ip] = name
|
|
log.Info("Adding %s: %s", name, ip)
|
|
default:
|
|
log.Warning("Unexpected RR type in answer section of A response: %v", rec)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (dc *dnsCache) Lookup(ip net.IP) string {
|
|
dc.lock.Lock()
|
|
defer dc.lock.Unlock()
|
|
return dc.ipMap[ip.String()]
|
|
}
|