-
Notifications
You must be signed in to change notification settings - Fork 1.2k
test(transport): add ipv6 coverage to integration tests #3461
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 10 commits
bf2d217
c955178
72d4ae0
91db88e
5d7c37c
ce3363f
c98c1d8
729e18f
073172f
263034f
2625b00
eb2e241
7e887b6
0e3934c
c8ecf00
14d5d51
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -116,6 +116,29 @@ func selfSignedTLSConfig(t *testing.T) *tls.Config { | |
| return tlsConfig | ||
| } | ||
|
|
||
| func skipIfNoIPv6(t *testing.T) { | ||
| t.Helper() | ||
| ln, err := net.Listen("tcp6", "[::1]:0") | ||
| if err != nil { | ||
| t.Skip("IPv6 loopback not available") | ||
| } | ||
| ln.Close() | ||
| } | ||
|
|
||
| // skipWebRTCIPv6OnWindows skips WebRTC IPv6 loopback integration scenarios on Windows only. | ||
| // | ||
| // The test listens on /ip6/::1/udp/.../webrtc-direct. Pion gathers ICE candidates on | ||
| // link-local and global IPv6 interfaces; Windows rejects UDP sends from those addresses | ||
| // to ::1 with wsasendto "The requested address is not valid in its context" (scope | ||
| // mismatch), so packets never leave the stack and a loopback capture shows no IPv6 UDP. | ||
| // Linux CI continues to run this transport case. | ||
| func skipWebRTCIPv6OnWindows(t *testing.T, transportName string) { | ||
| t.Helper() | ||
| if transportName == "WebRTC - IP6" && runtime.GOOS == "windows" { | ||
|
||
| t.Skip(`WebRTC IPv6 over ::1 skipped on Windows: ICE uses non-loopback IPv6 locals; wsasendto to ::1 fails with "The requested address is not valid in its context" (scope mismatch). See PR discussion.`) | ||
| } | ||
| } | ||
|
|
||
| var transportsToTest = []TransportTestCase{ | ||
| { | ||
| Name: "TCP / Noise / Yamux", | ||
|
|
@@ -353,11 +376,108 @@ var transportsToTest = []TransportTestCase{ | |
| return h | ||
| }, | ||
| }, | ||
| { | ||
| Name: "TCP / Noise / Yamux - IP6", | ||
| HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host { | ||
| skipIfNoIPv6(t) | ||
| libp2pOpts := transformOpts(opts) | ||
| libp2pOpts = append(libp2pOpts, libp2p.Security(noise.ID, noise.New)) | ||
| libp2pOpts = append(libp2pOpts, libp2p.Muxer(yamux.ID, yamux.DefaultTransport)) | ||
| if opts.NoListen { | ||
| libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs) | ||
| } else { | ||
| libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip6/::1/tcp/0")) | ||
| } | ||
| h, err := libp2p.New(libp2pOpts...) | ||
| require.NoError(t, err) | ||
| return h | ||
| }, | ||
| }, | ||
| { | ||
| Name: "TCP / TLS / Yamux - IP6", | ||
| HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host { | ||
| skipIfNoIPv6(t) | ||
| libp2pOpts := transformOpts(opts) | ||
| libp2pOpts = append(libp2pOpts, libp2p.Security(libp2ptls.ID, libp2ptls.New)) | ||
| libp2pOpts = append(libp2pOpts, libp2p.Muxer(yamux.ID, yamux.DefaultTransport)) | ||
| if opts.NoListen { | ||
| libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs) | ||
| } else { | ||
| libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip6/::1/tcp/0")) | ||
| } | ||
| h, err := libp2p.New(libp2pOpts...) | ||
| require.NoError(t, err) | ||
| return h | ||
| }, | ||
| }, | ||
| { | ||
| Name: "WebSocket - IP6", | ||
| HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host { | ||
| skipIfNoIPv6(t) | ||
| libp2pOpts := transformOpts(opts) | ||
| if opts.NoListen { | ||
| libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs) | ||
| } else { | ||
| libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip6/::1/tcp/0/ws")) | ||
| } | ||
| h, err := libp2p.New(libp2pOpts...) | ||
| require.NoError(t, err) | ||
| return h | ||
| }, | ||
| }, | ||
| { | ||
| Name: "QUIC - IP6", | ||
| HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host { | ||
| skipIfNoIPv6(t) | ||
| libp2pOpts := transformOpts(opts) | ||
| if opts.NoListen { | ||
| libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs) | ||
| } else { | ||
| libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip6/::1/udp/0/quic-v1")) | ||
| } | ||
| h, err := libp2p.New(libp2pOpts...) | ||
| require.NoError(t, err) | ||
| return h | ||
| }, | ||
| }, | ||
| { | ||
| Name: "WebTransport - IP6", | ||
| HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host { | ||
| skipIfNoIPv6(t) | ||
| libp2pOpts := transformOpts(opts) | ||
| if opts.NoListen { | ||
| libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs) | ||
| } else { | ||
| libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip6/::1/udp/0/quic-v1/webtransport")) | ||
| } | ||
| h, err := libp2p.New(libp2pOpts...) | ||
| require.NoError(t, err) | ||
| return h | ||
| }, | ||
| }, | ||
| { | ||
| Name: "WebRTC - IP6", | ||
| HostGenerator: func(t *testing.T, opts TransportTestCaseOpts) host.Host { | ||
| skipIfNoIPv6(t) | ||
| libp2pOpts := transformOpts(opts) | ||
| libp2pOpts = append(libp2pOpts, libp2p.Transport(libp2pwebrtc.New)) | ||
| if opts.NoListen { | ||
| libp2pOpts = append(libp2pOpts, libp2p.NoListenAddrs) | ||
| } else { | ||
| libp2pOpts = append(libp2pOpts, libp2p.ListenAddrStrings("/ip6/::1/udp/0/webrtc-direct")) | ||
| } | ||
| h, err := libp2p.New(libp2pOpts...) | ||
| require.NoError(t, err) | ||
| return h | ||
| }, | ||
| }, | ||
| } | ||
|
|
||
| func TestPing(t *testing.T) { | ||
|
|
||
|
||
| for _, tc := range transportsToTest { | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| h1 := tc.HostGenerator(t, TransportTestCaseOpts{}) | ||
| h2 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true}) | ||
| defer h1.Close() | ||
|
|
@@ -387,6 +507,7 @@ func TestBigPing(t *testing.T) { | |
|
|
||
| for _, tc := range transportsToTest { | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| h1 := tc.HostGenerator(t, TransportTestCaseOpts{}) | ||
| h2 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true}) | ||
| defer h1.Close() | ||
|
|
@@ -515,6 +636,7 @@ func TestManyStreams(t *testing.T) { | |
| const streamCount = 128 | ||
| for _, tc := range transportsToTest { | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| h1 := tc.HostGenerator(t, TransportTestCaseOpts{NoRcmgr: true}) | ||
| h2 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true, NoRcmgr: true}) | ||
| defer h1.Close() | ||
|
|
@@ -739,6 +861,7 @@ func TestMoreStreamsThanOurLimits(t *testing.T) { | |
| func TestListenerStreamResets(t *testing.T) { | ||
| for _, tc := range transportsToTest { | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| h1 := tc.HostGenerator(t, TransportTestCaseOpts{}) | ||
| h2 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true}) | ||
| defer h1.Close() | ||
|
|
@@ -768,6 +891,7 @@ func TestListenerStreamResets(t *testing.T) { | |
| func TestDialerStreamResets(t *testing.T) { | ||
| for _, tc := range transportsToTest { | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| h1 := tc.HostGenerator(t, TransportTestCaseOpts{}) | ||
| h2 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true}) | ||
| defer h1.Close() | ||
|
|
@@ -799,6 +923,7 @@ func TestDialerStreamResets(t *testing.T) { | |
| func TestStreamReadDeadline(t *testing.T) { | ||
| for _, tc := range transportsToTest { | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| h1 := tc.HostGenerator(t, TransportTestCaseOpts{}) | ||
| h2 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true}) | ||
| defer h1.Close() | ||
|
|
@@ -853,6 +978,7 @@ func TestDiscoverPeerIDFromSecurityNegotiation(t *testing.T) { | |
|
|
||
| for _, tc := range transportsToTest { | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| h1 := tc.HostGenerator(t, TransportTestCaseOpts{}) | ||
| h2 := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true}) | ||
| defer h1.Close() | ||
|
|
@@ -897,6 +1023,7 @@ func TestCloseConnWhenBlocked(t *testing.T) { | |
| continue | ||
| } | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| ctrl := gomock.NewController(t) | ||
| defer ctrl.Finish() | ||
| mockRcmgr := mocknetwork.NewMockResourceManager(ctrl) | ||
|
|
@@ -977,6 +1104,7 @@ func TestConnDroppedWhenBlocked(t *testing.T) { | |
| func TestConnClosedWhenRemoteCloses(t *testing.T) { | ||
| for _, tc := range transportsToTest { | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| server := tc.HostGenerator(t, TransportTestCaseOpts{}) | ||
| client := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true}) | ||
| defer server.Close() | ||
|
|
@@ -1017,6 +1145,7 @@ func TestErrorCodes(t *testing.T) { | |
| continue | ||
| } | ||
| t.Run(tc.Name, func(t *testing.T) { | ||
| skipWebRTCIPv6OnWindows(t, tc.Name) | ||
| server := tc.HostGenerator(t, TransportTestCaseOpts{}) | ||
| client := tc.HostGenerator(t, TransportTestCaseOpts{NoListen: true}) | ||
| defer server.Close() | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,6 +1,6 @@ | ||
| module github.com/libp2p/go-libp2p/test-plans/m/v2 | ||
|
|
||
| go 1.25.7 | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. back this out |
||
| go 1.24.6 | ||
|
|
||
| require ( | ||
| github.com/go-redis/redis/v8 v8.11.5 | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Back these changes out