logos-storage-nim/tests/storage/testnatsimulation.nim

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

181 lines
5.8 KiB
Nim
Raw Normal View History

import std/net
2026-05-12 10:05:16 +04:00
import pkg/chronos
import pkg/libp2p/wire
2026-05-12 10:05:16 +04:00
import ./helpers
import ../asynctest
import ../../storage/rng
import ../../storage/nat
2026-05-12 10:05:16 +04:00
import ../../storage/utils/natsimulation
const flags = {ServerFlags.ReuseAddr}
const listenAddr = "/ip4/127.0.0.1/tcp/0"
2026-05-25 11:55:40 +04:00
const filterTimeout = 500.millis
proc cannotConnect(a, b: Switch): Future[bool] {.async.} =
let completed =
try:
await a.connect(b.peerInfo.peerId, b.peerInfo.addrs).withTimeout(filterTimeout)
except LPError:
false
if completed:
return false
return not a.isConnected(b.peerInfo.peerId)
2026-05-12 10:05:16 +04:00
proc newSwitch(rng: Rng): Switch =
SwitchBuilder
.new()
.withRng(rng)
.withPrivateKey(PrivateKey.random(rng).get())
2026-05-12 10:05:16 +04:00
.withAddresses(@[MultiAddress.init(listenAddr).get()])
.withTcpTransport(flags)
.withNoise()
.withYamux()
.build()
proc newNatSwitch(router: NatRouter, rng: Rng): Switch =
SwitchBuilder
.new()
.withRng(rng)
.withPrivateKey(PrivateKey.random(rng).get())
2026-05-12 10:05:16 +04:00
.withAddresses(@[MultiAddress.init(listenAddr).get()])
.withNatTransport(router, flags)
.withNoise()
.withYamux()
.build()
asyncchecksuite "NatTransport - Endpoint-Independent Filtering":
var bootstrap, natNode: Switch
setup:
let router = NatRouter.new(EndpointIndependent)
bootstrap = newSwitch(Rng.instance())
natNode = newNatSwitch(router, Rng.instance())
await bootstrap.start()
await natNode.start()
teardown:
await bootstrap.stop()
await natNode.stop()
test "bootstrap can connect to nat node without any prior outbound":
await bootstrap.connect(natNode.peerInfo.peerId, natNode.peerInfo.addrs)
check bootstrap.isConnected(natNode.peerInfo.peerId)
asyncchecksuite "NatTransport - Address-Dependent Filtering":
var bootstrap, thirdNode, natNode: Switch
setup:
2026-05-25 11:33:04 +04:00
let router = NatRouter.new(AddressDependent)
2026-05-12 10:05:16 +04:00
bootstrap = newSwitch(Rng.instance())
thirdNode = newSwitch(Rng.instance())
natNode = newNatSwitch(router, Rng.instance())
await bootstrap.start()
await thirdNode.start()
await natNode.start()
teardown:
await bootstrap.stop()
await thirdNode.stop()
await natNode.stop()
test "bootstrap can connect to nat node with a pre-existing connection":
await natNode.connect(bootstrap.peerInfo.peerId, bootstrap.peerInfo.addrs)
check natNode.isConnected(bootstrap.peerInfo.peerId)
await bootstrap.connect(natNode.peerInfo.peerId, natNode.peerInfo.addrs)
check bootstrap.isConnected(natNode.peerInfo.peerId)
test "third node can connect to nat node after nat node connected to bootstrap":
await natNode.connect(bootstrap.peerInfo.peerId, bootstrap.peerInfo.addrs)
await thirdNode.connect(natNode.peerInfo.peerId, natNode.peerInfo.addrs)
check thirdNode.isConnected(natNode.peerInfo.peerId)
test "bootstrap cannot connect to nat node without a pre-existing connection":
2026-05-25 11:55:40 +04:00
check await cannotConnect(bootstrap, natNode)
2026-05-12 10:05:16 +04:00
asyncchecksuite "NatTransport - Address-and-Port-Dependent Filtering":
var bootstrap, thirdNode, natNode: Switch
setup:
2026-05-25 11:33:04 +04:00
let router = NatRouter.new(AddressAndPortDependent)
2026-05-12 10:05:16 +04:00
bootstrap = newSwitch(Rng.instance())
thirdNode = newSwitch(Rng.instance())
natNode = newNatSwitch(router, Rng.instance())
await bootstrap.start()
await thirdNode.start()
await natNode.start()
teardown:
await bootstrap.stop()
await thirdNode.stop()
await natNode.stop()
test "bootstrap can connect to nat node with a pre-existing connection":
await natNode.connect(bootstrap.peerInfo.peerId, bootstrap.peerInfo.addrs)
check natNode.isConnected(bootstrap.peerInfo.peerId)
await bootstrap.connect(natNode.peerInfo.peerId, natNode.peerInfo.addrs)
check bootstrap.isConnected(natNode.peerInfo.peerId)
test "bootstrap cannot connect to nat node without a pre-existing connection":
2026-05-25 11:55:40 +04:00
check await cannotConnect(bootstrap, natNode)
2026-05-12 10:05:16 +04:00
test "third node cannot connect to nat node even after nat node connected to bootstrap":
await natNode.connect(bootstrap.peerInfo.peerId, bootstrap.peerInfo.addrs)
2026-05-25 11:55:40 +04:00
check await cannotConnect(thirdNode, natNode)
asyncchecksuite "NatTransport - Double NAT":
var bootstrap, natNode: Switch
var router: NatRouter
setup:
2026-05-25 11:33:04 +04:00
router = NatRouter.new(DoubleNat)
bootstrap = newSwitch(Rng.instance())
natNode = newNatSwitch(router, Rng.instance())
await bootstrap.start()
await natNode.start()
teardown:
await bootstrap.stop()
await natNode.stop()
test "bootstrap cannot connect to nat node regardless of port mapping":
let actualPort = initTAddress(natNode.peerInfo.addrs[0]).get().port
let natMapper = NatPortMapper()
natMapper.activeTcpPort = some(actualPort)
router.natMapper = some(natMapper)
2026-05-25 11:55:40 +04:00
check await cannotConnect(bootstrap, natNode)
asyncchecksuite "NatTransport - Port Mapping":
var bootstrap, natNode: Switch
var router: NatRouter
setup:
2026-05-25 11:33:04 +04:00
router = NatRouter.new(AddressAndPortDependent)
bootstrap = newSwitch(Rng.instance())
natNode = newNatSwitch(router, Rng.instance())
await bootstrap.start()
await natNode.start()
teardown:
await bootstrap.stop()
await natNode.stop()
test "bootstrap can connect to nat node when port mapping matches listen port":
let actualPort = initTAddress(natNode.peerInfo.addrs[0]).get().port
let natMapper = NatPortMapper()
natMapper.activeTcpPort = some(actualPort)
router.natMapper = some(natMapper)
await bootstrap.connect(natNode.peerInfo.peerId, natNode.peerInfo.addrs)
check bootstrap.isConnected(natNode.peerInfo.peerId)
test "bootstrap cannot connect to nat node when port mapping does not match":
let natMapper = NatPortMapper()
natMapper.activeTcpPort = some(Port(1))
router.natMapper = some(natMapper)
2026-05-25 11:55:40 +04:00
check await cannotConnect(bootstrap, natNode)