Pull request: 1947 disable autohosts option
Merge in DNS/adguard-home from 1947-hosts-opt to master
Updates #1947.
Updates #2829.
Squashed commit of the following:
commit d09285c3dbfa7816469eec223b88c320c255c8fe
Merge: cff8c4cd 7c6557b0
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Mon Apr 12 18:23:20 2021 +0300
Merge branch 'master' into 1947-hosts-opt
commit cff8c4cdbf4bcd1f5f413c541d7f4a9e42b8b05b
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Mon Apr 12 17:46:19 2021 +0300
home: fix help
commit 1fa01d5b30f5adeda564dcc85a7064e2921d5981
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Mon Apr 12 17:40:48 2021 +0300
home: fix option order
commit 9d83cb604aaddcc8cbe99bafa544636f8f0b7e54
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Mon Apr 12 17:28:30 2021 +0300
aghnet: add important todo
commit 7f1386ff5c3081e07e975b640164a7a05e1319c9
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Mon Apr 12 17:17:17 2021 +0300
all: correct naming
commit cbe2b2e4b21d5bceb3ee88e09cad154ba62b5cef
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Mon Apr 12 15:55:46 2021 +0300
all: mv functionality from util
commit e82ad53862682d903dd0dd10844db65997a758bc
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Mon Apr 12 15:41:35 2021 +0300
home: imp code, docs
commit 9058977f3ff99648fabaebbd7c1c354c71671327
Author: Eugene Burkov <e.burkov@adguard.com>
Date: Mon Apr 12 15:02:34 2021 +0300
home: add an option to disable autohosts
This commit is contained in:
parent
7c6557b05e
commit
e671f43a2f
|
@ -15,6 +15,8 @@ and this project adheres to
|
|||
|
||||
### Added
|
||||
|
||||
- New flag `--no-etc-hosts` to disable client domain name lookups in the
|
||||
operating system's /etc/hosts files ([#1947]).
|
||||
- The ability to set up custom upstreams to resolve PTR queries for local
|
||||
addresses and to disable the automatic resolving of clients' addresses
|
||||
([#2704]).
|
||||
|
@ -54,6 +56,7 @@ and this project adheres to
|
|||
|
||||
[#1273]: https://github.com/AdguardTeam/AdGuardHome/issues/1273
|
||||
[#1401]: https://github.com/AdguardTeam/AdGuardHome/issues/1401
|
||||
[#1947]: https://github.com/AdguardTeam/AdGuardHome/issues/1947
|
||||
[#2385]: https://github.com/AdguardTeam/AdGuardHome/issues/2385
|
||||
[#2393]: https://github.com/AdguardTeam/AdGuardHome/issues/2393
|
||||
[#2412]: https://github.com/AdguardTeam/AdGuardHome/issues/2412
|
||||
|
|
|
@ -1,8 +1,4 @@
|
|||
// Package util contains various utilities.
|
||||
//
|
||||
// TODO(a.garipov): Such packages are widely considered an antipattern. Remove
|
||||
// this when we refactor our project structure.
|
||||
package util
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
|
@ -16,7 +12,6 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghos"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
"github.com/fsnotify/fsnotify"
|
||||
|
@ -25,8 +20,11 @@ import (
|
|||
|
||||
type onChangedT func()
|
||||
|
||||
// AutoHosts - automatic DNS records
|
||||
type AutoHosts struct {
|
||||
// EtcHostsContainer - automatic DNS records
|
||||
//
|
||||
// TODO(e.burkov): Move the logic under interface. Refactor. Probably remove
|
||||
// the resolving logic.
|
||||
type EtcHostsContainer struct {
|
||||
// lock protects table and tableReverse.
|
||||
lock sync.RWMutex
|
||||
// table is the host-to-IPs map.
|
||||
|
@ -47,63 +45,67 @@ type AutoHosts struct {
|
|||
}
|
||||
|
||||
// SetOnChanged - set callback function that will be called when the data is changed
|
||||
func (a *AutoHosts) SetOnChanged(onChanged onChangedT) {
|
||||
a.onChanged = onChanged
|
||||
func (ehc *EtcHostsContainer) SetOnChanged(onChanged onChangedT) {
|
||||
ehc.onChanged = onChanged
|
||||
}
|
||||
|
||||
// Notify other modules
|
||||
func (a *AutoHosts) notify() {
|
||||
if a.onChanged == nil {
|
||||
func (ehc *EtcHostsContainer) notify() {
|
||||
if ehc.onChanged == nil {
|
||||
return
|
||||
}
|
||||
a.onChanged()
|
||||
ehc.onChanged()
|
||||
}
|
||||
|
||||
// Init - initialize
|
||||
// hostsFn: Override default name for the hosts-file (optional)
|
||||
func (a *AutoHosts) Init(hostsFn string) {
|
||||
a.table = make(map[string][]net.IP)
|
||||
a.onlyWritesChan = make(chan fsnotify.Event, 2)
|
||||
func (ehc *EtcHostsContainer) Init(hostsFn string) {
|
||||
ehc.table = make(map[string][]net.IP)
|
||||
ehc.onlyWritesChan = make(chan fsnotify.Event, 2)
|
||||
|
||||
a.hostsFn = "/etc/hosts"
|
||||
ehc.hostsFn = "/etc/hosts"
|
||||
if runtime.GOOS == "windows" {
|
||||
a.hostsFn = os.ExpandEnv("$SystemRoot\\system32\\drivers\\etc\\hosts")
|
||||
ehc.hostsFn = os.ExpandEnv("$SystemRoot\\system32\\drivers\\etc\\hosts")
|
||||
}
|
||||
if len(hostsFn) != 0 {
|
||||
a.hostsFn = hostsFn
|
||||
ehc.hostsFn = hostsFn
|
||||
}
|
||||
|
||||
if aghos.IsOpenWrt() {
|
||||
// OpenWrt: "/tmp/hosts/dhcp.cfg01411c".
|
||||
a.hostsDirs = append(a.hostsDirs, "/tmp/hosts")
|
||||
ehc.hostsDirs = append(ehc.hostsDirs, "/tmp/hosts")
|
||||
}
|
||||
|
||||
// Load hosts initially
|
||||
a.updateHosts()
|
||||
ehc.updateHosts()
|
||||
|
||||
var err error
|
||||
a.watcher, err = fsnotify.NewWatcher()
|
||||
ehc.watcher, err = fsnotify.NewWatcher()
|
||||
if err != nil {
|
||||
log.Error("autohosts: %s", err)
|
||||
log.Error("etchostscontainer: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Start - start module
|
||||
func (a *AutoHosts) Start() {
|
||||
log.Debug("Start AutoHosts module")
|
||||
func (ehc *EtcHostsContainer) Start() {
|
||||
if ehc == nil {
|
||||
return
|
||||
}
|
||||
|
||||
a.updateHosts()
|
||||
log.Debug("Start etchostscontainer module")
|
||||
|
||||
if a.watcher != nil {
|
||||
go a.watcherLoop()
|
||||
ehc.updateHosts()
|
||||
|
||||
err := a.watcher.Add(a.hostsFn)
|
||||
if ehc.watcher != nil {
|
||||
go ehc.watcherLoop()
|
||||
|
||||
err := ehc.watcher.Add(ehc.hostsFn)
|
||||
if err != nil {
|
||||
log.Error("Error while initializing watcher for a file %s: %s", a.hostsFn, err)
|
||||
log.Error("Error while initializing watcher for a file %s: %s", ehc.hostsFn, err)
|
||||
}
|
||||
|
||||
for _, dir := range a.hostsDirs {
|
||||
err = a.watcher.Add(dir)
|
||||
for _, dir := range ehc.hostsDirs {
|
||||
err = ehc.watcher.Add(dir)
|
||||
if err != nil {
|
||||
log.Error("Error while initializing watcher for a directory %s: %s", dir, err)
|
||||
}
|
||||
|
@ -112,67 +114,71 @@ func (a *AutoHosts) Start() {
|
|||
}
|
||||
|
||||
// Close - close module
|
||||
func (a *AutoHosts) Close() {
|
||||
if a.watcher != nil {
|
||||
_ = a.watcher.Close()
|
||||
func (ehc *EtcHostsContainer) Close() {
|
||||
if ehc == nil {
|
||||
return
|
||||
}
|
||||
close(a.onlyWritesChan)
|
||||
|
||||
if ehc.watcher != nil {
|
||||
_ = ehc.watcher.Close()
|
||||
}
|
||||
close(ehc.onlyWritesChan)
|
||||
}
|
||||
|
||||
// Process returns the list of IP addresses for the hostname or nil if nothing
|
||||
// found.
|
||||
func (a *AutoHosts) Process(host string, qtype uint16) []net.IP {
|
||||
func (ehc *EtcHostsContainer) Process(host string, qtype uint16) []net.IP {
|
||||
if qtype == dns.TypePTR {
|
||||
return nil
|
||||
}
|
||||
|
||||
var ipsCopy []net.IP
|
||||
a.lock.RLock()
|
||||
defer a.lock.RUnlock()
|
||||
ehc.lock.RLock()
|
||||
defer ehc.lock.RUnlock()
|
||||
|
||||
if ips, ok := a.table[host]; ok {
|
||||
if ips, ok := ehc.table[host]; ok {
|
||||
ipsCopy = make([]net.IP, len(ips))
|
||||
copy(ipsCopy, ips)
|
||||
}
|
||||
|
||||
log.Debug("autohosts: answer: %s -> %v", host, ipsCopy)
|
||||
log.Debug("etchostscontainer: answer: %s -> %v", host, ipsCopy)
|
||||
return ipsCopy
|
||||
}
|
||||
|
||||
// ProcessReverse processes a PTR request. It returns nil if nothing is found.
|
||||
func (a *AutoHosts) ProcessReverse(addr string, qtype uint16) (hosts []string) {
|
||||
func (ehc *EtcHostsContainer) ProcessReverse(addr string, qtype uint16) (hosts []string) {
|
||||
if qtype != dns.TypePTR {
|
||||
return nil
|
||||
}
|
||||
|
||||
ipReal := aghnet.UnreverseAddr(addr)
|
||||
ipReal := UnreverseAddr(addr)
|
||||
if ipReal == nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
ipStr := ipReal.String()
|
||||
|
||||
a.lock.RLock()
|
||||
defer a.lock.RUnlock()
|
||||
ehc.lock.RLock()
|
||||
defer ehc.lock.RUnlock()
|
||||
|
||||
hosts = a.tableReverse[ipStr]
|
||||
hosts = ehc.tableReverse[ipStr]
|
||||
|
||||
if len(hosts) == 0 {
|
||||
return nil // not found
|
||||
}
|
||||
|
||||
log.Debug("autohosts: reverse-lookup: %s -> %s", addr, hosts)
|
||||
log.Debug("etchostscontainer: reverse-lookup: %s -> %s", addr, hosts)
|
||||
|
||||
return hosts
|
||||
}
|
||||
|
||||
// List returns an IP-to-hostnames table. It is safe for concurrent use.
|
||||
func (a *AutoHosts) List() (ipToHosts map[string][]string) {
|
||||
a.lock.RLock()
|
||||
defer a.lock.RUnlock()
|
||||
func (ehc *EtcHostsContainer) List() (ipToHosts map[string][]string) {
|
||||
ehc.lock.RLock()
|
||||
defer ehc.lock.RUnlock()
|
||||
|
||||
ipToHosts = make(map[string][]string, len(a.tableReverse))
|
||||
for k, v := range a.tableReverse {
|
||||
ipToHosts = make(map[string][]string, len(ehc.tableReverse))
|
||||
for k, v := range ehc.tableReverse {
|
||||
ipToHosts[k] = v
|
||||
}
|
||||
|
||||
|
@ -180,7 +186,7 @@ func (a *AutoHosts) List() (ipToHosts map[string][]string) {
|
|||
}
|
||||
|
||||
// update table
|
||||
func (a *AutoHosts) updateTable(table map[string][]net.IP, host string, ipAddr net.IP) {
|
||||
func (ehc *EtcHostsContainer) updateTable(table map[string][]net.IP, host string, ipAddr net.IP) {
|
||||
ips, ok := table[host]
|
||||
if ok {
|
||||
for _, ip := range ips {
|
||||
|
@ -199,17 +205,17 @@ func (a *AutoHosts) updateTable(table map[string][]net.IP, host string, ipAddr n
|
|||
ok = true
|
||||
}
|
||||
if ok {
|
||||
log.Debug("autohosts: added %s -> %s", ipAddr, host)
|
||||
log.Debug("etchostscontainer: added %s -> %s", ipAddr, host)
|
||||
}
|
||||
}
|
||||
|
||||
// updateTableRev updates the reverse address table.
|
||||
func (a *AutoHosts) updateTableRev(tableRev map[string][]string, newHost string, ipAddr net.IP) {
|
||||
func (ehc *EtcHostsContainer) updateTableRev(tableRev map[string][]string, newHost string, ipAddr net.IP) {
|
||||
ipStr := ipAddr.String()
|
||||
hosts, ok := tableRev[ipStr]
|
||||
if !ok {
|
||||
tableRev[ipStr] = []string{newHost}
|
||||
log.Debug("autohosts: added reverse-address %s -> %s", ipStr, newHost)
|
||||
log.Debug("etchostscontainer: added reverse-address %s -> %s", ipStr, newHost)
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -221,20 +227,20 @@ func (a *AutoHosts) updateTableRev(tableRev map[string][]string, newHost string,
|
|||
}
|
||||
|
||||
tableRev[ipStr] = append(tableRev[ipStr], newHost)
|
||||
log.Debug("autohosts: added reverse-address %s -> %s", ipStr, newHost)
|
||||
log.Debug("etchostscontainer: 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 (ehc *EtcHostsContainer) 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)
|
||||
log.Error("etchostscontainer: %s", err)
|
||||
return
|
||||
}
|
||||
defer f.Close()
|
||||
r := bufio.NewReader(f)
|
||||
log.Debug("autohosts: loading hosts from file %s", fn)
|
||||
log.Debug("etchostscontainer: loading hosts from file %s", fn)
|
||||
|
||||
for done := false; !done; {
|
||||
var line string
|
||||
|
@ -242,7 +248,7 @@ func (a *AutoHosts) load(table map[string][]net.IP, tableRev map[string][]string
|
|||
if err == io.EOF {
|
||||
done = true
|
||||
} else if err != nil {
|
||||
log.Error("autohosts: %s", err)
|
||||
log.Error("etchostscontainer: %s", err)
|
||||
|
||||
return
|
||||
}
|
||||
|
@ -276,8 +282,8 @@ func (a *AutoHosts) load(table map[string][]net.IP, tableRev map[string][]string
|
|||
host = host[:sharp]
|
||||
}
|
||||
|
||||
a.updateTable(table, host, ip)
|
||||
a.updateTableRev(tableRev, host, ip)
|
||||
ehc.updateTable(table, host, ip)
|
||||
ehc.updateTableRev(tableRev, host, ip)
|
||||
if sharp >= 0 {
|
||||
// Skip the comments again.
|
||||
break
|
||||
|
@ -287,20 +293,20 @@ func (a *AutoHosts) load(table map[string][]net.IP, tableRev map[string][]string
|
|||
}
|
||||
|
||||
// onlyWrites is a filter for (*fsnotify.Watcher).Events.
|
||||
func (a *AutoHosts) onlyWrites() {
|
||||
for event := range a.watcher.Events {
|
||||
func (ehc *EtcHostsContainer) onlyWrites() {
|
||||
for event := range ehc.watcher.Events {
|
||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||
a.onlyWritesChan <- event
|
||||
ehc.onlyWritesChan <- event
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Receive notifications from fsnotify package
|
||||
func (a *AutoHosts) watcherLoop() {
|
||||
go a.onlyWrites()
|
||||
func (ehc *EtcHostsContainer) watcherLoop() {
|
||||
go ehc.onlyWrites()
|
||||
for {
|
||||
select {
|
||||
case event, ok := <-a.onlyWritesChan:
|
||||
case event, ok := <-ehc.onlyWritesChan:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
|
@ -310,7 +316,7 @@ func (a *AutoHosts) watcherLoop() {
|
|||
repeat := true
|
||||
for repeat {
|
||||
select {
|
||||
case _, ok = <-a.onlyWritesChan:
|
||||
case _, ok = <-ehc.onlyWritesChan:
|
||||
repeat = ok
|
||||
default:
|
||||
repeat = false
|
||||
|
@ -318,48 +324,48 @@ func (a *AutoHosts) watcherLoop() {
|
|||
}
|
||||
|
||||
if event.Op&fsnotify.Write == fsnotify.Write {
|
||||
log.Debug("autohosts: modified: %s", event.Name)
|
||||
a.updateHosts()
|
||||
log.Debug("etchostscontainer: modified: %s", event.Name)
|
||||
ehc.updateHosts()
|
||||
}
|
||||
|
||||
case err, ok := <-a.watcher.Errors:
|
||||
case err, ok := <-ehc.watcher.Errors:
|
||||
if !ok {
|
||||
return
|
||||
}
|
||||
log.Error("autohosts: %s", err)
|
||||
log.Error("etchostscontainer: %s", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// updateHosts - loads system hosts
|
||||
func (a *AutoHosts) updateHosts() {
|
||||
func (ehc *EtcHostsContainer) updateHosts() {
|
||||
table := make(map[string][]net.IP)
|
||||
tableRev := make(map[string][]string)
|
||||
|
||||
a.load(table, tableRev, a.hostsFn)
|
||||
ehc.load(table, tableRev, ehc.hostsFn)
|
||||
|
||||
for _, dir := range a.hostsDirs {
|
||||
for _, dir := range ehc.hostsDirs {
|
||||
fis, err := ioutil.ReadDir(dir)
|
||||
if err != nil {
|
||||
if !errors.Is(err, os.ErrNotExist) {
|
||||
log.Error("autohosts: Opening directory: %q: %s", dir, err)
|
||||
log.Error("etchostscontainer: Opening directory: %q: %s", dir, err)
|
||||
}
|
||||
|
||||
continue
|
||||
}
|
||||
|
||||
for _, fi := range fis {
|
||||
a.load(table, tableRev, filepath.Join(dir, fi.Name()))
|
||||
ehc.load(table, tableRev, filepath.Join(dir, fi.Name()))
|
||||
}
|
||||
}
|
||||
|
||||
func() {
|
||||
a.lock.Lock()
|
||||
defer a.lock.Unlock()
|
||||
ehc.lock.Lock()
|
||||
defer ehc.lock.Unlock()
|
||||
|
||||
a.table = table
|
||||
a.tableReverse = tableRev
|
||||
ehc.table = table
|
||||
ehc.tableReverse = tableRev
|
||||
}()
|
||||
|
||||
a.notify()
|
||||
ehc.notify()
|
||||
}
|
|
@ -1,4 +1,4 @@
|
|||
package util
|
||||
package aghnet
|
||||
|
||||
import (
|
||||
"io/ioutil"
|
||||
|
@ -43,8 +43,8 @@ func assertWriting(t *testing.T, f *os.File, strs ...string) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestAutoHostsResolution(t *testing.T) {
|
||||
ah := &AutoHosts{}
|
||||
func TestEtcHostsContainerResolution(t *testing.T) {
|
||||
ehc := &EtcHostsContainer{}
|
||||
|
||||
f := prepareTestFile(t)
|
||||
|
||||
|
@ -52,25 +52,25 @@ func TestAutoHostsResolution(t *testing.T) {
|
|||
" 127.0.0.1 host localhost # comment \n",
|
||||
" ::1 localhost#comment \n",
|
||||
)
|
||||
ah.Init(f.Name())
|
||||
ehc.Init(f.Name())
|
||||
|
||||
t.Run("existing_host", func(t *testing.T) {
|
||||
ips := ah.Process("localhost", dns.TypeA)
|
||||
ips := ehc.Process("localhost", dns.TypeA)
|
||||
require.Len(t, ips, 1)
|
||||
assert.Equal(t, net.IPv4(127, 0, 0, 1), ips[0])
|
||||
})
|
||||
|
||||
t.Run("unknown_host", func(t *testing.T) {
|
||||
ips := ah.Process("newhost", dns.TypeA)
|
||||
ips := ehc.Process("newhost", dns.TypeA)
|
||||
assert.Nil(t, ips)
|
||||
|
||||
// Comment.
|
||||
ips = ah.Process("comment", dns.TypeA)
|
||||
ips = ehc.Process("comment", dns.TypeA)
|
||||
assert.Nil(t, ips)
|
||||
})
|
||||
|
||||
t.Run("hosts_file", func(t *testing.T) {
|
||||
names, ok := ah.List()["127.0.0.1"]
|
||||
names, ok := ehc.List()["127.0.0.1"]
|
||||
require.True(t, ok)
|
||||
assert.Equal(t, []string{"host", "localhost"}, names)
|
||||
})
|
||||
|
@ -90,29 +90,29 @@ func TestAutoHostsResolution(t *testing.T) {
|
|||
require.Nil(t, err)
|
||||
|
||||
a = strings.TrimSuffix(a, ".")
|
||||
hosts := ah.ProcessReverse(a, dns.TypePTR)
|
||||
hosts := ehc.ProcessReverse(a, dns.TypePTR)
|
||||
require.Len(t, hosts, tc.wantLen)
|
||||
assert.Equal(t, tc.wantHost, hosts[0])
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func TestAutoHostsFSNotify(t *testing.T) {
|
||||
ah := &AutoHosts{}
|
||||
func TestEtcHostsContainerFSNotify(t *testing.T) {
|
||||
ehc := &EtcHostsContainer{}
|
||||
|
||||
f := prepareTestFile(t)
|
||||
|
||||
assertWriting(t, f, " 127.0.0.1 host localhost \n")
|
||||
ah.Init(f.Name())
|
||||
ehc.Init(f.Name())
|
||||
|
||||
t.Run("unknown_host", func(t *testing.T) {
|
||||
ips := ah.Process("newhost", dns.TypeA)
|
||||
ips := ehc.Process("newhost", dns.TypeA)
|
||||
assert.Nil(t, ips)
|
||||
})
|
||||
|
||||
// Start monitoring for changes.
|
||||
ah.Start()
|
||||
t.Cleanup(ah.Close)
|
||||
ehc.Start()
|
||||
t.Cleanup(ehc.Close)
|
||||
|
||||
assertWriting(t, f, "127.0.0.2 newhost\n")
|
||||
require.Nil(t, f.Sync())
|
||||
|
@ -122,7 +122,7 @@ func TestAutoHostsFSNotify(t *testing.T) {
|
|||
time.Sleep(50 * time.Millisecond)
|
||||
|
||||
t.Run("notified", func(t *testing.T) {
|
||||
ips := ah.Process("newhost", dns.TypeA)
|
||||
ips := ehc.Process("newhost", dns.TypeA)
|
||||
assert.NotNil(t, ips)
|
||||
require.Len(t, ips, 1)
|
||||
assert.True(t, net.IP{127, 0, 0, 2}.Equal(ips[0]))
|
|
@ -13,7 +13,7 @@ import (
|
|||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/util"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||
"github.com/AdguardTeam/golibs/cache"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
|
@ -65,8 +65,9 @@ type Config struct {
|
|||
// Per-client settings can override this configuration.
|
||||
BlockedServices []string `yaml:"blocked_services"`
|
||||
|
||||
// IP-hostname pairs taken from system configuration (e.g. /etc/hosts) files
|
||||
AutoHosts *util.AutoHosts `yaml:"-"`
|
||||
// EtcHosts is a container of IP-hostname pairs taken from the operating
|
||||
// system configuration files (e.g. /etc/hosts).
|
||||
EtcHosts *aghnet.EtcHostsContainer `yaml:"-"`
|
||||
|
||||
// Called when the configuration is changed by HTTP request
|
||||
ConfigModified func() `yaml:"-"`
|
||||
|
@ -428,11 +429,11 @@ func (d *DNSFilter) checkAutoHosts(
|
|||
qtype uint16,
|
||||
_ *FilteringSettings,
|
||||
) (res Result, err error) {
|
||||
if d.Config.AutoHosts == nil {
|
||||
if d.Config.EtcHosts == nil {
|
||||
return Result{}, nil
|
||||
}
|
||||
|
||||
ips := d.Config.AutoHosts.Process(host, qtype)
|
||||
ips := d.Config.EtcHosts.Process(host, qtype)
|
||||
if ips != nil {
|
||||
res = Result{
|
||||
Reason: RewrittenAutoHosts,
|
||||
|
@ -442,7 +443,7 @@ func (d *DNSFilter) checkAutoHosts(
|
|||
return res, nil
|
||||
}
|
||||
|
||||
revHosts := d.Config.AutoHosts.ProcessReverse(host, qtype)
|
||||
revHosts := d.Config.EtcHosts.ProcessReverse(host, qtype)
|
||||
if len(revHosts) != 0 {
|
||||
res = Result{
|
||||
Reason: RewrittenAutoHosts,
|
||||
|
|
|
@ -23,7 +23,6 @@ import (
|
|||
"github.com/AdguardTeam/AdGuardHome/internal/aghtest"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/util"
|
||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||
"github.com/miekg/dns"
|
||||
|
@ -1074,7 +1073,7 @@ func TestPTRResponseFromDHCPLeases(t *testing.T) {
|
|||
|
||||
func TestPTRResponseFromHosts(t *testing.T) {
|
||||
c := dnsfilter.Config{
|
||||
AutoHosts: &util.AutoHosts{},
|
||||
EtcHosts: &aghnet.EtcHostsContainer{},
|
||||
}
|
||||
|
||||
// Prepare test hosts file.
|
||||
|
@ -1090,8 +1089,8 @@ func TestPTRResponseFromHosts(t *testing.T) {
|
|||
_, _ = hf.WriteString(" ::1 localhost#comment \n")
|
||||
|
||||
// Init auto hosts.
|
||||
c.AutoHosts.Init(hf.Name())
|
||||
t.Cleanup(c.AutoHosts.Close)
|
||||
c.EtcHosts.Init(hf.Name())
|
||||
t.Cleanup(c.EtcHosts.Close)
|
||||
|
||||
var snd *aghnet.SubnetDetector
|
||||
snd, err = aghnet.NewSubnetDetector()
|
||||
|
|
|
@ -18,7 +18,6 @@ import (
|
|||
"github.com/AdguardTeam/AdGuardHome/internal/dnsfilter"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/querylog"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/util"
|
||||
"github.com/AdguardTeam/dnsproxy/proxy"
|
||||
"github.com/AdguardTeam/dnsproxy/upstream"
|
||||
"github.com/AdguardTeam/golibs/log"
|
||||
|
@ -92,7 +91,7 @@ type clientsContainer struct {
|
|||
// dnsServer is used for checking clients IP status access list status
|
||||
dnsServer *dnsforward.Server
|
||||
|
||||
autoHosts *util.AutoHosts // get entries from system hosts-files
|
||||
etcHosts *aghnet.EtcHostsContainer // get entries from system hosts-files
|
||||
|
||||
testing bool // if TRUE, this object is used for internal tests
|
||||
}
|
||||
|
@ -100,7 +99,11 @@ type clientsContainer struct {
|
|||
// Init initializes clients container
|
||||
// dhcpServer: optional
|
||||
// Note: this function must be called only once
|
||||
func (clients *clientsContainer) Init(objects []clientObject, dhcpServer *dhcpd.Server, autoHosts *util.AutoHosts) {
|
||||
func (clients *clientsContainer) Init(
|
||||
objects []clientObject,
|
||||
dhcpServer *dhcpd.Server,
|
||||
etcHosts *aghnet.EtcHostsContainer,
|
||||
) {
|
||||
if clients.list != nil {
|
||||
log.Fatal("clients.list != nil")
|
||||
}
|
||||
|
@ -114,7 +117,9 @@ func (clients *clientsContainer) Init(objects []clientObject, dhcpServer *dhcpd.
|
|||
}
|
||||
|
||||
clients.dhcpServer = dhcpServer
|
||||
clients.autoHosts = autoHosts
|
||||
if etcHosts != nil {
|
||||
clients.etcHosts = etcHosts
|
||||
}
|
||||
clients.addFromConfig(objects)
|
||||
|
||||
if !clients.testing {
|
||||
|
@ -122,7 +127,9 @@ func (clients *clientsContainer) Init(objects []clientObject, dhcpServer *dhcpd.
|
|||
if clients.dhcpServer != nil {
|
||||
clients.dhcpServer.SetOnLeaseChanged(clients.onDHCPLeaseChanged)
|
||||
}
|
||||
clients.autoHosts.SetOnChanged(clients.onHostsChanged)
|
||||
if clients.etcHosts != nil {
|
||||
clients.etcHosts.SetOnChanged(clients.onHostsChanged)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -692,7 +699,11 @@ func (clients *clientsContainer) rmHostsBySrc(src clientSource) {
|
|||
// addFromHostsFile fills the client-hostname pairing index from the system's
|
||||
// hosts files.
|
||||
func (clients *clientsContainer) addFromHostsFile() {
|
||||
hosts := clients.autoHosts.List()
|
||||
if clients.etcHosts == nil {
|
||||
return
|
||||
}
|
||||
|
||||
hosts := clients.etcHosts.List()
|
||||
|
||||
clients.lock.Lock()
|
||||
defer clients.lock.Unlock()
|
||||
|
|
|
@ -57,7 +57,7 @@ func initDNSServer() error {
|
|||
Context.queryLog = querylog.New(conf)
|
||||
|
||||
filterConf := config.DNS.DnsfilterConf
|
||||
filterConf.AutoHosts = &Context.autoHosts
|
||||
filterConf.EtcHosts = Context.etcHosts
|
||||
filterConf.ConfigModified = onConfigModified
|
||||
filterConf.HTTPRegister = httpRegister
|
||||
Context.dnsFilter = dnsfilter.New(&filterConf, nil)
|
||||
|
|
|
@ -46,19 +46,19 @@ type homeContext struct {
|
|||
// Modules
|
||||
// --
|
||||
|
||||
clients clientsContainer // per-client-settings module
|
||||
stats stats.Stats // statistics module
|
||||
queryLog querylog.QueryLog // query log module
|
||||
dnsServer *dnsforward.Server // DNS module
|
||||
rdns *RDNS // rDNS module
|
||||
whois *Whois // WHOIS module
|
||||
dnsFilter *dnsfilter.DNSFilter // DNS filtering module
|
||||
dhcpServer *dhcpd.Server // DHCP module
|
||||
auth *Auth // HTTP authentication module
|
||||
filters Filtering // DNS filtering module
|
||||
web *Web // Web (HTTP, HTTPS) module
|
||||
tls *TLSMod // TLS module
|
||||
autoHosts util.AutoHosts // IP-hostname pairs taken from system configuration (e.g. /etc/hosts) files
|
||||
clients clientsContainer // per-client-settings module
|
||||
stats stats.Stats // statistics module
|
||||
queryLog querylog.QueryLog // query log module
|
||||
dnsServer *dnsforward.Server // DNS module
|
||||
rdns *RDNS // rDNS module
|
||||
whois *Whois // WHOIS module
|
||||
dnsFilter *dnsfilter.DNSFilter // DNS filtering module
|
||||
dhcpServer *dhcpd.Server // DHCP module
|
||||
auth *Auth // HTTP authentication module
|
||||
filters Filtering // DNS filtering module
|
||||
web *Web // Web (HTTP, HTTPS) module
|
||||
tls *TLSMod // TLS module
|
||||
etcHosts *aghnet.EtcHostsContainer // IP-hostname pairs taken from system configuration (e.g. /etc/hosts) files
|
||||
updater *updater.Updater
|
||||
|
||||
subnetDetector *aghnet.SubnetDetector
|
||||
|
@ -186,8 +186,6 @@ func setupConfig(args options) {
|
|||
log.Fatalf("can't initialize dhcp module")
|
||||
}
|
||||
|
||||
Context.autoHosts.Init("")
|
||||
|
||||
Context.updater = updater.NewUpdater(&updater.Config{
|
||||
Client: Context.client,
|
||||
Version: version.Version(),
|
||||
|
@ -200,7 +198,11 @@ func setupConfig(args options) {
|
|||
ConfName: config.getConfigFilename(),
|
||||
})
|
||||
|
||||
Context.clients.Init(config.Clients, Context.dhcpServer, &Context.autoHosts)
|
||||
if !args.noEtcHosts {
|
||||
Context.etcHosts = &aghnet.EtcHostsContainer{}
|
||||
Context.etcHosts.Init("")
|
||||
Context.clients.Init(config.Clients, Context.dhcpServer, Context.etcHosts)
|
||||
}
|
||||
config.Clients = nil
|
||||
|
||||
if (runtime.GOOS == "linux" || runtime.GOOS == "darwin") &&
|
||||
|
@ -317,7 +319,7 @@ func run(args options) {
|
|||
}
|
||||
|
||||
Context.tls.Start()
|
||||
Context.autoHosts.Start()
|
||||
Context.etcHosts.Start()
|
||||
|
||||
go func() {
|
||||
serr := startDNSServer()
|
||||
|
@ -530,7 +532,7 @@ func cleanup(ctx context.Context) {
|
|||
Context.dhcpServer.Stop()
|
||||
}
|
||||
|
||||
Context.autoHosts.Close()
|
||||
Context.etcHosts.Close()
|
||||
|
||||
if Context.tls != nil {
|
||||
Context.tls.Close()
|
||||
|
|
|
@ -32,6 +32,10 @@ type options struct {
|
|||
disableMemoryOptimization bool
|
||||
|
||||
glinetMode bool // Activate GL-Inet compatibility mode
|
||||
|
||||
// noEtcHosts flag should be provided when /etc/hosts file shouldn't be
|
||||
// used.
|
||||
noEtcHosts bool
|
||||
}
|
||||
|
||||
// functions used for their side-effects
|
||||
|
@ -191,7 +195,7 @@ var glinetArg = arg{
|
|||
}
|
||||
|
||||
var versionArg = arg{
|
||||
description: "Show the version and exit",
|
||||
description: "Show the version and exit. Show more detailed version description with -v",
|
||||
longName: "version",
|
||||
shortName: "",
|
||||
updateWithValue: nil,
|
||||
|
@ -212,7 +216,7 @@ var versionArg = arg{
|
|||
}
|
||||
|
||||
var helpArg = arg{
|
||||
"Print this help. Show more detailed version description with -v",
|
||||
"Print this help",
|
||||
"help", "",
|
||||
nil, nil, func(o options, exec string) (effect, error) {
|
||||
return func() error { _ = printHelp(exec); os.Exit(64); return nil }, nil
|
||||
|
@ -220,6 +224,16 @@ var helpArg = arg{
|
|||
func(o options) []string { return nil },
|
||||
}
|
||||
|
||||
var noEtcHostsArg = arg{
|
||||
description: "Do not use the OS-provided hosts.",
|
||||
longName: "no-etc-hosts",
|
||||
shortName: "",
|
||||
updateWithValue: nil,
|
||||
updateNoValue: func(o options) (options, error) { o.noEtcHosts = true; return o, nil },
|
||||
effect: nil,
|
||||
serialize: func(o options) []string { return boolSliceOrNil(o.noEtcHosts) },
|
||||
}
|
||||
|
||||
func init() {
|
||||
args = []arg{
|
||||
configArg,
|
||||
|
@ -232,6 +246,7 @@ func init() {
|
|||
checkConfigArg,
|
||||
noCheckUpdateArg,
|
||||
disableMemoryOptimizationArg,
|
||||
noEtcHostsArg,
|
||||
verboseArg,
|
||||
glinetArg,
|
||||
versionArg,
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
// Package util contains various utilities.
|
||||
//
|
||||
// TODO(a.garipov): Such packages are widely considered an antipattern. Remove
|
||||
// this when we refactor our project structure.
|
||||
package util
|
||||
|
||||
import (
|
||||
|
|
Loading…
Reference in New Issue