package internal import ( "net/netip" "testing" "github.com/stretchr/testify/require" firewallManager "github.com/netbirdio/netbird/client/firewall/manager" "github.com/netbirdio/netbird/client/internal/peer" "github.com/netbirdio/netbird/client/internal/peerstore" mgmProto "github.com/netbirdio/netbird/shared/management/proto" ) func TestPrefixesContain(t *testing.T) { tests := []struct { name string prefixes []string addr string want bool }{ {name: "own overlay /32 matches", prefixes: []string{"100.110.8.145/32"}, addr: "100.110.8.145", want: true}, {name: "addr inside routed subnet", prefixes: []string{"10.121.0.0/16"}, addr: "10.121.208.4", want: true}, {name: "addr outside subnet", prefixes: []string{"10.121.0.0/16"}, addr: "10.122.0.1", want: false}, {name: "different /32", prefixes: []string{"100.110.8.145/32"}, addr: "100.110.8.146", want: false}, {name: "ipv6 /128 matches", prefixes: []string{"fd00::1/128"}, addr: "fd00::1", want: true}, {name: "no prefixes", prefixes: nil, addr: "10.121.208.4", want: false}, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { prefixes := make([]netip.Prefix, 0, len(tt.prefixes)) for _, p := range tt.prefixes { prefixes = append(prefixes, netip.MustParsePrefix(p)) } require.Equal(t, tt.want, prefixesContain(prefixes, netip.MustParseAddr(tt.addr))) }) } } // TestToExcludedLazyPeers_ForwardTarget guards a regression: the forward-target // peer (the peer routing a ForwardRule.TranslatedAddress) must be excluded from // lazy connections, matched via the peer's already-parsed AllowedIPs. func TestToExcludedLazyPeers_ForwardTarget(t *testing.T) { const targetPeerKey = "cccccccccccccccccccccccccccccccccccccccccc0=" const otherPeerKey = "dddddddddddddddddddddddddddddddddddddddddd0=" store := peerstore.NewConnStore() store.AddPeerConn(targetPeerKey, newTestConn(t, targetPeerKey, "100.110.8.145/32")) store.AddPeerConn(otherPeerKey, newTestConn(t, otherPeerKey, "100.110.9.10/32")) e := &Engine{peerStore: store} peers := []*mgmProto.RemotePeerConfig{ {WgPubKey: targetPeerKey, AllowedIps: []string{"100.110.8.145/32"}}, {WgPubKey: otherPeerKey, AllowedIps: []string{"100.110.9.10/32"}}, } rules := []firewallManager.ForwardRule{ {TranslatedAddress: netip.MustParseAddr("100.110.8.145")}, } excluded := e.toExcludedLazyPeers(rules, peers) require.True(t, excluded[targetPeerKey], "forward-target peer must be excluded from lazy connections") require.False(t, excluded[otherPeerKey], "non-target peer must not be excluded") require.Len(t, excluded, 1) } func TestToExcludedLazyPeers_NoRules(t *testing.T) { e := &Engine{peerStore: peerstore.NewConnStore()} peers := []*mgmProto.RemotePeerConfig{ {WgPubKey: "peer-a", AllowedIps: []string{"100.110.8.145/32"}}, } require.Empty(t, e.toExcludedLazyPeers(nil, peers)) } func newTestConn(t *testing.T, key, allowedIP string) *peer.Conn { t.Helper() conn, err := peer.NewConn(peer.ConnConfig{ Key: key, WgConfig: peer.WgConfig{AllowedIps: []netip.Prefix{netip.MustParsePrefix(allowedIP)}}, }, peer.ServiceDependencies{}) require.NoError(t, err) return conn }