Skip to content

Commit a4861df

Browse files
committed
Portal: Add IPv6 support
1 parent a4e9ac3 commit a4861df

File tree

5 files changed

+115
-22
lines changed

5 files changed

+115
-22
lines changed

portal/client/nimbus_portal_client.nim

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -102,16 +102,64 @@ proc run(portalClient: PortalClient, config: PortalConf) {.raises: [CatchableErr
102102
)
103103

104104
## Network configuration
105+
##
106+
## - bind IP is dual stack:
107+
## - both enrIpv6Address and nat:extip set: use those
108+
## - only nat:extip set: use nat:extip for v4 and getBestRoute for v6
109+
## - only enrIpv6Address set: use enrIpv6Address for v6 and getBestRoute + nat for v4
110+
## - none set: use getBestRoute + nat for v4 and getBestRoute for v6
111+
## - bind IP is only v4:
112+
## - nat:extip set: use nat:extip for v4
113+
## - none set: use getBestRoute + nat for v4
114+
## - bind IP is only v6:
115+
## - enrIpv6Address set: use enrIpv6Address for v6
116+
## - none set: use getBestRoute for v6
117+
105118
let
106-
bindIp = config.listenAddress
107119
udpPort = Port(config.udpPort)
108-
(extIp, extPorts) = setupAddress(
109-
config.nat,
110-
config.listenAddress,
111-
@[(port: udpPort, protocol: PortProtocol.UDP)],
112-
"nimbus_portal_client",
113-
)
114-
extUdpPort = extPorts[0].toPort()
120+
listenAddress =
121+
if config.listenAddress.isSome():
122+
config.listenAddress.get()
123+
else:
124+
getAutoAddress(Port(0)).toIpAddress()
125+
126+
(extIp4, extIp6, extUdpPort) =
127+
if listenAddress == AnyAddress6.toIpAddress():
128+
let
129+
extIp6 =
130+
if config.enrIpv6Address.isSome():
131+
Opt.some(config.enrIpv6Address.get())
132+
else:
133+
getRoutePrefSrcv6(listenAddress)
134+
135+
(extIp4, extPorts) = setupAddress(
136+
config.nat,
137+
listenAddress,
138+
@[(port: udpPort, protocol: PortProtocol.UDP)],
139+
"nimbus_portal_client",
140+
)
141+
extUdpPort = extPorts[0].toPort()
142+
143+
(extIp4, extIp6, extUdpPort)
144+
elif listenAddress.family == IpAddressFamily.IPv6:
145+
let extIp6 =
146+
if config.enrIpv6Address.isSome():
147+
Opt.some(config.enrIpv6Address.get())
148+
else:
149+
getRoutePrefSrcv6(listenAddress)
150+
(Opt.none(IpAddress), extIp6, Opt.some(udpPort))
151+
else: # listenAddress.family == IpAddressFamily.IPv4
152+
let
153+
(extIp4, extPorts) = setupAddress(
154+
config.nat,
155+
listenAddress,
156+
@[(port: udpPort, protocol: PortProtocol.UDP)],
157+
"nimbus_portal_client",
158+
)
159+
extUdpPort = extPorts[0].toPort()
160+
161+
(extIp4, Opt.none(IpAddress), extUdpPort)
162+
115163
(netkey, newNetKey) =
116164
if config.networkKey.isSome():
117165
(config.networkKey.get(), true)
@@ -146,7 +194,10 @@ proc run(portalClient: PortalClient, config: PortalConf) {.raises: [CatchableErr
146194
)
147195
d = newProtocol(
148196
netkey,
149-
extIp,
197+
extIp4,
198+
Opt.none(Port),
199+
extUdpPort,
200+
extIp6,
150201
Opt.none(Port),
151202
extUdpPort,
152203
# Note: usage of the client field "c" is replaced with ping extensions client_info.
@@ -157,7 +208,7 @@ proc run(portalClient: PortalClient, config: PortalConf) {.raises: [CatchableErr
157208
],
158209
bootstrapRecords = bootstrapRecords,
159210
previousRecord = previousEnr,
160-
bindIp = bindIp,
211+
bindIp = Opt.some(listenAddress),
161212
bindPort = udpPort,
162213
enrAutoUpdate = config.enrAutoUpdate,
163214
config = discoveryConfig,

portal/client/nimbus_portal_client_conf.nim

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,7 @@ import
2525
../network/wire/portal_protocol_config
2626

2727
const
28-
defaultListenAddress* = (static parseIpAddress("0.0.0.0"))
2928
defaultAdminListenAddress* = (static parseIpAddress("127.0.0.1"))
30-
defaultListenAddressDesc = $defaultListenAddress
3129
defaultAdminListenAddressDesc = $defaultAdminListenAddress
3230

3331
defaultStorageCapacity* = 2000'u32 # 2 GB default
@@ -77,11 +75,9 @@ type
7775
uint16
7876

7977
listenAddress* {.
80-
defaultValue: defaultListenAddress,
81-
defaultValueDesc: $defaultListenAddressDesc,
82-
desc: "Listening address for the Discovery v5 traffic",
83-
name: "listen-address"
84-
.}: IpAddress
78+
desc: "Listening address for the Discovery v5 traffic"
79+
defaultValueDesc: "*"
80+
name: "listen-address" .}: Option[IpAddress]
8581

8682
network* {.
8783
desc:
@@ -124,6 +120,14 @@ type
124120
name: "nat"
125121
.}: NatConfig
126122

123+
# Note: add enrIpv4Address option that would deprecate nat:extip
124+
# Or have one enr-address that accepts multiple addresses? (ipv4/ipv6)
125+
enrIpv6Address* {.
126+
hidden,
127+
desc: "Specifies the IPv6 address to be advertised in the node’s ENR",
128+
name: "debug-enr-ipv6-address"
129+
.}: Option[IpAddress]
130+
127131
enrAutoUpdate* {.
128132
defaultValue: false,
129133
desc:

portal/network/wire/portal_protocol.nim

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -909,7 +909,7 @@ proc findNodes*(
909909

910910
let records = ?recordsFromBytes(response.enrs)
911911
ok(
912-
verifyNodesRecords(records, dst, enrsResultLimit, distances).filterIt(
912+
verifyNodesRecords(records, dst, p.localNode, enrsResultLimit, distances).filterIt(
913913
not p.isBanned(it.id)
914914
)
915915
)
@@ -987,7 +987,7 @@ proc findContent*(
987987
)
988988
of enrsType:
989989
let records = ?recordsFromBytes(response.enrs)
990-
let verifiedNodes = verifyNodesRecords(records, dst, enrsResultLimit)
990+
let verifiedNodes = verifyNodesRecords(records, dst, p.localNode, enrsResultLimit)
991991

992992
ok(
993993
FoundContent(

portal/scripts/launch_local_testnet.sh

Lines changed: 40 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -332,12 +332,50 @@ for NUM_NODE in $(seq 0 $(( NUM_NODES - 1 ))); do
332332
RPC="ws"
333333
fi
334334

335+
# Some testing here for now...
336+
group=$(( NUM_NODE % 3 ))
337+
338+
case "${group}" in
339+
0)
340+
# Group 2: Dual stack
341+
# Need to specifically set both extip because they are loopback addresses
342+
EXTIP="127.0.0.1"
343+
EXTIPV6="::1"
344+
LISTEN_ADDRESS="::" # This is the default setting, so could also not set it
345+
NETWORK_ARGS="\
346+
--listen-address="${LISTEN_ADDRESS}" \
347+
--nat:extip:"${EXTIP}" \
348+
--debug-enr-ipv6-address="${EXTIPV6}" \
349+
"
350+
;;
351+
1)
352+
# Group 0: IPv4 only
353+
EXTIP="127.0.0.1"
354+
LISTEN_ADDRESS="127.0.0.1" # Could set 0.0.0.0
355+
NETWORK_ARGS="\
356+
--listen-address="${LISTEN_ADDRESS}" \
357+
--nat:extip:"${EXTIP}" \
358+
"
359+
;;
360+
2)
361+
# Group 1: IPv6 only
362+
# TODO: The nat:none should not be needed, based on IPv6 only bind address we should not set enr ipv4
363+
EXTIPV6="::1"
364+
LISTEN_ADDRESS="::1" # Cannot set :: as this would also listen on IPv4
365+
NETWORK_ARGS="\
366+
--listen-address="${LISTEN_ADDRESS}" \
367+
--debug-enr-ipv6-address="${EXTIPV6}" \
368+
--nat:none \
369+
"
370+
;;
371+
esac
372+
335373
# Running with bits-per-hop of 1 to make the lookups more likely requiring
336374
# to request to nodes over the network instead of having most of them in the
337375
# own routing table.
376+
338377
./build/nimbus_portal_client \
339-
--listen-address:127.0.0.1 \
340-
--nat:extip:127.0.0.1 \
378+
${NETWORK_ARGS} \
341379
--log-level="${LOG_LEVEL}" \
342380
--udp-port=$(( BASE_PORT + NUM_NODE )) \
343381
--data-dir="${NODE_DATA_DIR}" \

0 commit comments

Comments
 (0)