mirror of
https://github.com/netbirdio/netbird.git
synced 2026-04-16 07:16:38 +00:00
[client] Fix bind exclusion routes (#4154)
This commit is contained in:
@@ -6,6 +6,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/netip"
|
||||
"sync"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -17,11 +18,16 @@ type ListenerWriteHookFunc func(connID ConnectionID, ip *net.IPAddr, data []byte
|
||||
// ListenerCloseHookFunc defines the function signature for close hooks for PacketConn.
|
||||
type ListenerCloseHookFunc func(connID ConnectionID, conn net.PacketConn) error
|
||||
|
||||
// ListenerAddressRemoveHookFunc defines the function signature for hooks called when addresses are removed.
|
||||
type ListenerAddressRemoveHookFunc func(connID ConnectionID, prefix netip.Prefix) error
|
||||
|
||||
var (
|
||||
listenerWriteHooksMutex sync.RWMutex
|
||||
listenerWriteHooks []ListenerWriteHookFunc
|
||||
listenerCloseHooksMutex sync.RWMutex
|
||||
listenerCloseHooks []ListenerCloseHookFunc
|
||||
listenerWriteHooksMutex sync.RWMutex
|
||||
listenerWriteHooks []ListenerWriteHookFunc
|
||||
listenerCloseHooksMutex sync.RWMutex
|
||||
listenerCloseHooks []ListenerCloseHookFunc
|
||||
listenerAddressRemoveHooksMutex sync.RWMutex
|
||||
listenerAddressRemoveHooks []ListenerAddressRemoveHookFunc
|
||||
)
|
||||
|
||||
// AddListenerWriteHook allows adding a new write hook to be executed before a UDP packet is sent.
|
||||
@@ -38,7 +44,14 @@ func AddListenerCloseHook(hook ListenerCloseHookFunc) {
|
||||
listenerCloseHooks = append(listenerCloseHooks, hook)
|
||||
}
|
||||
|
||||
// RemoveListenerHooks removes all dialer hooks.
|
||||
// AddListenerAddressRemoveHook allows adding a new hook to be executed when an address is removed.
|
||||
func AddListenerAddressRemoveHook(hook ListenerAddressRemoveHookFunc) {
|
||||
listenerAddressRemoveHooksMutex.Lock()
|
||||
defer listenerAddressRemoveHooksMutex.Unlock()
|
||||
listenerAddressRemoveHooks = append(listenerAddressRemoveHooks, hook)
|
||||
}
|
||||
|
||||
// RemoveListenerHooks removes all listener hooks.
|
||||
func RemoveListenerHooks() {
|
||||
listenerWriteHooksMutex.Lock()
|
||||
defer listenerWriteHooksMutex.Unlock()
|
||||
@@ -47,6 +60,10 @@ func RemoveListenerHooks() {
|
||||
listenerCloseHooksMutex.Lock()
|
||||
defer listenerCloseHooksMutex.Unlock()
|
||||
listenerCloseHooks = nil
|
||||
|
||||
listenerAddressRemoveHooksMutex.Lock()
|
||||
defer listenerAddressRemoveHooksMutex.Unlock()
|
||||
listenerAddressRemoveHooks = nil
|
||||
}
|
||||
|
||||
// ListenPacket listens on the network address and returns a PacketConn
|
||||
@@ -61,6 +78,7 @@ func (l *ListenerConfig) ListenPacket(ctx context.Context, network, address stri
|
||||
return nil, fmt.Errorf("listen packet: %w", err)
|
||||
}
|
||||
connID := GenerateConnID()
|
||||
|
||||
return &PacketConn{PacketConn: pc, ID: connID, seenAddrs: &sync.Map{}}, nil
|
||||
}
|
||||
|
||||
@@ -102,6 +120,45 @@ func (c *UDPConn) Close() error {
|
||||
return closeConn(c.ID, c.UDPConn)
|
||||
}
|
||||
|
||||
// WrapUDPConn wraps an existing *net.UDPConn with nbnet functionality
|
||||
func WrapUDPConn(conn *net.UDPConn) *UDPConn {
|
||||
return &UDPConn{
|
||||
UDPConn: conn,
|
||||
ID: GenerateConnID(),
|
||||
seenAddrs: &sync.Map{},
|
||||
}
|
||||
}
|
||||
|
||||
// RemoveAddress removes an address from the seen cache and triggers removal hooks.
|
||||
func (c *UDPConn) RemoveAddress(addr string) {
|
||||
if _, exists := c.seenAddrs.LoadAndDelete(addr); !exists {
|
||||
return
|
||||
}
|
||||
|
||||
ipStr, _, err := net.SplitHostPort(addr)
|
||||
if err != nil {
|
||||
log.Errorf("Error splitting IP address and port: %v", err)
|
||||
return
|
||||
}
|
||||
|
||||
ipAddr, err := netip.ParseAddr(ipStr)
|
||||
if err != nil {
|
||||
log.Errorf("Error parsing IP address %s: %v", ipStr, err)
|
||||
return
|
||||
}
|
||||
|
||||
prefix := netip.PrefixFrom(ipAddr, ipAddr.BitLen())
|
||||
|
||||
listenerAddressRemoveHooksMutex.RLock()
|
||||
defer listenerAddressRemoveHooksMutex.RUnlock()
|
||||
|
||||
for _, hook := range listenerAddressRemoveHooks {
|
||||
if err := hook(c.ID, prefix); err != nil {
|
||||
log.Errorf("Error executing listener address remove hook: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func callWriteHooks(id ConnectionID, seenAddrs *sync.Map, b []byte, addr net.Addr) {
|
||||
// Lookup the address in the seenAddrs map to avoid calling the hooks for every write
|
||||
if _, loaded := seenAddrs.LoadOrStore(addr.String(), true); !loaded {
|
||||
|
||||
10
util/net/listener_listen_ios.go
Normal file
10
util/net/listener_listen_ios.go
Normal file
@@ -0,0 +1,10 @@
|
||||
package net
|
||||
|
||||
import (
|
||||
"net"
|
||||
)
|
||||
|
||||
// WrapUDPConn on iOS just returns the original connection since iOS handles its own networking
|
||||
func WrapUDPConn(conn *net.UDPConn) *net.UDPConn {
|
||||
return conn
|
||||
}
|
||||
Reference in New Issue
Block a user