mirror of
https://github.com/netbirdio/netbird.git
synced 2026-07-17 20:19:55 +00:00
Fix route notificaiton
This commit is contained in:
@@ -8,6 +8,7 @@ import (
|
||||
"net/netip"
|
||||
"net/url"
|
||||
"runtime"
|
||||
"slices"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
@@ -142,6 +143,7 @@ func NewManager(config ManagerConfig) *DefaultManager {
|
||||
func (m *DefaultManager) setupAndroidRoutes(config ManagerConfig) {
|
||||
cr := m.initialClientRoutes(config.InitialRoutes)
|
||||
|
||||
routesForComparison := slices.Clone(cr)
|
||||
if config.DNSFeatureFlag {
|
||||
m.fakeIPManager = fakeip.NewManager()
|
||||
|
||||
@@ -156,7 +158,7 @@ func (m *DefaultManager) setupAndroidRoutes(config ManagerConfig) {
|
||||
cr = append(cr, fakeIPRoute)
|
||||
}
|
||||
|
||||
m.notifier.SetInitialClientRoutes(cr, config.DNSFeatureFlag)
|
||||
m.notifier.SetInitialClientRoutes(cr, routesForComparison, config.DNSFeatureFlag)
|
||||
}
|
||||
|
||||
func (m *DefaultManager) setupRefCounters(useNoop bool) {
|
||||
|
||||
@@ -3,6 +3,7 @@ package notifier
|
||||
import (
|
||||
"net/netip"
|
||||
"runtime"
|
||||
"slices"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
@@ -12,8 +13,9 @@ import (
|
||||
)
|
||||
|
||||
type Notifier struct {
|
||||
initialRouteRanges []string
|
||||
routeRanges []string
|
||||
initialRoutes []*route.Route
|
||||
routesForComparison []*route.Route
|
||||
dnsFeatureFlag bool
|
||||
|
||||
listener listener.NetworkChangeListener
|
||||
listenerMux sync.Mutex
|
||||
@@ -29,17 +31,10 @@ func (n *Notifier) SetListener(listener listener.NetworkChangeListener) {
|
||||
n.listener = listener
|
||||
}
|
||||
|
||||
func (n *Notifier) SetInitialClientRoutes(clientRoutes []*route.Route, dnsFeatureFlag bool) {
|
||||
nets := make([]string, 0)
|
||||
for _, r := range clientRoutes {
|
||||
if r.IsDynamic() && !dnsFeatureFlag {
|
||||
// this kind of dynamic route is not supported on android
|
||||
continue
|
||||
}
|
||||
nets = append(nets, r.Network.String())
|
||||
}
|
||||
sort.Strings(nets)
|
||||
n.initialRouteRanges = nets
|
||||
func (n *Notifier) SetInitialClientRoutes(allRoutes []*route.Route, routesForComparison []*route.Route, dnsFeatureFlag bool) {
|
||||
n.dnsFeatureFlag = dnsFeatureFlag
|
||||
n.initialRoutes = allRoutes
|
||||
n.routesForComparison = routesForComparison
|
||||
}
|
||||
|
||||
func (n *Notifier) OnNewRoutes(idMap route.HAMap) {
|
||||
@@ -47,22 +42,16 @@ func (n *Notifier) OnNewRoutes(idMap route.HAMap) {
|
||||
return
|
||||
}
|
||||
|
||||
var newNets []string
|
||||
var newRoutes []*route.Route
|
||||
for _, routes := range idMap {
|
||||
for _, r := range routes {
|
||||
if r.IsDynamic() {
|
||||
continue
|
||||
}
|
||||
newNets = append(newNets, r.Network.String())
|
||||
}
|
||||
newRoutes = append(newRoutes, routes...)
|
||||
}
|
||||
|
||||
sort.Strings(newNets)
|
||||
if !n.hasDiff(n.initialRouteRanges, newNets) {
|
||||
if !n.hasRouteDiff(n.routesForComparison, newRoutes) {
|
||||
return
|
||||
}
|
||||
|
||||
n.routeRanges = newNets
|
||||
n.routesForComparison = newRoutes
|
||||
n.notify()
|
||||
}
|
||||
|
||||
@@ -74,11 +63,12 @@ func (n *Notifier) OnNewPrefixes(prefixes []netip.Prefix) {
|
||||
}
|
||||
|
||||
sort.Strings(newNets)
|
||||
if !n.hasDiff(n.routeRanges, newNets) {
|
||||
|
||||
currentNets := n.routesToStrings(n.routesForComparison)
|
||||
if slices.Equal(currentNets, newNets) {
|
||||
return
|
||||
}
|
||||
|
||||
n.routeRanges = newNets
|
||||
n.notify()
|
||||
}
|
||||
|
||||
@@ -89,37 +79,67 @@ func (n *Notifier) notify() {
|
||||
return
|
||||
}
|
||||
|
||||
routeStrings := n.routesToStrings(n.routesForComparison)
|
||||
sort.Strings(routeStrings)
|
||||
go func(l listener.NetworkChangeListener) {
|
||||
l.OnNetworkChanged(strings.Join(addIPv6RangeIfNeeded(n.routeRanges), ","))
|
||||
l.OnNetworkChanged(strings.Join(n.addIPv6RangeIfNeeded(routeStrings, n.routesForComparison), ","))
|
||||
}(n.listener)
|
||||
}
|
||||
|
||||
func (n *Notifier) hasDiff(a []string, b []string) bool {
|
||||
if len(a) != len(b) {
|
||||
return true
|
||||
}
|
||||
for i, v := range a {
|
||||
if v != b[i] {
|
||||
return true
|
||||
// hasRouteDiff compares two route slices for differences
|
||||
func (n *Notifier) hasRouteDiff(a []*route.Route, b []*route.Route) bool {
|
||||
aFiltered := n.filterRoutes(a)
|
||||
bFiltered := n.filterRoutes(b)
|
||||
|
||||
slices.SortFunc(aFiltered, func(x, y *route.Route) int {
|
||||
return strings.Compare(x.NetString(), y.NetString())
|
||||
})
|
||||
slices.SortFunc(bFiltered, func(x, y *route.Route) int {
|
||||
return strings.Compare(x.NetString(), y.NetString())
|
||||
})
|
||||
|
||||
return !slices.EqualFunc(aFiltered, bFiltered, func(x, y *route.Route) bool {
|
||||
return x.NetString() == y.NetString()
|
||||
})
|
||||
}
|
||||
|
||||
// filterRoutes filters routes based on DNS feature flag
|
||||
func (n *Notifier) filterRoutes(routes []*route.Route) []*route.Route {
|
||||
filtered := make([]*route.Route, 0, len(routes))
|
||||
for _, r := range routes {
|
||||
if r.IsDynamic() && !n.dnsFeatureFlag {
|
||||
// this kind of dynamic route is not supported on android
|
||||
continue
|
||||
}
|
||||
filtered = append(filtered, r)
|
||||
}
|
||||
return false
|
||||
return filtered
|
||||
}
|
||||
|
||||
// routesToStrings converts routes to string slice (caller should sort if needed)
|
||||
func (n *Notifier) routesToStrings(routes []*route.Route) []string {
|
||||
filtered := n.filterRoutes(routes)
|
||||
nets := make([]string, 0, len(filtered))
|
||||
for _, r := range filtered {
|
||||
nets = append(nets, r.NetString())
|
||||
}
|
||||
return nets
|
||||
}
|
||||
|
||||
func (n *Notifier) GetInitialRouteRanges() []string {
|
||||
return addIPv6RangeIfNeeded(n.initialRouteRanges)
|
||||
initialStrings := n.routesToStrings(n.initialRoutes)
|
||||
sort.Strings(initialStrings)
|
||||
return n.addIPv6RangeIfNeeded(initialStrings, n.initialRoutes)
|
||||
}
|
||||
|
||||
// addIPv6RangeIfNeeded returns the input ranges with the default IPv6 range when there is an IPv4 default route.
|
||||
func addIPv6RangeIfNeeded(inputRanges []string) []string {
|
||||
ranges := inputRanges
|
||||
for _, r := range inputRanges {
|
||||
func (n *Notifier) addIPv6RangeIfNeeded(inputRanges []string, routes []*route.Route) []string {
|
||||
for _, r := range routes {
|
||||
// we are intentionally adding the ipv6 default range in case of ipv4 default range
|
||||
// to ensure that all traffic is managed by the tunnel interface on android
|
||||
if r == "0.0.0.0/0" {
|
||||
ranges = append(ranges, "::/0")
|
||||
break
|
||||
if r.Network.Addr().Is4() && r.Network.Bits() == 0 {
|
||||
return append(slices.Clone(inputRanges), "::/0")
|
||||
}
|
||||
}
|
||||
return ranges
|
||||
return inputRanges
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user