Pull request: 3597 arpdb

Merge in DNS/adguard-home from 3597-wrt-netlink to master

Updates #3597.

Squashed commit of the following:

commit 1709582cd204bb80c84775feabae8723ed3340f6
Merge: 0507b6ed e7b3c996
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Mar 15 20:25:18 2022 +0300

    Merge branch 'master' into 3597-wrt-netlink

commit 0507b6ede1162554ca8ac7399d827264aca64f98
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Mar 15 20:21:29 2022 +0300

    all: imp code

commit 71f9758d854b3e2cf90cbd3655ae4818cfbcf528
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Mar 9 18:03:48 2022 +0500

    aghnet: imp naming

commit c949e765104f130aa3e5ba465bdebc3286bebe44
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Mar 9 17:26:30 2022 +0500

    all: imp code, docs

commit cf605ddb401b6e7b0a7a4bb1b175a4dc588d253a
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Tue Mar 8 15:33:52 2022 +0500

    all: imp code, docs

commit 2960c6549a7e4944cc0072ca47a0cd4e82ec850e
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Sun Mar 6 21:34:58 2022 +0500

    all: imp code & docs, fix tests

commit 29c049f3aee91a826c3416961686396d562a7066
Author: Eugene Burkov <E.Burkov@AdGuard.COM>
Date:   Wed Mar 2 20:45:34 2022 +0300

    all: add arpdb
This commit is contained in:
Eugene Burkov
2022-03-15 20:57:46 +03:00
parent e7b3c9969b
commit 573cbafe3f
19 changed files with 1058 additions and 44 deletions

View File

@@ -4,10 +4,7 @@ import (
"bytes"
"fmt"
"net"
"os/exec"
"runtime"
"sort"
"strings"
"sync"
"time"
@@ -99,6 +96,9 @@ type clientsContainer struct {
// hosts database.
etcHosts *aghnet.HostsContainer
// arpdb stores the neighbors retrieved from ARP.
arpdb aghnet.ARPDB
testing bool // if TRUE, this object is used for internal tests
}
@@ -109,6 +109,7 @@ func (clients *clientsContainer) Init(
objects []*clientObject,
dhcpServer *dhcpd.Server,
etcHosts *aghnet.HostsContainer,
arpdb aghnet.ARPDB,
) {
if clients.list != nil {
log.Fatal("clients.list != nil")
@@ -121,6 +122,7 @@ func (clients *clientsContainer) Init(
clients.dhcpServer = dhcpServer
clients.etcHosts = etcHosts
clients.arpdb = arpdb
clients.addFromConfig(objects)
if clients.testing {
@@ -807,16 +809,18 @@ func (clients *clientsContainer) addFromHostsFile(hosts *netutil.IPMap) {
// addFromSystemARP adds the IP-hostname pairings from the output of the arp -a
// command.
func (clients *clientsContainer) addFromSystemARP() {
if runtime.GOOS == "windows" {
if err := clients.arpdb.Refresh(); err != nil {
log.Error("refreshing arp container: %s", err)
clients.arpdb = aghnet.EmptyARPDB{}
return
}
cmd := exec.Command("arp", "-a")
log.Tracef("executing %q %q", cmd.Path, cmd.Args)
data, err := cmd.Output()
if err != nil || cmd.ProcessState.ExitCode() != 0 {
log.Debug("command %q has failed: %q code:%d",
cmd.Path, err, cmd.ProcessState.ExitCode())
ns := clients.arpdb.Neighbors()
if len(ns) == 0 {
log.Debug("refreshing arp container: the update is empty")
return
}
@@ -825,30 +829,14 @@ func (clients *clientsContainer) addFromSystemARP() {
clients.rmHostsBySrc(ClientSourceARP)
n := 0
// TODO(a.garipov): Rewrite to use bufio.Scanner.
lines := strings.Split(string(data), "\n")
for _, ln := range lines {
lparen := strings.Index(ln, " (")
rparen := strings.Index(ln, ") ")
if lparen == -1 || rparen == -1 || lparen >= rparen {
continue
}
host := ln[:lparen]
ipStr := ln[lparen+2 : rparen]
ip := net.ParseIP(ipStr)
if netutil.ValidateDomainName(host) != nil || ip == nil {
continue
}
ok := clients.addHostLocked(ip, host, ClientSourceARP)
if ok {
n++
added := 0
for _, n := range ns {
if clients.addHostLocked(n.IP, "", ClientSourceARP) {
added++
}
}
log.Debug("clients: added %d client aliases from 'arp -a' command output", n)
log.Debug("clients: added %d client aliases from arp neighborhood", added)
}
// updateFromDHCP adds the clients that have a non-empty hostname from the DHCP

View File

@@ -18,7 +18,7 @@ func TestClients(t *testing.T) {
clients := clientsContainer{}
clients.testing = true
clients.Init(nil, nil, nil)
clients.Init(nil, nil, nil, nil)
t.Run("add_success", func(t *testing.T) {
c := &Client{
@@ -194,7 +194,7 @@ func TestClientsWHOIS(t *testing.T) {
clients := clientsContainer{
testing: true,
}
clients.Init(nil, nil, nil)
clients.Init(nil, nil, nil, nil)
whois := &RuntimeClientWHOISInfo{
Country: "AU",
Orgname: "Example Org",
@@ -253,7 +253,7 @@ func TestClientsAddExisting(t *testing.T) {
clients := clientsContainer{
testing: true,
}
clients.Init(nil, nil, nil)
clients.Init(nil, nil, nil, nil)
t.Run("simple", func(t *testing.T) {
ip := net.IP{1, 1, 1, 1}
@@ -332,7 +332,7 @@ func TestClientsCustomUpstream(t *testing.T) {
clients := clientsContainer{
testing: true,
}
clients.Init(nil, nil, nil)
clients.Init(nil, nil, nil, nil)
// Add client with upstreams.
ok, err := clients.Add(&Client{

View File

@@ -293,7 +293,15 @@ func setupConfig(args options) (err error) {
}
}
Context.clients.Init(config.Clients, Context.dhcpServer, Context.etcHosts)
var arpdb aghnet.ARPDB
arpdb, err = aghnet.NewARPDB()
if err != nil {
log.Info("warning: creating arpdb: %s; using stub", err)
arpdb = aghnet.EmptyARPDB{}
}
Context.clients.Init(config.Clients, Context.dhcpServer, Context.etcHosts, arpdb)
if args.bindPort != 0 {
uc := aghalg.UniqChecker{}