fix: improved the reverse hostname lookup process

This commit is contained in:
pommee
2025-07-23 14:53:25 +02:00
parent 6b17979ec8
commit 44cc6ff130
4 changed files with 69 additions and 29 deletions

View File

@@ -27,22 +27,37 @@ func trimDomainDot(name string) string {
return name
}
func isPTRQuery(request *Request, domainName string) bool {
return request.Question.Qtype == dns.TypePTR || strings.HasSuffix(domainName, "in-addr.arpa.")
}
func (s *DNSServer) checkAndUpdatePauseStatus() {
if s.Config.DNS.Status.Paused &&
time.Since(s.Config.DNS.Status.PausedAt).Seconds() >= float64(s.Config.DNS.Status.PauseTime) {
s.Config.DNS.Status.Paused = false
}
}
func (s *DNSServer) shouldBlockQuery(domainName, fullName string) bool {
return !s.Config.DNS.Status.Paused &&
s.Blacklist.IsBlacklisted(domainName) &&
!s.Whitelist.IsWhitelisted(fullName)
}
func (s *DNSServer) processQuery(request *Request) model.RequestLogEntry {
domainName := trimDomainDot(request.Question.Name)
if request.Question.Qtype == dns.TypePTR || strings.HasSuffix(domainName, "in-addr.arpa.") {
if isPTRQuery(request, domainName) {
return s.handlePTRQuery(request)
}
if hostIP, found := s.reverseHostnameLookup(request.Question.Name); found {
return s.respondWithHostnameA(request, hostIP)
if ip, found := s.reverseHostnameLookup(request.Question.Name); found {
return s.respondWithHostnameA(request, ip)
}
if s.Config.DNS.Status.Paused && time.Since(s.Config.DNS.Status.PausedAt).Seconds() >= float64(s.Config.DNS.Status.PauseTime) {
s.Config.DNS.Status.Paused = false
}
s.checkAndUpdatePauseStatus()
if !s.Config.DNS.Status.Paused && s.Blacklist.IsBlacklisted(domainName) && !s.Whitelist.IsWhitelisted(request.Question.Name) {
if s.shouldBlockQuery(domainName, request.Question.Name) {
return s.handleBlacklisted(request)
}
@@ -63,29 +78,16 @@ func (s *DNSServer) SaveMacVendor(clientIP, mac, vendor string) {
database.SaveMacEntry(s.DBManager.Conn, clientIP, mac, vendor)
}
func (s *DNSServer) reverseHostnameLookup(hostname string) (string, bool) {
var (
trimmedHost = strings.TrimSuffix(hostname, ".")
resultIP string
found bool
)
func (s *DNSServer) reverseHostnameLookup(requestedHostname string) (string, bool) {
trimmed := strings.TrimSuffix(requestedHostname, ".")
s.clientCache.Range(func(_, value any) bool {
client, ok := value.(*model.Client)
if !ok {
return true
if value, ok := s.hostnameCache.Load(trimmed); ok {
if ip, ok := value.(string); ok {
return ip, true
}
}
if strings.TrimSuffix(client.Name, ".") == trimmedHost {
resultIP = client.IP
found = true
return false
}
return true
})
return resultIP, found
return "", false
}
func (s *DNSServer) getClientInfo(remoteAddr string) *model.Client {
@@ -131,6 +133,11 @@ func (s *DNSServer) getClientInfo(remoteAddr string) *model.Client {
client := model.Client{IP: resultIP, Name: hostname, MAC: macAddress}
s.clientCache.Store(clientIP, &client)
if client.Name != "unknown" {
s.hostnameCache.Store(client.Name, client.IP)
}
return &client
}

View File

@@ -32,6 +32,7 @@ type DNSServer struct {
lastLogTime time.Time
Cache sync.Map
clientCache sync.Map
hostnameCache sync.Map
WebServer *gin.Engine
logEntryChannel chan model.RequestLogEntry
WSQueries *websocket.Conn
@@ -146,6 +147,36 @@ func (s *DNSServer) detectProtocol(w dns.ResponseWriter) model.Protocol {
return model.UDP
}
func (s *DNSServer) PopulateHostnameCache() (err error) {
rows, err := s.DBManager.Conn.Query(`
SELECT DISTINCT client_ip, client_name
FROM request_log
WHERE client_name IS NOT NULL AND client_name != 'unknown'
`)
if err != nil {
return err
}
defer func() {
closeErr := rows.Close()
if err == nil {
err = closeErr
}
}()
for rows.Next() {
var ip, name string
if scanErr := rows.Scan(&ip, &name); scanErr != nil {
return scanErr
}
if _, exists := s.hostnameCache.Load(name); !exists {
s.hostnameCache.Store(name, ip)
}
}
return rows.Err()
}
func (s *DNSServer) WSCom(message communicationMessage) {
if s.WSCommunication == nil {
return

View File

@@ -181,8 +181,6 @@ func (config *Config) Save() {
if err := os.WriteFile("./config/settings.yaml", data, 0644); err != nil {
log.Error("Could not save settings %v", err)
}
log.Info("Settings saved successfully")
}
func (config *Config) UpdateSettings(updatedSettings Config) {

View File

@@ -274,6 +274,10 @@ func startServices(
prefetcher := prefetch.New(dnsServer)
if err := dnsServer.PopulateHostnameCache(); err != nil {
log.Warning("Unable to populate hostname cache: %s", err)
}
wg.Add(1)
go func() {
defer wg.Done()