2023-08-21 03:50:38 +00:00
|
|
|
package identify
|
|
|
|
|
|
|
|
// This test lives in the identify package, not the identify_test package, so it
|
|
|
|
// can access internal types.
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2024-06-08 11:32:45 +00:00
|
|
|
"sync/atomic"
|
2023-08-21 03:50:38 +00:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
ma "github.com/multiformats/go-multiaddr"
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
)
|
|
|
|
|
|
|
|
type mockConn struct {
|
|
|
|
local, remote ma.Multiaddr
|
2024-06-08 11:32:45 +00:00
|
|
|
isClosed atomic.Bool
|
2023-08-21 03:50:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// LocalMultiaddr implements connMultiaddrProvider
|
|
|
|
func (c *mockConn) LocalMultiaddr() ma.Multiaddr {
|
|
|
|
return c.local
|
|
|
|
}
|
|
|
|
|
|
|
|
// RemoteMultiaddr implements connMultiaddrProvider
|
|
|
|
func (c *mockConn) RemoteMultiaddr() ma.Multiaddr {
|
|
|
|
return c.remote
|
|
|
|
}
|
|
|
|
|
2024-06-08 11:32:45 +00:00
|
|
|
func (c *mockConn) Close() {
|
|
|
|
c.isClosed.Store(true)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *mockConn) IsClosed() bool {
|
|
|
|
return c.isClosed.Load()
|
|
|
|
}
|
|
|
|
|
2023-08-21 03:50:38 +00:00
|
|
|
func TestShouldRecordObservationWithWebTransport(t *testing.T) {
|
2024-10-12 18:55:17 +00:00
|
|
|
listenAddr := tStringCast("/ip4/0.0.0.0/udp/0/quic-v1/webtransport/certhash/uEgNmb28")
|
|
|
|
ifaceAddr := tStringCast("/ip4/10.0.0.2/udp/9999/quic-v1/webtransport/certhash/uEgNmb28")
|
2024-06-08 11:32:45 +00:00
|
|
|
listenAddrs := func() []ma.Multiaddr { return []ma.Multiaddr{listenAddr} }
|
|
|
|
ifaceListenAddrs := func() ([]ma.Multiaddr, error) { return []ma.Multiaddr{ifaceAddr}, nil }
|
|
|
|
addrs := func() []ma.Multiaddr { return []ma.Multiaddr{listenAddr} }
|
|
|
|
|
2023-08-21 03:50:38 +00:00
|
|
|
c := &mockConn{
|
|
|
|
local: listenAddr,
|
2024-10-12 18:55:17 +00:00
|
|
|
remote: tStringCast("/ip4/1.2.3.6/udp/1236/quic-v1/webtransport"),
|
2023-08-21 03:50:38 +00:00
|
|
|
}
|
2024-10-12 18:55:17 +00:00
|
|
|
observedAddr := tStringCast("/ip4/1.2.3.4/udp/1231/quic-v1/webtransport")
|
2024-06-08 11:32:45 +00:00
|
|
|
o, err := NewObservedAddrManager(listenAddrs, addrs, ifaceListenAddrs, normalize)
|
|
|
|
require.NoError(t, err)
|
|
|
|
shouldRecord, _, _ := o.shouldRecordObservation(c, observedAddr)
|
|
|
|
require.True(t, shouldRecord)
|
2023-08-21 03:50:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func TestShouldRecordObservationWithNAT64Addr(t *testing.T) {
|
2024-10-12 18:55:17 +00:00
|
|
|
listenAddr1 := tStringCast("/ip4/0.0.0.0/tcp/1234")
|
|
|
|
ifaceAddr1 := tStringCast("/ip4/10.0.0.2/tcp/4321")
|
|
|
|
listenAddr2 := tStringCast("/ip6/::/tcp/1234")
|
|
|
|
ifaceAddr2 := tStringCast("/ip6/1::1/tcp/4321")
|
2023-08-21 03:50:38 +00:00
|
|
|
|
2024-06-08 11:32:45 +00:00
|
|
|
var (
|
|
|
|
listenAddrs = func() []ma.Multiaddr { return []ma.Multiaddr{listenAddr1, listenAddr2} }
|
|
|
|
ifaceListenAddrs = func() ([]ma.Multiaddr, error) { return []ma.Multiaddr{ifaceAddr1, ifaceAddr2}, nil }
|
|
|
|
addrs = func() []ma.Multiaddr { return []ma.Multiaddr{listenAddr1, listenAddr2} }
|
|
|
|
)
|
2023-08-21 03:50:38 +00:00
|
|
|
c := &mockConn{
|
|
|
|
local: listenAddr1,
|
2024-10-12 18:55:17 +00:00
|
|
|
remote: tStringCast("/ip4/1.2.3.6/tcp/4321"),
|
2023-08-21 03:50:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
cases := []struct {
|
|
|
|
addr ma.Multiaddr
|
|
|
|
want bool
|
|
|
|
failureReason string
|
|
|
|
}{
|
|
|
|
{
|
2024-10-12 18:55:17 +00:00
|
|
|
addr: tStringCast("/ip4/1.2.3.4/tcp/1234"),
|
2023-08-21 03:50:38 +00:00
|
|
|
want: true,
|
|
|
|
failureReason: "IPv4 should be observed",
|
|
|
|
},
|
|
|
|
{
|
2024-10-12 18:55:17 +00:00
|
|
|
addr: tStringCast("/ip6/1::4/tcp/1234"),
|
2023-08-21 03:50:38 +00:00
|
|
|
want: true,
|
|
|
|
failureReason: "public IPv6 address should be observed",
|
|
|
|
},
|
|
|
|
{
|
2024-10-12 18:55:17 +00:00
|
|
|
addr: tStringCast("/ip6/64:ff9b::192.0.1.2/tcp/1234"),
|
2023-08-21 03:50:38 +00:00
|
|
|
want: false,
|
|
|
|
failureReason: "NAT64 IPv6 address shouldn't be observed",
|
|
|
|
},
|
|
|
|
}
|
2024-06-08 11:32:45 +00:00
|
|
|
|
|
|
|
o, err := NewObservedAddrManager(listenAddrs, addrs, ifaceListenAddrs, normalize)
|
|
|
|
require.NoError(t, err)
|
2023-08-21 03:50:38 +00:00
|
|
|
for i, tc := range cases {
|
|
|
|
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
|
|
|
|
2024-06-08 11:32:45 +00:00
|
|
|
if shouldRecord, _, _ := o.shouldRecordObservation(c, tc.addr); shouldRecord != tc.want {
|
2023-08-21 03:50:38 +00:00
|
|
|
t.Fatalf("%s %s", tc.addr, tc.failureReason)
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
2024-06-08 11:32:45 +00:00
|
|
|
|
|
|
|
func TestThinWaistForm(t *testing.T) {
|
|
|
|
tc := []struct {
|
|
|
|
input string
|
|
|
|
tw string
|
|
|
|
rest string
|
|
|
|
err bool
|
|
|
|
}{{
|
|
|
|
input: "/ip4/1.2.3.4/tcp/1",
|
|
|
|
tw: "/ip4/1.2.3.4/tcp/1",
|
|
|
|
rest: "",
|
|
|
|
}, {
|
|
|
|
input: "/ip4/1.2.3.4/tcp/1/ws",
|
|
|
|
tw: "/ip4/1.2.3.4/tcp/1",
|
|
|
|
rest: "/ws",
|
|
|
|
}, {
|
|
|
|
input: "/ip4/127.0.0.1/udp/1/quic-v1",
|
|
|
|
tw: "/ip4/127.0.0.1/udp/1",
|
|
|
|
rest: "/quic-v1",
|
|
|
|
}, {
|
|
|
|
input: "/ip4/1.2.3.4/udp/1/quic-v1/webtransport",
|
|
|
|
tw: "/ip4/1.2.3.4/udp/1",
|
|
|
|
rest: "/quic-v1/webtransport",
|
|
|
|
}, {
|
|
|
|
input: "/ip4/1.2.3.4/",
|
|
|
|
err: true,
|
|
|
|
}, {
|
|
|
|
input: "/tcp/1",
|
|
|
|
err: true,
|
|
|
|
}, {
|
|
|
|
input: "/ip6/::1/tcp/1",
|
|
|
|
tw: "/ip6/::1/tcp/1",
|
|
|
|
rest: "",
|
|
|
|
}}
|
|
|
|
for i, tt := range tc {
|
|
|
|
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
|
2024-10-12 18:55:17 +00:00
|
|
|
inputAddr := tStringCast(tt.input)
|
2024-06-08 11:32:45 +00:00
|
|
|
tw, err := thinWaistForm(inputAddr)
|
|
|
|
if tt.err {
|
|
|
|
require.Equal(t, tw, thinWaist{})
|
|
|
|
require.Error(t, err)
|
|
|
|
return
|
|
|
|
}
|
2024-10-12 18:55:17 +00:00
|
|
|
wantTW := tStringCast(tt.tw)
|
2024-06-08 11:32:45 +00:00
|
|
|
var restTW ma.Multiaddr
|
|
|
|
if tt.rest != "" {
|
2024-10-12 18:55:17 +00:00
|
|
|
restTW = tStringCast(tt.rest)
|
2024-06-08 11:32:45 +00:00
|
|
|
}
|
|
|
|
require.Equal(t, tw.Addr, inputAddr, "%s %s", tw.Addr, inputAddr)
|
|
|
|
require.Equal(t, wantTW, tw.TW, "%s %s", tw.TW, wantTW)
|
|
|
|
require.Equal(t, restTW, tw.Rest, "%s %s", restTW, tw.Rest)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|