mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-07-04 01:07:49 +02:00
internal: only delete old ipv6 if it is non-link local
So the client is removed from table only when it's global ipv6 changed.
This commit is contained in:
committed by
Cuong Manh Le
parent
affef963c1
commit
b002dff624
+14
-10
@@ -15,6 +15,7 @@ import (
|
|||||||
"github.com/mdlayher/ndp"
|
"github.com/mdlayher/ndp"
|
||||||
|
|
||||||
"github.com/Control-D-Inc/ctrld"
|
"github.com/Control-D-Inc/ctrld"
|
||||||
|
ctrldnet "github.com/Control-D-Inc/ctrld/internal/net"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ndpDiscover provides client discovery functionality using NDP protocol.
|
// ndpDiscover provides client discovery functionality using NDP protocol.
|
||||||
@@ -70,20 +71,23 @@ func (nd *ndpDiscover) List() []string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// saveInfo saves ip and mac info to mapping table.
|
// saveInfo saves ip and mac info to mapping table.
|
||||||
// If force is true, old ip will be removed before saving.
|
func (nd *ndpDiscover) saveInfo(ip, mac string) {
|
||||||
func (nd *ndpDiscover) saveInfo(ip, mac string, force bool) {
|
|
||||||
ip = normalizeIP(ip)
|
ip = normalizeIP(ip)
|
||||||
// Store ip => map mapping,
|
// Store ip => map mapping,
|
||||||
nd.mac.Store(ip, mac)
|
nd.mac.Store(ip, mac)
|
||||||
|
|
||||||
if force {
|
// Do not store mac => ip mapping if new ip is a link local unicast.
|
||||||
// If there is old ip => mac mapping, delete it.
|
if ctrldnet.IsLinkLocalUnicastIPv6(ip) {
|
||||||
if old, ok := nd.ip.Load(mac); ok {
|
return
|
||||||
oldIP := old.(string)
|
}
|
||||||
|
|
||||||
|
// If there is old ip => mac mapping, delete it.
|
||||||
|
if old, existed := nd.ip.Load(mac); existed {
|
||||||
|
oldIP := old.(string)
|
||||||
|
if oldIP != ip {
|
||||||
nd.mac.Delete(oldIP)
|
nd.mac.Delete(oldIP)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Store mac => ip mapping.
|
// Store mac => ip mapping.
|
||||||
nd.ip.Store(mac, ip)
|
nd.ip.Store(mac, ip)
|
||||||
}
|
}
|
||||||
@@ -138,7 +142,7 @@ func (nd *ndpDiscover) listenOnInterface(ctx context.Context, ifi *net.Interface
|
|||||||
for _, opt := range am.Options {
|
for _, opt := range am.Options {
|
||||||
if lla, ok := opt.(*ndp.LinkLayerAddress); ok {
|
if lla, ok := opt.(*ndp.LinkLayerAddress); ok {
|
||||||
mac := lla.Addr.String()
|
mac := lla.Addr.String()
|
||||||
nd.saveInfo(fromIP, mac, true)
|
nd.saveInfo(fromIP, mac)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,7 +157,7 @@ func (nd *ndpDiscover) scanWindows(r io.Reader) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
if mac := parseMAC(fields[1]); mac != "" {
|
if mac := parseMAC(fields[1]); mac != "" {
|
||||||
nd.saveInfo(fields[0], mac, true)
|
nd.saveInfo(fields[0], mac)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,7 +176,7 @@ func (nd *ndpDiscover) scanUnix(r io.Reader) {
|
|||||||
if idx := strings.IndexByte(ip, '%'); idx != -1 {
|
if idx := strings.IndexByte(ip, '%'); idx != -1 {
|
||||||
ip = ip[:idx]
|
ip = ip[:idx]
|
||||||
}
|
}
|
||||||
nd.saveInfo(ip, mac, true)
|
nd.saveInfo(ip, mac)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ func (nd *ndpDiscover) scan() {
|
|||||||
}
|
}
|
||||||
ip := n.IP.String()
|
ip := n.IP.String()
|
||||||
mac := n.HardwareAddr.String()
|
mac := n.HardwareAddr.String()
|
||||||
nd.saveInfo(ip, mac, false)
|
nd.saveInfo(ip, mac)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ func (nd *ndpDiscover) subscribe(ctx context.Context) {
|
|||||||
mac := nu.HardwareAddr.String()
|
mac := nu.HardwareAddr.String()
|
||||||
switch nu.State {
|
switch nu.State {
|
||||||
case netlink.NUD_REACHABLE:
|
case netlink.NUD_REACHABLE:
|
||||||
nd.saveInfo(ip, mac, false)
|
nd.saveInfo(ip, mac)
|
||||||
case netlink.NUD_FAILED:
|
case netlink.NUD_FAILED:
|
||||||
ctrld.ProxyLogger.Load().Debug().Msgf("removing NDP neighbor with failed state: %s", ip)
|
ctrld.ProxyLogger.Load().Debug().Msgf("removing NDP neighbor with failed state: %s", ip)
|
||||||
nd.mac.Delete(ip)
|
nd.mac.Delete(ip)
|
||||||
|
|||||||
@@ -45,18 +45,17 @@ ff02::c 33-33-00-00-00-0c Permanent
|
|||||||
nd.scanWindows(r)
|
nd.scanWindows(r)
|
||||||
|
|
||||||
count := 0
|
count := 0
|
||||||
expectedCount := 5
|
expectedCount := 6
|
||||||
nd.mac.Range(func(key, value any) bool {
|
nd.mac.Range(func(key, value any) bool {
|
||||||
count++
|
count++
|
||||||
return true
|
return true
|
||||||
})
|
})
|
||||||
// There are 2 entries for 60-57-47-21-dd-00 in the table, but (*ndpDiscover).saveInfo
|
|
||||||
// only saves the last one, that's why the expected count number is 5.
|
|
||||||
if count != expectedCount {
|
if count != expectedCount {
|
||||||
t.Errorf("unexpected count, want %d, got: %d", expectedCount, count)
|
t.Errorf("unexpected count, want %d, got: %d", expectedCount, count)
|
||||||
}
|
}
|
||||||
|
|
||||||
count = 0
|
count = 0
|
||||||
|
expectedCount = 4
|
||||||
nd.ip.Range(func(key, value any) bool {
|
nd.ip.Range(func(key, value any) bool {
|
||||||
count++
|
count++
|
||||||
return true
|
return true
|
||||||
|
|||||||
@@ -115,6 +115,15 @@ func IsIPv6(ip string) bool {
|
|||||||
return parsedIP != nil && parsedIP.To4() == nil && parsedIP.To16() != nil
|
return parsedIP != nil && parsedIP.To4() == nil && parsedIP.To16() != nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// IsLinkLocalUnicastIPv6 checks if the provided IP is a link local unicast v6 address.
|
||||||
|
func IsLinkLocalUnicastIPv6(ip string) bool {
|
||||||
|
parsedIP := net.ParseIP(ip)
|
||||||
|
if parsedIP == nil || parsedIP.To4() != nil || parsedIP.To16() == nil {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
return parsedIP.To16().IsLinkLocalUnicast()
|
||||||
|
}
|
||||||
|
|
||||||
type parallelDialerResult struct {
|
type parallelDialerResult struct {
|
||||||
conn net.Conn
|
conn net.Conn
|
||||||
err error
|
err error
|
||||||
|
|||||||
Reference in New Issue
Block a user