diff --git a/client/internal/peer/status.go b/client/internal/peer/status.go index bd576287b..568be26e3 100644 --- a/client/internal/peer/status.go +++ b/client/internal/peer/status.go @@ -34,6 +34,11 @@ type EventListener interface { OnEvent(event *proto.SystemEvent) } +type RouteWithResourceId struct { + Route string + ResourceId string +} + // State contains the latest state of a peer type State struct { Mux *sync.RWMutex @@ -53,40 +58,51 @@ type State struct { BytesRx int64 Latency time.Duration RosenpassEnabled bool - routes map[string]struct{} + routes map[RouteWithResourceId]struct{} } // AddRoute add a single route to routes map -func (s *State) AddRoute(network string) { +func (s *State) AddRoute(network, resourceId string) { s.Mux.Lock() defer s.Mux.Unlock() if s.routes == nil { - s.routes = make(map[string]struct{}) + s.routes = make(map[RouteWithResourceId]struct{}) } - s.routes[network] = struct{}{} + s.routes[RouteWithResourceId{network, resourceId}] = struct{}{} } // SetRoutes set state routes -func (s *State) SetRoutes(routes map[string]struct{}) { +func (s *State) SetRoutes(routes map[RouteWithResourceId]struct{}) { s.Mux.Lock() defer s.Mux.Unlock() s.routes = routes } // DeleteRoute removes a route from the network amp -func (s *State) DeleteRoute(network string) { +func (s *State) DeleteRoute(network, resourceId string) { s.Mux.Lock() defer s.Mux.Unlock() - delete(s.routes, network) + delete(s.routes, RouteWithResourceId{network, resourceId}) } // GetRoutes return routes map -func (s *State) GetRoutes() map[string]struct{} { +func (s *State) GetRoutes() map[RouteWithResourceId]struct{} { s.Mux.RLock() defer s.Mux.RUnlock() return maps.Clone(s.routes) } +// GetRoutes return routes map +func (s *State) GetRoutesSlice() []string { + s.Mux.RLock() + defer s.Mux.RUnlock() + routes := make([]string, 0, len(s.routes)) + for route := range s.routes { + routes = append(routes, route.Route) + } + return routes +} + // LocalPeerState contains the latest state of the local peer type LocalPeerState struct { IP string @@ -311,7 +327,7 @@ func (d *Status) UpdatePeerState(receivedState State) error { return nil } -func (d *Status) AddPeerStateRoute(peer string, route string) error { +func (d *Status) AddPeerStateRoute(peer string, route string, resourceId string) error { d.mux.Lock() defer d.mux.Unlock() @@ -320,7 +336,7 @@ func (d *Status) AddPeerStateRoute(peer string, route string) error { return errors.New("peer doesn't exist") } - peerState.AddRoute(route) + peerState.AddRoute(route, resourceId) d.peers[peer] = peerState // todo: consider to make sense of this notification or not @@ -328,7 +344,7 @@ func (d *Status) AddPeerStateRoute(peer string, route string) error { return nil } -func (d *Status) RemovePeerStateRoute(peer string, route string) error { +func (d *Status) RemovePeerStateRoute(peer string, route string, resourceId string) error { d.mux.Lock() defer d.mux.Unlock() @@ -337,7 +353,7 @@ func (d *Status) RemovePeerStateRoute(peer string, route string) error { return errors.New("peer doesn't exist") } - peerState.DeleteRoute(route) + peerState.DeleteRoute(route, resourceId) d.peers[peer] = peerState // todo: consider to make sense of this notification or not @@ -375,7 +391,7 @@ func (d *Status) CheckRoutes(src, dst netip.Addr) (srcMatchedPeerIP string, dstM for _, peer := range d.peers { peerRoutes := peer.GetRoutes() for route := range peerRoutes { - prefix, err := netip.ParsePrefix(route) + prefix, err := netip.ParsePrefix(route.Route) if err != nil { log.Debugf("failed to parse route %s: %v", route, err) continue diff --git a/client/internal/routemanager/client.go b/client/internal/routemanager/client.go index 6680f727a..430d74823 100644 --- a/client/internal/routemanager/client.go +++ b/client/internal/routemanager/client.go @@ -255,7 +255,7 @@ func (c *clientNetwork) startPeersStatusChangeWatcher() { } func (c *clientNetwork) removeRouteFromWireGuardPeer() error { - if err := c.statusRecorder.RemovePeerStateRoute(c.currentChosen.Peer, c.handler.String()); err != nil { + if err := c.statusRecorder.RemovePeerStateRoute(c.currentChosen.Peer, c.handler.String(), c.currentChosen.GetResourceID()); err != nil { log.Warnf("Failed to update peer state: %v", err) } @@ -330,7 +330,7 @@ func (c *clientNetwork) recalculateRouteAndUpdatePeerAndSystem(rsn reason) error c.connectEvent() } - err := c.statusRecorder.AddPeerStateRoute(c.currentChosen.Peer, c.handler.String()) + err := c.statusRecorder.AddPeerStateRoute(c.currentChosen.Peer, c.handler.String(), c.currentChosen.GetResourceID()) if err != nil { return fmt.Errorf("add peer state route: %w", err) } diff --git a/client/ios/NetBirdSDK/client.go b/client/ios/NetBirdSDK/client.go index 622f8e840..19a85eb27 100644 --- a/client/ios/NetBirdSDK/client.go +++ b/client/ios/NetBirdSDK/client.go @@ -155,7 +155,7 @@ func (c *Client) GetStatusDetails() *StatusDetails { for n, p := range fullStatus.Peers { var routes = RoutesDetails{} for r := range p.GetRoutes() { - routeInfo := RoutesInfo{r} + routeInfo := RoutesInfo{r.Route} routes.items = append(routes.items, routeInfo) } pi := PeerInfo{ diff --git a/client/server/debug.go b/client/server/debug.go index 749220d62..d5b0002f3 100644 --- a/client/server/debug.go +++ b/client/server/debug.go @@ -614,7 +614,7 @@ func seedFromStatus(a *anonymize.Anonymizer, status *peer.FullStatus) { for _, peer := range status.Peers { a.AnonymizeDomain(peer.FQDN) for route := range peer.GetRoutes() { - a.AnonymizeRoute(route) + a.AnonymizeRoute(route.Route) } } diff --git a/client/server/server.go b/client/server/server.go index 8907f541f..d3610e553 100644 --- a/client/server/server.go +++ b/client/server/server.go @@ -829,7 +829,7 @@ func toProtoFullStatus(fullStatus peer.FullStatus) *proto.FullStatus { BytesRx: peerState.BytesRx, BytesTx: peerState.BytesTx, RosenpassEnabled: peerState.RosenpassEnabled, - Networks: maps.Keys(peerState.GetRoutes()), + Networks: peerState.GetRoutesSlice(), Latency: durationpb.New(peerState.Latency), } pbFullStatus.Peers = append(pbFullStatus.Peers, pbPeerState)