|
5 | 5 |
|
6 | 6 | import chronos, random, stew/byteutils |
7 | 7 | import |
8 | | - ../../../libp2p/ |
9 | | - [transports/transport, transports/quictransport, upgrademngrs/upgrade, muxers/muxer] |
| 8 | + ../../../libp2p/[ |
| 9 | + transports/transport, |
| 10 | + transports/quictransport, |
| 11 | + upgrademngrs/upgrade, |
| 12 | + muxers/muxer, |
| 13 | + multiaddress, |
| 14 | + ] |
10 | 15 | import ../../tools/[unittest, crypto as cryptoTools, multiaddress] |
11 | 16 | import ./basic_tests |
12 | 17 | import ./stream_tests |
@@ -50,35 +55,6 @@ suite "Quic transport": |
50 | 55 | streamProvider, |
51 | 56 | ) |
52 | 57 |
|
53 | | - asyncTest "Connection.reset aborts the initiator stream": |
54 | | - var serverResetDone = newFuture[void]() |
55 | | - |
56 | | - proc serverStreamHandler(stream: MuxedStream) {.async: (raises: []).} = |
57 | | - noExceptionWithStreamClose(stream): |
58 | | - let msg = await stream.readLp(100) |
59 | | - check msg == fromHex("1234") |
60 | | - await stream.reset() |
61 | | - serverResetDone.complete() |
62 | | - |
63 | | - proc clientStreamHandler(stream: MuxedStream) {.async: (raises: []).} = |
64 | | - noExceptionWithStreamClose(stream): |
65 | | - await stream.writeLp(fromHex("1234")) |
66 | | - await serverResetDone |
67 | | - |
68 | | - var buffer: array[1, byte] |
69 | | - check (await stream.readOnce(addr buffer[0], 1)) == 0 |
70 | | - |
71 | | - expect LPStreamResetError: |
72 | | - await stream.writeLp(fromHex("1234")) |
73 | | - |
74 | | - await runSingleStreamScenario( |
75 | | - @[MultiAddress.init(addressIP4).get()], |
76 | | - quicTransProvider, |
77 | | - streamProvider, |
78 | | - serverStreamHandler, |
79 | | - clientStreamHandler, |
80 | | - ) |
81 | | - |
82 | 58 | asyncTest "transport e2e - invalid cert - server": |
83 | 59 | let server = await createQuicTransport(isServer = true, withInvalidCert = true) |
84 | 60 | asyncSpawn createServerAcceptConn(server)() |
@@ -131,9 +107,9 @@ suite "Quic transport": |
131 | 107 | discard await client.dial("", server.addrs[0], Opt.some(wrongPeerId)) |
132 | 108 |
|
133 | 109 | asyncTest "should allow multiple local addresses": |
134 | | - let key = PrivateKey.random(ECDSA, rng()).tryGet() |
135 | | - let server = QuicTransport.new(Upgrade(), key) |
136 | | - await server.start(@[QuicAutoAddress, QuicAutoAddress]) |
| 110 | + let server = await createQuicTransport( |
| 111 | + isServer = true, addresses = @[QuicAutoAddress, QuicAutoAddress] |
| 112 | + ) |
137 | 113 | defer: |
138 | 114 | await server.stop() |
139 | 115 |
|
@@ -183,9 +159,9 @@ suite "Quic transport": |
183 | 159 | extractPort(serverConn.observedAddr.get()) == clientListenPort |
184 | 160 |
|
185 | 161 | asyncTest "dial uses dial-only endpoint with multiple listener matches": |
186 | | - let key = PrivateKey.random(ECDSA, rng()).tryGet() |
187 | | - let client = QuicTransport.new(Upgrade(), key) |
188 | | - await client.start(@[QuicAutoAddress, QuicAutoAddress]) |
| 162 | + let client = await createQuicTransport( |
| 163 | + isServer = true, addresses = @[QuicAutoAddress, QuicAutoAddress] |
| 164 | + ) |
189 | 165 | let server = await createQuicTransport(isServer = true) |
190 | 166 | defer: |
191 | 167 | await allFutures(client.stop(), server.stop()) |
@@ -227,6 +203,54 @@ suite "Quic transport": |
227 | 203 | extractPort(serverConn.observedAddr.get()) == |
228 | 204 | extractPort(clientConn.localAddr.get()) |
229 | 205 |
|
| 206 | + asyncTest "dual-stack dialer reuses the matching-family listener": |
| 207 | + # Dialing from the listener endpoint makes the remote observe the listen port. |
| 208 | + # Port reuse and DCUtR hole punching depend on that. |
| 209 | + let dialer = await createQuicTransport( |
| 210 | + isServer = true, addresses = @[QuicAutoAddressIP4, QuicAutoAddressIP6] |
| 211 | + ) |
| 212 | + let server = |
| 213 | + await createQuicTransport(isServer = true, addresses = @[QuicAutoAddressIP6]) |
| 214 | + defer: |
| 215 | + await allFutures(dialer.stop(), server.stop()) |
| 216 | + |
| 217 | + let dialerIPv6Port = extractPort(dialer.addrs.addrByFamily(IP6)) |
| 218 | + |
| 219 | + let acceptFut = server.accept() |
| 220 | + let dialerConn = await dialer.dial("", server.addrs[0]) |
| 221 | + let serverConn = await acceptFut |
| 222 | + defer: |
| 223 | + await allFutures(dialerConn.close(), serverConn.close()) |
| 224 | + |
| 225 | + check: |
| 226 | + serverConn.observedAddr.isSome() |
| 227 | + # same port as the IPv6 listener means that listener was reused |
| 228 | + extractPort(serverConn.observedAddr.get()) == dialerIPv6Port |
| 229 | + |
| 230 | + asyncTest "dial uses an IPv6 dial-only endpoint when only an IPv4 listener exists": |
| 231 | + # An IPv4 socket cannot carry an IPv6 dial, so the IPv4 listener cannot be |
| 232 | + # reused and a separate IPv6 dial-only endpoint has to be opened. |
| 233 | + let dialer = |
| 234 | + await createQuicTransport(isServer = true, addresses = @[QuicAutoAddressIP4]) |
| 235 | + let server = |
| 236 | + await createQuicTransport(isServer = true, addresses = @[QuicAutoAddressIP6]) |
| 237 | + defer: |
| 238 | + await allFutures(dialer.stop(), server.stop()) |
| 239 | + |
| 240 | + let dialerIPv4Port = extractPort(dialer.addrs[0]) |
| 241 | + |
| 242 | + let acceptFut = server.accept() |
| 243 | + let dialerConn = await dialer.dial("", server.addrs[0]) |
| 244 | + let serverConn = await acceptFut |
| 245 | + defer: |
| 246 | + await allFutures(dialerConn.close(), serverConn.close()) |
| 247 | + |
| 248 | + check: |
| 249 | + dialer.addrs.len == 1 |
| 250 | + serverConn.observedAddr.isSome() |
| 251 | + # a different port than the IPv4 listener means a separate endpoint was used |
| 252 | + extractPort(serverConn.observedAddr.get()) != dialerIPv4Port |
| 253 | + |
230 | 254 | asyncTest "server not accepting": |
231 | 255 | let server = await createQuicTransport(isServer = true) |
232 | 256 | # intentionally not calling createServerAcceptConn as server should not accept |
|
0 commit comments