NagyZoltanPeter 53e4e7b95a
Bump nim-chornicles, nim-libp2p, nimcrypto
Bump nim-web3, nim-eth and deps - on_chain/group_manager.nim adaption
Added status-im/nim-minilru submodule required by latest nim-eth
Added nim-quic and nim-ngtcp2 as new deps of nim-libp2p
Fixing tests.

 Changes:
	modified:   .gitmodules
	modified:   tests/waku_discv5/utils.nim
	modified:   tests/waku_enr/utils.nim
	modified:   tests/waku_rln_relay/test_rln_group_manager_onchain.nim
	modified:   tests/waku_rln_relay/utils.nim
	modified:   tests/waku_rln_relay/utils_onchain.nim

        modified:   vendor/nim-chronicles
	modified:   vendor/nim-eth
	modified:   vendor/nim-http-utils
	modified:   vendor/nim-json-rpc
	modified:   vendor/nim-json-serialization
	modified:   vendor/nim-libp2p
	modified:   vendor/nim-metrics
	new file:   vendor/nim-minilru
	modified:   vendor/nim-nat-traversal
	new file:   vendor/nim-ngtcp2
	modified:   vendor/nim-presto
	new file:   vendor/nim-quic
	modified:   vendor/nim-secp256k1
	modified:   vendor/nim-serialization
	modified:   vendor/nim-stew
	modified:   vendor/nim-taskpools
	modified:   vendor/nim-testutils
	modified:   vendor/nim-toml-serialization
	modified:   vendor/nim-unicodedb
	modified:   vendor/nim-unittest2
	modified:   vendor/nim-web3
	modified:   vendor/nim-websock
	modified:   vendor/nim-zlib
	modified:   vendor/nimcrypto
	modified:   waku.nimble

        modified:   waku/common/enr/builder.nim
	modified:   waku/common/enr/typed_record.nim
	modified:   waku/common/utils/nat.nim
	modified:   waku/discovery/waku_discv5.nim
	modified:   waku/waku_rln_relay/conversion_utils.nim
	modified:   waku/waku_rln_relay/group_manager/on_chain/group_manager.nim
	modified:   waku/waku_rln_relay/rln/wrappers.nim
	modified:   waku/waku_rln_relay/rln_relay.nim
2024-12-12 11:02:33 +01:00

80 lines
2.9 KiB
Nim

{.push raises: [].}
import std/[options, strutils, net]
import chronicles, eth/net/nat, results, nativesockets
logScope:
topics = "nat"
## Due to the design of nim-eth/nat module we must ensure it is only initialized once.
## see: https://github.com/waku-org/nwaku/issues/2628
## Details: nim-eth/nat module starts a meaintenance thread for refreshing the NAT mappings, but everything in the module is global,
## there is no room to store multiple configurations.
## Exact meaning: redirectPorts cannot be called twice in a program lifetime.
## During waku tests we happen to start several node instances in parallel thus resulting in multiple NAT configurations and multiple threads.
## Those threads will dead lock each other in tear down.
var singletonNat: bool = false
proc setupNat*(
natConf, clientId: string, tcpPort, udpPort: Port
): Result[
tuple[ip: Option[IpAddress], tcpPort: Option[Port], udpPort: Option[Port]], string
] {.gcsafe.} =
let strategy =
case natConf.toLowerAscii()
of "any": NatAny
of "none": NatNone
of "upnp": NatUpnp
of "pmp": NatPmp
else: NatNone
var endpoint:
tuple[ip: Option[IpAddress], tcpPort: Option[Port], udpPort: Option[Port]]
if strategy != NatNone:
## Only initialize the NAT module once
## redirectPorts cannot be called twice in a program lifetime.
## We can do it as same happens if getExternalIP fails and returns None
if singletonNat:
warn "NAT already initialized, skipping as cannot be done multiple times"
else:
singletonNat = true
var extIp = none(IpAddress)
try:
extIp = getExternalIP(strategy)
except Exception:
warn "exception in setupNat", error = getCurrentExceptionMsg()
if extIP.isSome():
endpoint.ip = some(extIp.get())
# RedirectPorts in considered a gcsafety violation
# because it obtains the address of a non-gcsafe proc?
var extPorts: Opt[(Port, Port)]
try:
extPorts = (
{.gcsafe.}:
redirectPorts(
tcpPort = tcpPort, udpPort = udpPort, description = clientId
)
)
except CatchableError:
# TODO: nat.nim Error: can raise an unlisted exception: Exception. Isolate here for now.
error "unable to determine external ports"
extPorts = Opt.none((Port, Port))
if extPorts.isSome():
let (extTcpPort, extUdpPort) = extPorts.get()
endpoint.tcpPort = some(extTcpPort)
endpoint.udpPort = some(extUdpPort)
else: # NatNone
if not natConf.startsWith("extip:"):
return err("not a valid NAT mechanism: " & $natConf)
try:
# any required port redirection is assumed to be done by hand
endpoint.ip = some(parseIpAddress(natConf[6 ..^ 1]))
except ValueError:
return err("not a valid IP address: " & $natConf[6 ..^ 1])
return ok(endpoint)