fix: support ipv6 dual stack (#1148)

Fixes https://github.com/vacp2p/nim-libp2p/issues/1147
This commit is contained in:
diegomrsantos 2024-07-10 18:08:52 +02:00 committed by GitHub
parent 86563cbddd
commit fa19bbbbb7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 43 additions and 49 deletions

View File

@ -97,52 +97,49 @@ proc getWildcardMultiAddresses(
proc getWildcardAddress(
maddress: MultiAddress,
multiCodec: MultiCodec,
anyAddr: openArray[uint8],
addrFamily: AddressFamily,
port: Port,
networkInterfaceProvider: NetworkInterfaceProvider,
): seq[MultiAddress] =
var addresses: seq[MultiAddress]
maddress.getProtocolArgument(multiCodec).withValue(address):
if address == anyAddr:
let filteredInterfaceAddresses = networkInterfaceProvider(addrFamily)
addresses.add(
getWildcardMultiAddresses(filteredInterfaceAddresses, IPPROTO_TCP, port)
)
else:
addresses.add(maddress)
return addresses
let filteredInterfaceAddresses = networkInterfaceProvider(addrFamily)
getWildcardMultiAddresses(filteredInterfaceAddresses, IPPROTO_TCP, port)
proc expandWildcardAddresses(
networkInterfaceProvider: NetworkInterfaceProvider, listenAddrs: seq[MultiAddress]
): seq[MultiAddress] =
var addresses: seq[MultiAddress]
# In this loop we expand bound addresses like `0.0.0.0` and `::` to list of interface addresses.
for listenAddr in listenAddrs:
if TCP_IP.matchPartial(listenAddr):
listenAddr.getProtocolArgument(multiCodec("tcp")).withValue(portArg):
let port = Port(uint16.fromBytesBE(portArg))
if IP4.matchPartial(listenAddr):
let wildcardAddresses = getWildcardAddress(
listenAddr,
multiCodec("ip4"),
AnyAddress.address_v4,
AddressFamily.IPv4,
port,
networkInterfaceProvider,
)
addresses.add(wildcardAddresses)
listenAddr.getProtocolArgument(multiCodec("ip4")).withValue(ip4):
if ip4 == AnyAddress.address_v4:
addresses.add(
getWildcardAddress(
listenAddr, AddressFamily.IPv4, port, networkInterfaceProvider
)
)
else:
addresses.add(listenAddr)
elif IP6.matchPartial(listenAddr):
let wildcardAddresses = getWildcardAddress(
listenAddr,
multiCodec("ip6"),
AnyAddress6.address_v6,
AddressFamily.IPv6,
port,
networkInterfaceProvider,
)
addresses.add(wildcardAddresses)
listenAddr.getProtocolArgument(multiCodec("ip6")).withValue(ip6):
if ip6 == AnyAddress6.address_v6:
addresses.add(
getWildcardAddress(
listenAddr, AddressFamily.IPv6, port, networkInterfaceProvider
)
)
# IPv6 dual stack
addresses.add(
getWildcardAddress(
listenAddr, AddressFamily.IPv4, port, networkInterfaceProvider
)
)
else:
addresses.add(listenAddr)
else:
addresses.add(listenAddr)
else:

View File

@ -24,4 +24,5 @@ import
testbufferstream, testidentify, testobservedaddrmanager, testconnmngr, testswitch,
testnoise, testpeerinfo, testpeerstore, testping, testmplex, testrelayv1, testrelayv2,
testrendezvous, testdiscovery, testyamux, testautonat, testautonatservice,
testautorelay, testdcutr, testhpservice, testutility, testhelpers
testautorelay, testdcutr, testhpservice, testutility, testhelpers,
testwildcardresolverservice

View File

@ -38,18 +38,11 @@ proc getAddressesMock(
echo "Error: " & $e.msg
fail()
proc createSwitch(svc: Service): Switch =
proc createSwitch(svc: Service, addrs: seq[MultiAddress]): Switch =
SwitchBuilder
.new()
.withRng(newRng())
.withAddresses(
@[
MultiAddress.init("/ip4/127.0.0.1/tcp/0/").tryGet(),
MultiAddress.init("/ip4/0.0.0.0/tcp/0/").tryGet(),
MultiAddress.init("/ip6/::/tcp/0/").tryGet(),
],
false,
)
.withAddresses(addrs, false)
.withTcpTransport()
.withMplex()
.withNoise()
@ -63,19 +56,19 @@ suite "WildcardAddressResolverService":
asyncTest "WildcardAddressResolverService must resolve wildcard addresses and stop doing so when stopped":
let svc: Service =
WildcardAddressResolverService.new(networkInterfaceProvider = getAddressesMock)
let switch = createSwitch(svc)
let switch = createSwitch(
svc,
@[
MultiAddress.init("/ip4/127.0.0.1/tcp/0/").tryGet(),
MultiAddress.init("/ip4/0.0.0.0/tcp/0/").tryGet(),
MultiAddress.init("/ip6/::/tcp/0/").tryGet(),
],
)
await switch.start()
let tcpIp4Locahost = switch.peerInfo.addrs[0][multiCodec("tcp")].get
let tcpIp4Wildcard = switch.peerInfo.addrs[1][multiCodec("tcp")].get
let tcpIp6 = switch.peerInfo.addrs[2][multiCodec("tcp")].get # tcp port for ip6
let tcpIp6 = switch.peerInfo.addrs[3][multiCodec("tcp")].get # tcp port for ip6
check switch.peerInfo.addrs ==
@[
MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4Locahost).get,
MultiAddress.init("/ip4/0.0.0.0" & $tcpIp4Wildcard).get,
MultiAddress.init("/ip6/::" & $tcpIp6).get,
]
await svc.run(switch)
check switch.peerInfo.addrs ==
@[
MultiAddress.init("/ip4/127.0.0.1" & $tcpIp4Locahost).get,
@ -83,6 +76,9 @@ suite "WildcardAddressResolverService":
MultiAddress.init("/ip4/192.168.1.22" & $tcpIp4Wildcard).get,
MultiAddress.init("/ip6/::1" & $tcpIp6).get,
MultiAddress.init("/ip6/fe80::1" & $tcpIp6).get,
# IPv6 dual stack
MultiAddress.init("/ip4/127.0.0.1" & $tcpIp6).get,
MultiAddress.init("/ip4/192.168.1.22" & $tcpIp6).get,
]
await switch.stop()
check switch.peerInfo.addrs ==