Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions libp2p/transports/quictransport.nim
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,17 @@ proc listenerEndpointFor(
return ok(Opt.none(QuicEndpoint))
matchedEndpoint = Opt.some(endpoint)

if matchedEndpoint.isSome() or address.family != AddressFamily.IPv4:
return ok(matchedEndpoint)

for endpoint in self.listeners:
let local = endpoint.localAddress()
if local.family == AddressFamily.IPv6 and local.isAnyLocal() and
endpoint.datagramTransport().fd.getDualstack().get(false):
if matchedEndpoint.isSome():
return ok(Opt.none(QuicEndpoint))
matchedEndpoint = Opt.some(endpoint)

ok(matchedEndpoint)

proc newDialEndpoint(
Expand Down
21 changes: 21 additions & 0 deletions tests/libp2p/transports/test_quic.nim
Original file line number Diff line number Diff line change
Expand Up @@ -322,6 +322,27 @@ suite "Quic transport":
# same port as the IPv6 listener means that listener was reused
extractPort(serverConn.observedAddr.get()) == dialerIPv6Port

asyncTest "IPv4 dial reuses an IPv6 wildcard listener":
let dialer = await createQuicTransport(
isServer = true, addresses = @[ma("/ip6/::/udp/0/quic-v1")]
)
let server =
await createQuicTransport(isServer = true, addresses = @[QuicAutoAddressIP4])
defer:
await allFutures(dialer.stop(), server.stop())

let dialerPort = extractPort(dialer.addrs[0])

let acceptFut = server.accept()
let dialerConn = await dialer.dial("", server.addrs[0])
let serverConn = await acceptFut
defer:
await allFutures(dialerConn.close(), serverConn.close())

check:
serverConn.observedAddr.isSome()
extractPort(serverConn.observedAddr.get()) == dialerPort

asyncTest "dial uses an IPv6 dial-only endpoint when only an IPv4 listener exists":
# An IPv4 socket cannot carry an IPv6 dial, so the IPv4 listener cannot be
# reused and a separate IPv6 dial-only endpoint has to be opened.
Expand Down
Loading