Pull request: * all: allow multiple hosts in reverse lookups
Merge in DNS/adguard-home from 2269-multiple-hosts to master
For #2269.
Squashed commit of the following:
commit f8ae452540b106f2d5b130b8edb08c4e76b003f4
Merge: 8dd06f7cc 3e1f92225
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date: Fri Nov 6 17:28:12 2020 +0300
Merge branch 'master' into 2269-multiple-hosts
commit 8dd06f7cca27ec32a4690e2673603b166f82af0a
Author: Ainar Garipov <A.Garipov@AdGuard.COM>
Date: Thu Nov 5 20:28:33 2020 +0300
* all: allow multiple hosts in reverse lookups
This commit is contained in:
@@ -20,9 +20,14 @@ type onChangedT func()
|
||||
|
||||
// AutoHosts - automatic DNS records
|
||||
type AutoHosts struct {
|
||||
lock sync.Mutex // serialize access to table
|
||||
table map[string][]net.IP // 'hostname -> IP' table
|
||||
tableReverse map[string]string // "IP -> hostname" table for reverse lookup
|
||||
// lock protects table and tableReverse.
|
||||
lock sync.Mutex
|
||||
// table is the host-to-IPs map.
|
||||
table map[string][]net.IP
|
||||
// tableReverse is the IP-to-hosts map.
|
||||
//
|
||||
// TODO(a.garipov): Make better use of newtypes. Perhaps a custom map.
|
||||
tableReverse map[string][]string
|
||||
|
||||
hostsFn string // path to the main hosts-file
|
||||
hostsDirs []string // paths to OS-specific directories with hosts-files
|
||||
@@ -127,40 +132,44 @@ func (a *AutoHosts) Process(host string, qtype uint16) []net.IP {
|
||||
return ipsCopy
|
||||
}
|
||||
|
||||
// ProcessReverse - process PTR request
|
||||
// Return "" if not found or an error occurred
|
||||
func (a *AutoHosts) ProcessReverse(addr string, qtype uint16) string {
|
||||
// ProcessReverse processes a PTR request. It returns nil if nothing is found.
|
||||
func (a *AutoHosts) ProcessReverse(addr string, qtype uint16) (hosts []string) {
|
||||
if qtype != dns.TypePTR {
|
||||
return ""
|
||||
return nil
|
||||
}
|
||||
|
||||
ipReal := DNSUnreverseAddr(addr)
|
||||
if ipReal == nil {
|
||||
return "" // invalid IP in question
|
||||
return nil
|
||||
}
|
||||
|
||||
ipStr := ipReal.String()
|
||||
|
||||
a.lock.Lock()
|
||||
host := a.tableReverse[ipStr]
|
||||
a.lock.Unlock()
|
||||
defer a.lock.Unlock()
|
||||
|
||||
if len(host) == 0 {
|
||||
return "" // not found
|
||||
hosts = a.tableReverse[ipStr]
|
||||
|
||||
if len(hosts) == 0 {
|
||||
return nil // not found
|
||||
}
|
||||
|
||||
log.Debug("AutoHosts: reverse-lookup: %s -> %s", addr, host)
|
||||
return host
|
||||
log.Debug("AutoHosts: reverse-lookup: %s -> %s", addr, hosts)
|
||||
|
||||
return hosts
|
||||
}
|
||||
|
||||
// List - get "IP -> hostname" table. Thread-safe.
|
||||
func (a *AutoHosts) List() map[string]string {
|
||||
table := make(map[string]string)
|
||||
// List returns an IP-to-hostnames table. It is safe for concurrent use.
|
||||
func (a *AutoHosts) List() (ipToHosts map[string][]string) {
|
||||
a.lock.Lock()
|
||||
defer a.lock.Unlock()
|
||||
|
||||
ipToHosts = make(map[string][]string, len(a.tableReverse))
|
||||
for k, v := range a.tableReverse {
|
||||
table[k] = v
|
||||
ipToHosts[k] = v
|
||||
}
|
||||
a.lock.Unlock()
|
||||
return table
|
||||
|
||||
return ipToHosts
|
||||
}
|
||||
|
||||
// update table
|
||||
@@ -187,19 +196,30 @@ func (a *AutoHosts) updateTable(table map[string][]net.IP, host string, ipAddr n
|
||||
}
|
||||
}
|
||||
|
||||
// update "reverse" table
|
||||
func (a *AutoHosts) updateTableRev(tableRev map[string]string, host string, ipAddr net.IP) {
|
||||
// updateTableRev updates the reverse address table.
|
||||
func (a *AutoHosts) updateTableRev(tableRev map[string][]string, newHost string, ipAddr net.IP) {
|
||||
ipStr := ipAddr.String()
|
||||
_, ok := tableRev[ipStr]
|
||||
hosts, ok := tableRev[ipStr]
|
||||
if !ok {
|
||||
tableRev[ipStr] = host
|
||||
log.Debug("AutoHosts: added reverse-address %s -> %s", ipStr, host)
|
||||
tableRev[ipStr] = []string{newHost}
|
||||
log.Debug("AutoHosts: added reverse-address %s -> %s", ipStr, newHost)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
for _, host := range hosts {
|
||||
if host == newHost {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
tableRev[ipStr] = append(tableRev[ipStr], newHost)
|
||||
log.Debug("AutoHosts: added reverse-address %s -> %s", ipStr, newHost)
|
||||
}
|
||||
|
||||
// Read IP-hostname pairs from file
|
||||
// Multiple hostnames per line (per one IP) is supported.
|
||||
func (a *AutoHosts) load(table map[string][]net.IP, tableRev map[string]string, fn string) {
|
||||
func (a *AutoHosts) load(table map[string][]net.IP, tableRev map[string][]string, fn string) {
|
||||
f, err := os.Open(fn)
|
||||
if err != nil {
|
||||
log.Error("AutoHosts: %s", err)
|
||||
@@ -306,7 +326,7 @@ func (a *AutoHosts) updateLoop() {
|
||||
// updateHosts - loads system hosts
|
||||
func (a *AutoHosts) updateHosts() {
|
||||
table := make(map[string][]net.IP)
|
||||
tableRev := make(map[string]string)
|
||||
tableRev := make(map[string][]string)
|
||||
|
||||
a.load(table, tableRev, a.hostsFn)
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import (
|
||||
func prepareTestDir() string {
|
||||
const dir = "./agh-test"
|
||||
_ = os.RemoveAll(dir)
|
||||
_ = os.MkdirAll(dir, 0755)
|
||||
_ = os.MkdirAll(dir, 0o755)
|
||||
return dir
|
||||
}
|
||||
|
||||
@@ -50,17 +50,24 @@ func TestAutoHostsResolution(t *testing.T) {
|
||||
|
||||
// Test hosts file
|
||||
table := ah.List()
|
||||
name, ok := table["127.0.0.1"]
|
||||
names, ok := table["127.0.0.1"]
|
||||
assert.True(t, ok)
|
||||
assert.Equal(t, "host", name)
|
||||
assert.Equal(t, []string{"host", "localhost"}, names)
|
||||
|
||||
// Test PTR
|
||||
a, _ := dns.ReverseAddr("127.0.0.1")
|
||||
a = strings.TrimSuffix(a, ".")
|
||||
assert.True(t, ah.ProcessReverse(a, dns.TypePTR) == "host")
|
||||
hosts := ah.ProcessReverse(a, dns.TypePTR)
|
||||
if assert.Len(t, hosts, 2) {
|
||||
assert.Equal(t, hosts[0], "host")
|
||||
}
|
||||
|
||||
a, _ = dns.ReverseAddr("::1")
|
||||
a = strings.TrimSuffix(a, ".")
|
||||
assert.True(t, ah.ProcessReverse(a, dns.TypePTR) == "localhost")
|
||||
hosts = ah.ProcessReverse(a, dns.TypePTR)
|
||||
if assert.Len(t, hosts, 1) {
|
||||
assert.Equal(t, hosts[0], "localhost")
|
||||
}
|
||||
}
|
||||
|
||||
func TestAutoHostsFSNotify(t *testing.T) {
|
||||
|
||||
Reference in New Issue
Block a user