Pull request 1861: 4923-gopacket-dhcp vol.1
Merge in DNS/adguard-home from 4923-gopacket-dhcp to master Updates #4923. Squashed commit of the following: commit edf36ce8b1873272c3daebe8cc8f8132793aac44 Merge: a17513d3e123ca8738Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Thu Jun 22 14:14:39 2023 +0300 Merge branch 'master' into 4923-gopacket-dhcp commit a17513d3e0a9e596d56444dfa46478eee15631de Merge: f04727c29994906fbdAuthor: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Wed Jun 21 17:49:09 2023 +0300 Merge branch 'master' into 4923-gopacket-dhcp commit f04727c29eaf22f9eb53f3aa33d42d00e177b224 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Tue Jun 20 15:42:31 2023 +0300 home: revert clients container commit c58284ac6b5b2274da5eed2e853847d757709e5b Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Mon Jun 19 21:10:36 2023 +0300 all: imp code, names, docs commit 4c4613c939e1325d11655822d9dbc3f05a6d203c Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Tue Jun 13 18:51:12 2023 +0300 all: imp code commit 0b4a6e0dd561d9b7bb78dea21dcc947bcd0bd583 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Wed Jun 7 18:40:15 2023 +0300 all: imp api commit 0425edea03d6ca0859657df683bef6ec45bfc399 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Mon Jun 5 15:57:23 2023 +0300 dhcpsvc: introduce package commit 5628ebe6cccf91e2c48778966730bcbbe9e1d9f2 Author: Eugene Burkov <E.Burkov@AdGuard.COM> Date: Thu Jun 1 17:49:12 2023 +0300 WIP
This commit is contained in:
@@ -11,6 +11,7 @@ import (
|
||||
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/aghnet"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/dhcpd"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/dhcpsvc"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/filtering"
|
||||
"github.com/AdguardTeam/AdGuardHome/internal/querylog"
|
||||
@@ -24,6 +25,23 @@ import (
|
||||
"golang.org/x/exp/slices"
|
||||
)
|
||||
|
||||
// DHCP is an interface for accesing DHCP lease data the [clientsContainer]
|
||||
// needs.
|
||||
type DHCP interface {
|
||||
// Leases returns all the DHCP leases.
|
||||
Leases() (leases []*dhcpsvc.Lease)
|
||||
|
||||
// HostByIP returns the hostname of the DHCP client with the given IP
|
||||
// address. The address will be netip.Addr{} if there is no such client,
|
||||
// due to an assumption that a DHCP client must always have an IP address.
|
||||
HostByIP(ip netip.Addr) (host string)
|
||||
|
||||
// MACByIP returns the MAC address for the given IP address leased. It
|
||||
// returns nil if there is no such client, due to an assumption that a DHCP
|
||||
// client must always have a MAC address.
|
||||
MACByIP(ip netip.Addr) (mac net.HardwareAddr)
|
||||
}
|
||||
|
||||
// clientsContainer is the storage of all runtime and persistent clients.
|
||||
type clientsContainer struct {
|
||||
// TODO(a.garipov): Perhaps use a number of separate indices for different
|
||||
@@ -101,9 +119,9 @@ func (clients *clientsContainer) Init(
|
||||
return
|
||||
}
|
||||
|
||||
clients.updateFromDHCP(true)
|
||||
if clients.dhcpServer != nil {
|
||||
clients.dhcpServer.SetOnLeaseChanged(clients.onDHCPLeaseChanged)
|
||||
clients.onDHCPLeaseChanged(dhcpd.LeaseChangedAdded)
|
||||
}
|
||||
|
||||
if clients.etcHosts != nil {
|
||||
@@ -277,15 +295,38 @@ func (clients *clientsContainer) periodicUpdate() {
|
||||
}
|
||||
}
|
||||
|
||||
// onDHCPLeaseChanged is a callback for the DHCP server. It updates the list of
|
||||
// runtime clients using the DHCP server's leases.
|
||||
//
|
||||
// TODO(e.burkov): Remove when switched to dhcpsvc.
|
||||
func (clients *clientsContainer) onDHCPLeaseChanged(flags int) {
|
||||
switch flags {
|
||||
case dhcpd.LeaseChangedAdded,
|
||||
dhcpd.LeaseChangedAddedStatic,
|
||||
dhcpd.LeaseChangedRemovedStatic:
|
||||
clients.updateFromDHCP(true)
|
||||
case dhcpd.LeaseChangedRemovedAll:
|
||||
clients.updateFromDHCP(false)
|
||||
if clients.dhcpServer == nil || !config.Clients.Sources.DHCP {
|
||||
return
|
||||
}
|
||||
|
||||
clients.lock.Lock()
|
||||
defer clients.lock.Unlock()
|
||||
|
||||
clients.rmHostsBySrc(ClientSourceDHCP)
|
||||
|
||||
if flags == dhcpd.LeaseChangedRemovedAll {
|
||||
return
|
||||
}
|
||||
|
||||
leases := clients.dhcpServer.Leases(dhcpd.LeasesAll)
|
||||
n := 0
|
||||
for _, l := range leases {
|
||||
if l.Hostname == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
ok := clients.addHostLocked(l.IP, l.Hostname, ClientSourceDHCP)
|
||||
if ok {
|
||||
n++
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug("clients: added %d client aliases from dhcp", n)
|
||||
}
|
||||
|
||||
// clientSource checks if client with this IP address already exists and returns
|
||||
@@ -301,11 +342,11 @@ func (clients *clientsContainer) clientSource(ip netip.Addr) (src clientSource)
|
||||
}
|
||||
|
||||
rc, ok := clients.ipToRC[ip]
|
||||
if !ok {
|
||||
return ClientSourceNone
|
||||
if ok {
|
||||
return rc.Source
|
||||
}
|
||||
|
||||
return rc.Source
|
||||
return ClientSourceNone
|
||||
}
|
||||
|
||||
// findMultiple is a wrapper around Find to make it a valid client finder for
|
||||
@@ -466,11 +507,11 @@ func (clients *clientsContainer) findLocked(id string) (c *Client, ok bool) {
|
||||
}
|
||||
}
|
||||
|
||||
if clients.dhcpServer == nil {
|
||||
return nil, false
|
||||
if clients.dhcpServer != nil {
|
||||
return clients.findDHCP(ip)
|
||||
}
|
||||
|
||||
return clients.findDHCP(ip)
|
||||
return nil, false
|
||||
}
|
||||
|
||||
// findDHCP searches for a client by its MAC, if the DHCP server is active and
|
||||
@@ -697,28 +738,27 @@ func (clients *clientsContainer) setWHOISInfo(ip netip.Addr, wi *whois.Info) {
|
||||
_, ok := clients.findLocked(ip.String())
|
||||
if ok {
|
||||
log.Debug("clients: client for %s is already created, ignore whois info", ip)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// TODO(e.burkov): Consider storing WHOIS information separately and
|
||||
// potentially get rid of [RuntimeClient].
|
||||
rc, ok := clients.ipToRC[ip]
|
||||
if ok {
|
||||
rc.WHOIS = wi
|
||||
if !ok {
|
||||
// Create a RuntimeClient implicitly so that we don't do this check
|
||||
// again.
|
||||
rc = &RuntimeClient{
|
||||
Source: ClientSourceWHOIS,
|
||||
}
|
||||
clients.ipToRC[ip] = rc
|
||||
|
||||
log.Debug("clients: set whois info for runtime client with ip %s: %+v", ip, wi)
|
||||
} else {
|
||||
log.Debug("clients: set whois info for runtime client %s: %+v", rc.Host, wi)
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
// Create a RuntimeClient implicitly so that we don't do this check
|
||||
// again.
|
||||
rc = &RuntimeClient{
|
||||
Source: ClientSourceWHOIS,
|
||||
}
|
||||
|
||||
rc.WHOIS = wi
|
||||
|
||||
clients.ipToRC[ip] = rc
|
||||
|
||||
log.Debug("clients: set whois info for runtime client with ip %s: %+v", ip, wi)
|
||||
}
|
||||
|
||||
// AddHost adds a new IP-hostname pairing. The priorities of the sources are
|
||||
@@ -742,23 +782,19 @@ func (clients *clientsContainer) addHostLocked(
|
||||
src clientSource,
|
||||
) (ok bool) {
|
||||
rc, ok := clients.ipToRC[ip]
|
||||
if ok {
|
||||
if rc.Source > src {
|
||||
return false
|
||||
}
|
||||
|
||||
rc.Host = host
|
||||
rc.Source = src
|
||||
} else {
|
||||
if !ok {
|
||||
rc = &RuntimeClient{
|
||||
Host: host,
|
||||
Source: src,
|
||||
WHOIS: &whois.Info{},
|
||||
WHOIS: &whois.Info{},
|
||||
}
|
||||
|
||||
clients.ipToRC[ip] = rc
|
||||
} else if src < rc.Source {
|
||||
return false
|
||||
}
|
||||
|
||||
rc.Host = host
|
||||
rc.Source = src
|
||||
|
||||
log.Debug("clients: added %s -> %q [%d]", ip, host, len(clients.ipToRC))
|
||||
|
||||
return true
|
||||
@@ -827,38 +863,6 @@ func (clients *clientsContainer) addFromSystemARP() {
|
||||
log.Debug("clients: added %d client aliases from arp neighborhood", added)
|
||||
}
|
||||
|
||||
// updateFromDHCP adds the clients that have a non-empty hostname from the DHCP
|
||||
// server.
|
||||
func (clients *clientsContainer) updateFromDHCP(add bool) {
|
||||
if clients.dhcpServer == nil || !config.Clients.Sources.DHCP {
|
||||
return
|
||||
}
|
||||
|
||||
clients.lock.Lock()
|
||||
defer clients.lock.Unlock()
|
||||
|
||||
clients.rmHostsBySrc(ClientSourceDHCP)
|
||||
|
||||
if !add {
|
||||
return
|
||||
}
|
||||
|
||||
leases := clients.dhcpServer.Leases(dhcpd.LeasesAll)
|
||||
n := 0
|
||||
for _, l := range leases {
|
||||
if l.Hostname == "" {
|
||||
continue
|
||||
}
|
||||
|
||||
ok := clients.addHostLocked(l.IP, l.Hostname, ClientSourceDHCP)
|
||||
if ok {
|
||||
n++
|
||||
}
|
||||
}
|
||||
|
||||
log.Debug("clients: added %d client aliases from dhcp", n)
|
||||
}
|
||||
|
||||
// close gracefully closes all the client-specific upstream configurations of
|
||||
// the persistent clients.
|
||||
func (clients *clientsContainer) close() (err error) {
|
||||
|
||||
Reference in New Issue
Block a user