Merge: * clients: update runtime clients of type DHCP by event from DHCP module

Close #1378

Squashed commit of the following:

commit e45e2d0e2768fe0677eee43538d381b3eaba39ca
Merge: bea8f79d 5e9c21b0
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jan 29 20:08:20 2020 +0300

    Merge remote-tracking branch 'origin/master' into 1378-dhcp-clients

commit bea8f79dd6f8f3eae87649d853917b503df29616
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jan 29 20:08:06 2020 +0300

    minor

commit 6f1da9c6ea9db5bf80acf234ffe322a4cd2d8d92
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jan 29 19:31:08 2020 +0300

    fix

commit a88b46c1ded2b460ef7f0bfbcf1b80a066edf1c1
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Wed Jan 29 12:53:22 2020 +0300

    minor

commit d2897fe0a9b726fcd97a04906e3be3d21f6b42d7
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Tue Jan 28 19:55:10 2020 +0300

    * clients: update runtime clients of type DHCP by event from DHCP module

commit 3aa352ed2372141617d77363b2f2aeaf3a7e47a0
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Tue Jan 28 19:52:08 2020 +0300

    * minor

commit f5c2291e39df4d13b9baf9aa773284890494bb0a
Author: Simon Zolin <s.zolin@adguard.com>
Date:   Tue Jan 28 19:08:23 2020 +0300

    * clients: remove old entries of source type /etc/hosts or ARP
This commit is contained in:
Simon Zolin
2020-01-30 10:25:02 +03:00
parent 5e9c21b0a7
commit dcc575402b
6 changed files with 121 additions and 37 deletions

View File

@@ -100,6 +100,9 @@ func (clients *clientsContainer) Init(objects []clientObject, dhcpServer *dhcpd.
if !clients.testing {
go clients.periodicUpdate()
clients.addFromDHCP()
clients.dhcpServer.SetOnLeaseChanged(clients.onDHCPLeaseChanged)
clients.registerWebHandlers()
}
}
@@ -186,11 +189,19 @@ func (clients *clientsContainer) periodicUpdate() {
for {
clients.addFromHostsFile()
clients.addFromSystemARP()
clients.addFromDHCP()
time.Sleep(clientsUpdatePeriod)
}
}
func (clients *clientsContainer) onDHCPLeaseChanged(flags int) {
switch flags {
case dhcpd.LeaseChangedAdded,
dhcpd.LeaseChangedAddedStatic,
dhcpd.LeaseChangedRemovedStatic:
clients.addFromDHCP()
}
}
// Exists checks if client with this IP already exists
func (clients *clientsContainer) Exists(ip string, source clientSource) bool {
clients.lock.Lock()
@@ -412,7 +423,7 @@ func (clients *clientsContainer) Add(c Client) (bool, error) {
clients.idIndex[id] = &c
}
log.Tracef("'%s': ID:%v [%d]", c.Name, c.IDs, len(clients.list))
log.Debug("Clients: added '%s': ID:%v [%d]", c.Name, c.IDs, len(clients.list))
return true, nil
}
@@ -535,8 +546,12 @@ func (clients *clientsContainer) SetWhoisInfo(ip string, info [][]string) {
// so we overwrite existing entries with an equal or higher priority
func (clients *clientsContainer) AddHost(ip, host string, source clientSource) (bool, error) {
clients.lock.Lock()
defer clients.lock.Unlock()
b, e := clients.addHost(ip, host, source)
clients.lock.Unlock()
return b, e
}
func (clients *clientsContainer) addHost(ip, host string, source clientSource) (bool, error) {
// check auto-clients index
ch, ok := clients.ipHost[ip]
if ok && ch.Source > source {
@@ -550,10 +565,23 @@ func (clients *clientsContainer) AddHost(ip, host string, source clientSource) (
}
clients.ipHost[ip] = ch
}
log.Tracef("'%s' -> '%s' [%d]", ip, host, len(clients.ipHost))
log.Debug("Clients: added '%s' -> '%s' [%d]", ip, host, len(clients.ipHost))
return true, nil
}
// Remove all entries that match the specified source
func (clients *clientsContainer) rmHosts(source clientSource) int {
n := 0
for k, v := range clients.ipHost {
if v.Source == source {
delete(clients.ipHost, k)
n++
}
}
log.Debug("Clients: removed %d client aliases", n)
return n
}
// Parse system 'hosts' file and fill clients array
func (clients *clientsContainer) addFromHostsFile() {
hostsFn := "/etc/hosts"
@@ -567,6 +595,10 @@ func (clients *clientsContainer) addFromHostsFile() {
return
}
clients.lock.Lock()
defer clients.lock.Unlock()
_ = clients.rmHosts(ClientSourceHostsFile)
lines := strings.Split(string(d), "\n")
n := 0
for _, ln := range lines {
@@ -580,7 +612,7 @@ func (clients *clientsContainer) addFromHostsFile() {
continue
}
ok, e := clients.AddHost(fields[0], fields[1], ClientSourceHostsFile)
ok, e := clients.addHost(fields[0], fields[1], ClientSourceHostsFile)
if e != nil {
log.Tracef("%s", e)
}
@@ -589,7 +621,7 @@ func (clients *clientsContainer) addFromHostsFile() {
}
}
log.Debug("Added %d client aliases from %s", n, hostsFn)
log.Debug("Clients: added %d client aliases from %s", n, hostsFn)
}
// Add IP -> Host pairs from the system's `arp -a` command output
@@ -609,6 +641,10 @@ func (clients *clientsContainer) addFromSystemARP() {
return
}
clients.lock.Lock()
defer clients.lock.Unlock()
_ = clients.rmHosts(ClientSourceARP)
n := 0
lines := strings.Split(string(data), "\n")
for _, ln := range lines {
@@ -625,7 +661,7 @@ func (clients *clientsContainer) addFromSystemARP() {
continue
}
ok, e := clients.AddHost(ip, host, ClientSourceARP)
ok, e := clients.addHost(ip, host, ClientSourceARP)
if e != nil {
log.Tracef("%s", e)
}
@@ -634,24 +670,30 @@ func (clients *clientsContainer) addFromSystemARP() {
}
}
log.Debug("Added %d client aliases from 'arp -a' command output", n)
log.Debug("Clients: added %d client aliases from 'arp -a' command output", n)
}
// add clients from DHCP that have non-empty Hostname property
// Add clients from DHCP that have non-empty Hostname property
func (clients *clientsContainer) addFromDHCP() {
if clients.dhcpServer == nil {
return
}
leases := clients.dhcpServer.Leases()
clients.lock.Lock()
defer clients.lock.Unlock()
_ = clients.rmHosts(ClientSourceDHCP)
leases := clients.dhcpServer.Leases(dhcpd.LeasesAll)
n := 0
for _, l := range leases {
if len(l.Hostname) == 0 {
continue
}
ok, _ := clients.AddHost(l.IP.String(), l.Hostname, ClientSourceDHCP)
ok, _ := clients.addHost(l.IP.String(), l.Hostname, ClientSourceDHCP)
if ok {
n++
}
}
log.Debug("Added %d client aliases from DHCP", n)
log.Debug("Clients: added %d client aliases from DHCP", n)
}