Prevent libplum re-initialization after shutdown

This commit is contained in:
Arnaud 2026-06-05 18:06:10 +04:00
parent a4196d6a5d
commit d1a44ef997
No known key found for this signature in database
GPG Key ID: A6C7C781817146FA
3 changed files with 26 additions and 2 deletions

View File

@ -47,13 +47,14 @@ type NatPortMapper* = ref object of RootObj
activeTcpPort*: Option[Port]
activeUdpPort*: Option[Port]
plumInitialized: bool
closed: bool
method mapNatPorts*(
m: NatPortMapper
): Future[Option[(Port, Port, MappingProtocol)]] {.
async: (raises: [CancelledError]), base, gcsafe
.} =
if m.natConfig.hasExtIp:
if m.closed or m.natConfig.hasExtIp:
return none((Port, Port, MappingProtocol))
# If both mappings are still active, return the stored ports without recreating.
@ -126,6 +127,11 @@ proc close*(m: NatPortMapper) =
discard cleanup()
m.plumInitialized = false
proc stop*(m: NatPortMapper) =
## Ensure that any future AutoNAT callback does not re-initialize libplum.
m.closed = true
m.close()
proc isPortMapped*(m: NatPortMapper, port: Port): bool =
m.activeTcpPort.isSome and m.activeTcpPort.get == port
@ -170,6 +176,9 @@ method handleNatStatus*(
switch: Switch,
autoRelayService: AutoRelayService,
) {.async: (raises: [CancelledError]), base, gcsafe.} =
if m.closed:
return
case networkReachability
of Unknown:
discard

View File

@ -158,7 +158,7 @@ proc stop*(s: StorageServer) {.async.} =
notice "Stopping Storage node"
if s.natMapper.isSome:
s.natMapper.get.close()
s.natMapper.get.stop()
if s.holePunchHandler.isSome:
s.storageNode.switch.removePeerEventHandler(

View File

@ -114,6 +114,21 @@ asyncchecksuite "NAT - handleNatStatus":
check not autoRelay.isRunning
check not disc.protocol.clientMode
test "handleNatStatus does nothing after the mapper is stopped":
let dialBack = MultiAddress.init("/ip4/1.2.3.4/tcp/8080").expect("valid")
let mapper = MockNatPortMapper(
mappedPorts: some((Port(9000), Port(9001), MappingProtocol.UPnP))
)
mapper.stop()
autorelayservice.setup(autoRelay, sw)
await mapper.handleNatStatus(
NotReachable, Opt.some(dialBack), discoveryPort, disc, sw, autoRelay
)
check not autoRelay.isRunning
check disc.announceAddrs == newSeq[MultiAddress]()
test "announcePeerInfoAddrs excludes relay circuit addresses":
let circuitAddr = MultiAddress
.init("/ip4/1.2.3.4/tcp/4040/p2p/" & $sw.peerInfo.peerId & "/p2p-circuit")