fix: disable port mapping to avoid crash (#1500)

This commit is contained in:
Arnaud 2026-08-05 00:00:38 +04:00 committed by GitHub
parent 18c0b82351
commit 05284b25fe
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 57 additions and 30 deletions

View File

@ -161,7 +161,7 @@ proc start*(m: NatPortMapper) =
proc stop*(m: NatPortMapper) =
## Ensure that any future AutoNAT callback does not re-initialize libplum.
m.stopped = true
m.close()
# m.close()
method handleNatStatus*(
m: NatPortMapper,
@ -200,31 +200,31 @@ method handleNatStatus*(
# If the relay is running, the addresses will be updated on reservation.
discovery.announceDirectAddrs(@[], udpPort = discoveryPort)
if m.hasLivePortMapping():
# The mapping is still live but the node is not reachable: keep it and let
# the relay take over. A dead mapping falls through to be recreated.
debug "Not Reachable with live port mapping, keeping it and starting relay if not started"
else:
debug "Node is not reachable trying port mapping now"
# if m.hasLivePortMapping():
# # The mapping is still live but the node is not reachable: keep it and let
# # the relay take over. A dead mapping falls through to be recreated.
# debug "Not Reachable with live port mapping, keeping it and starting relay if not started"
# else:
# debug "Node is not reachable trying port mapping now"
let maybePorts = await m.mapNatPorts()
# let maybePorts = await m.mapNatPorts()
if m.stopped:
# Double check in case the node is stopping
return
# if m.stopped:
# # Double check in case the node is stopping
# return
if maybePorts.isSome:
let (tcpPort, udpPort, protocol) = maybePorts.get()
# if maybePorts.isSome:
# let (tcpPort, udpPort, protocol) = maybePorts.get()
info "Port mapping created successfully", tcpPort, udpPort, protocol
# info "Port mapping created successfully", tcpPort, udpPort, protocol
# The announce happens once AutoNAT confirms Reachable.
# # The announce happens once AutoNAT confirms Reachable.
return
else:
# In case of failure, close the port mapping in order to rerun discover
# on the next iteration
m.close()
# return
# else:
# # In case of failure, close the port mapping in order to rerun discover
# # on the next iteration
# m.close()
if not autoRelayService.isRunning:
debug "No port mapping found let's start autorelay"

View File

@ -13,6 +13,9 @@ proc announcesDirectAddr(info: JsonNode): bool =
## A reachable node announces at least one direct (non-circuit) address.
info{"providerAddresses"}.getElems.anyIt("p2p-circuit" notin it.getStr)
# Port mapping is disabled in storage/nat.nim
const skipScenario = true
asyncchecksuite "NAT pcp":
let
composeFile = currentSourcePath.parentDir / "compose.yml"
@ -24,15 +27,21 @@ asyncchecksuite "NAT pcp":
var client: StorageClient
setup:
compose(composeFile, "up -d")
client = StorageClient.new(nodeApiUrl)
if not skipScenario:
compose(composeFile, "up -d")
client = StorageClient.new(nodeApiUrl)
teardown:
await client.close()
saveContainerLogs(composeFile, suiteName, testName, startTime, services)
compose(composeFile, "down -v")
if not skipScenario:
await client.close()
saveContainerLogs(composeFile, suiteName, testName, startTime, services)
compose(composeFile, "down -v")
test testName:
if skipScenario:
skip()
return
# Reachable is the settling signal: wait for it, then assert each expected
# property separately so a failure points at the exact condition.
check eventuallyInfo(client, info{"nat"}{"reachability"}.getStr == "Reachable")

View File

@ -13,6 +13,9 @@ proc announcesDirectAddr(info: JsonNode): bool =
## A reachable node announces at least one direct (non-circuit) address.
info{"providerAddresses"}.getElems.anyIt("p2p-circuit" notin it.getStr)
# Port mapping is disabled in storage/nat.nim
const skipScenario = true
asyncchecksuite "NAT upnp":
let
composeFile = currentSourcePath.parentDir / "compose.yml"
@ -24,15 +27,21 @@ asyncchecksuite "NAT upnp":
var client: StorageClient
setup:
compose(composeFile, "up -d")
client = StorageClient.new(nodeApiUrl)
if not skipScenario:
compose(composeFile, "up -d")
client = StorageClient.new(nodeApiUrl)
teardown:
await client.close()
saveContainerLogs(composeFile, suiteName, testName, startTime, services)
compose(composeFile, "down -v")
if not skipScenario:
await client.close()
saveContainerLogs(composeFile, suiteName, testName, startTime, services)
compose(composeFile, "down -v")
test testName:
if skipScenario:
skip()
return
# Reachable is the settling signal: wait for it, then assert each expected
# property separately so a failure points at the exact condition.
check eventuallyInfo(client, info{"nat"}{"reachability"}.getStr == "Reachable")

View File

@ -90,6 +90,9 @@ asyncchecksuite "NAT reaction - port mapping":
let discoveryPort = Port(8090)
test "handleNatStatus keeps relay off when NotReachable and mapping succeeds":
skip()
return
let dialBack = MultiAddress.init("/ip4/1.2.3.4/tcp/8080").expect("valid")
let mapper = MockNatPortMapper(
mappedPorts: some((Port(9000), Port(9001), MappingProtocol.UPnP))
@ -143,6 +146,9 @@ asyncchecksuite "NAT reaction - port mapping":
check mapper.destroyed.len == 0 # never torn down
test "handleNatStatus recreates a dead mapping instead of pinning it":
skip()
return
privateAccess(PortMapping)
let dialBack = MultiAddress.init("/ip4/1.2.3.4/tcp/8080").expect("valid")
let mapper = MockMapNatPortMapper(
@ -198,6 +204,9 @@ asyncchecksuite "NAT reaction - port mapping":
check disc.providerAddrs == newSeq[MultiAddress]()
test "handleNatStatus retries the port mapping on the next NotReachable after a failure":
skip()
return
# A failed mapping must not disable the mapper: close() resets plum so the
# next AutoNAT iteration re-runs discover and tries again.
let mapper = MockMapNatPortMapper(