* (dnsforward): fix reverse lookups from /etc/hosts

There was a bug with empty PTR responses for IPs that are in the hosts
file

Closes: #2085
This commit is contained in:
Andrey Meshkov
2020-09-11 11:53:36 +03:00
parent caee4b86fa
commit cb8afde629
4 changed files with 125 additions and 80 deletions

View File

@@ -10,9 +10,10 @@ import (
"strings"
"sync"
"github.com/miekg/dns"
"github.com/AdguardTeam/golibs/log"
"github.com/fsnotify/fsnotify"
"github.com/miekg/dns"
)
type onChangedT func()
@@ -62,6 +63,9 @@ func (a *AutoHosts) Init(hostsFn string) {
a.hostsDirs = append(a.hostsDirs, "/tmp/hosts") // OpenWRT: "/tmp/hosts/dhcp.cfg01411c"
}
// Load hosts initially
a.updateHosts()
var err error
a.watcher, err = fsnotify.NewWatcher()
if err != nil {
@@ -102,6 +106,62 @@ func (a *AutoHosts) Close() {
}
}
// Process - get the list of IP addresses for the hostname
// Return nil if not found
func (a *AutoHosts) Process(host string, qtype uint16) []net.IP {
if qtype == dns.TypePTR {
return nil
}
var ipsCopy []net.IP
a.lock.Lock()
ips, _ := a.table[host]
if len(ips) != 0 {
ipsCopy = make([]net.IP, len(ips))
copy(ipsCopy, ips)
}
a.lock.Unlock()
log.Debug("AutoHosts: answer: %s -> %v", host, ipsCopy)
return ipsCopy
}
// ProcessReverse - process PTR request
// Return "" if not found or an error occurred
func (a *AutoHosts) ProcessReverse(addr string, qtype uint16) string {
if qtype != dns.TypePTR {
return ""
}
ipReal := DNSUnreverseAddr(addr)
if ipReal == nil {
return "" // invalid IP in question
}
ipStr := ipReal.String()
a.lock.Lock()
host := a.tableReverse[ipStr]
a.lock.Unlock()
if len(host) == 0 {
return "" // not found
}
log.Debug("AutoHosts: reverse-lookup: %s -> %s", addr, host)
return host
}
// List - get "IP -> hostname" table. Thread-safe.
func (a *AutoHosts) List() map[string]string {
table := make(map[string]string)
a.lock.Lock()
for k, v := range a.tableReverse {
table[k] = v
}
a.lock.Unlock()
return table
}
// update table
func (a *AutoHosts) updateTable(table map[string][]net.IP, host string, ipAddr net.IP) {
ips, ok := table[host]
@@ -275,59 +335,3 @@ func (a *AutoHosts) updateHosts() {
a.notify()
}
// Process - get the list of IP addresses for the hostname
// Return nil if not found
func (a *AutoHosts) Process(host string, qtype uint16) []net.IP {
if qtype == dns.TypePTR {
return nil
}
var ipsCopy []net.IP
a.lock.Lock()
ips, _ := a.table[host]
if len(ips) != 0 {
ipsCopy = make([]net.IP, len(ips))
copy(ipsCopy, ips)
}
a.lock.Unlock()
log.Debug("AutoHosts: answer: %s -> %v", host, ipsCopy)
return ipsCopy
}
// ProcessReverse - process PTR request
// Return "" if not found or an error occurred
func (a *AutoHosts) ProcessReverse(addr string, qtype uint16) string {
if qtype != dns.TypePTR {
return ""
}
ipReal := DNSUnreverseAddr(addr)
if ipReal == nil {
return "" // invalid IP in question
}
ipStr := ipReal.String()
a.lock.Lock()
host := a.tableReverse[ipStr]
a.lock.Unlock()
if len(host) == 0 {
return "" // not found
}
log.Debug("AutoHosts: reverse-lookup: %s -> %s", addr, host)
return host
}
// List - get "IP -> hostname" table. Thread-safe.
func (a *AutoHosts) List() map[string]string {
table := make(map[string]string)
a.lock.Lock()
for k, v := range a.tableReverse {
table[k] = v
}
a.lock.Unlock()
return table
}

View File

@@ -34,9 +34,6 @@ func TestAutoHostsResolution(t *testing.T) {
ah.Init(f.Name())
// Update from the hosts file
ah.updateHosts()
// Existing host
ips := ah.Process("localhost", dns.TypeA)
assert.NotNil(t, ips)
@@ -79,7 +76,6 @@ func TestAutoHostsFSNotify(t *testing.T) {
// Init
_, _ = f.WriteString(" 127.0.0.1 host localhost \n")
ah.Init(f.Name())
ah.updateHosts()
// Unknown host
ips := ah.Process("newhost", dns.TypeA)