mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
65 lines
1.5 KiB
Go
65 lines
1.5 KiB
Go
package clientinfo
|
|
|
|
import (
|
|
"context"
|
|
|
|
"github.com/vishvananda/netlink"
|
|
"golang.org/x/sys/unix"
|
|
|
|
"github.com/Control-D-Inc/ctrld"
|
|
)
|
|
|
|
// scan populates NDP table using information from system mappings.
|
|
func (nd *ndpDiscover) scan() {
|
|
neighs, err := netlink.NeighList(0, netlink.FAMILY_V6)
|
|
if err != nil {
|
|
ctrld.ProxyLogger.Load().Warn().Err(err).Msg("could not get neigh list")
|
|
return
|
|
}
|
|
|
|
for _, n := range neighs {
|
|
// Skipping non-reachable neighbors.
|
|
if n.State&netlink.NUD_REACHABLE == 0 {
|
|
continue
|
|
}
|
|
ip := n.IP.String()
|
|
mac := n.HardwareAddr.String()
|
|
nd.saveInfo(ip, mac)
|
|
}
|
|
}
|
|
|
|
// subscribe watches NDP table changes and update new information to local table.
|
|
func (nd *ndpDiscover) subscribe(ctx context.Context) {
|
|
ch := make(chan netlink.NeighUpdate)
|
|
done := make(chan struct{})
|
|
defer close(done)
|
|
if err := netlink.NeighSubscribe(ch, done); err != nil {
|
|
ctrld.ProxyLogger.Load().Err(err).Msg("could not perform neighbor subscribing")
|
|
return
|
|
}
|
|
for {
|
|
select {
|
|
case <-ctx.Done():
|
|
return
|
|
case nu := <-ch:
|
|
if nu.Family != netlink.FAMILY_V6 {
|
|
continue
|
|
}
|
|
ip := normalizeIP(nu.IP.String())
|
|
if nu.Type == unix.RTM_DELNEIGH {
|
|
ctrld.ProxyLogger.Load().Debug().Msgf("removing NDP neighbor: %s", ip)
|
|
nd.mac.Delete(ip)
|
|
continue
|
|
}
|
|
mac := nu.HardwareAddr.String()
|
|
switch nu.State {
|
|
case netlink.NUD_REACHABLE:
|
|
nd.saveInfo(ip, mac)
|
|
case netlink.NUD_FAILED:
|
|
ctrld.ProxyLogger.Load().Debug().Msgf("removing NDP neighbor with failed state: %s", ip)
|
|
nd.mac.Delete(ip)
|
|
}
|
|
}
|
|
}
|
|
}
|