nim-libp2p-experimental/tests/testtortransport.nim

147 lines
4.9 KiB
Nim

{.used.}
# Nim-Libp2p
# Copyright (c) 2023 Status Research & Development GmbH
# Licensed under either of
# * Apache License, version 2.0, ([LICENSE-APACHE](LICENSE-APACHE))
# * MIT license ([LICENSE-MIT](LICENSE-MIT))
# at your option.
# This file may not be copied, modified, or distributed except according to
# those terms.
{.push raises: [].}
import tables
import chronos, stew/[byteutils]
import ../libp2p/[stream/connection,
transports/tcptransport,
transports/tortransport,
upgrademngrs/upgrade,
multiaddress,
builders]
import ./helpers, ./stubs/torstub, ./commontransport
const torServer = initTAddress("127.0.0.1", 9050.Port)
var stub: TorServerStub
var startFut: Future[void]
suite "Tor transport":
setup:
stub = TorServerStub.new()
stub.registerAddr("127.0.0.1:8080", "/ip4/127.0.0.1/tcp/8080")
stub.registerAddr("libp2p.nim:8080", "/ip4/127.0.0.1/tcp/8080")
stub.registerAddr("::1:8080", "/ip6/::1/tcp/8080")
stub.registerAddr("a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcad.onion:80", "/ip4/127.0.0.1/tcp/8080")
stub.registerAddr("a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcae.onion:81", "/ip4/127.0.0.1/tcp/8081")
startFut = stub.start(torServer)
teardown:
waitFor startFut.cancelAndWait()
waitFor stub.stop()
checkTrackers()
proc test(lintesAddr: string, dialAddr: string) {.async.} =
let server = TcpTransport.new({ReuseAddr}, Upgrade())
let ma2 = @[MultiAddress.init(lintesAddr).tryGet()]
await server.start(ma2)
proc runClient() {.async.} =
let client = TorTransport.new(transportAddress = torServer, upgrade = Upgrade())
let conn = await client.dial("", MultiAddress.init(dialAddr).tryGet())
await conn.write("client")
var resp: array[6, byte]
await conn.readExactly(addr resp, 6)
await conn.close()
check string.fromBytes(resp) == "server"
await client.stop()
proc serverAcceptHandler() {.async, gcsafe.} =
let conn = await server.accept()
var resp: array[6, byte]
await conn.readExactly(addr resp, 6)
check string.fromBytes(resp) == "client"
await conn.write("server")
await conn.close()
await server.stop()
asyncSpawn serverAcceptHandler()
await runClient()
asyncTest "test start and dial using ipv4":
await test("/ip4/127.0.0.1/tcp/8080", "/ip4/127.0.0.1/tcp/8080")
asyncTest "test start and dial using ipv6":
await test("/ip6/::1/tcp/8080", "/ip6/::1/tcp/8080")
asyncTest "test start and dial using dns":
await test("/ip4/127.0.0.1/tcp/8080", "/dns/libp2p.nim/tcp/8080")
asyncTest "test start and dial usion onion3 and builder":
const TestCodec = "/test/proto/1.0.0" # custom protocol string identifier
type
TestProto = ref object of LPProtocol # declare a custom protocol
proc new(T: typedesc[TestProto]): T =
# every incoming connections will be in handled in this closure
proc handle(conn: Connection, proto: string) {.async, gcsafe.} =
var resp: array[6, byte]
await conn.readExactly(addr resp, 6)
check string.fromBytes(resp) == "client"
await conn.write("server")
# We must close the connections ourselves when we're done with it
await conn.close()
return T(codecs: @[TestCodec], handler: handle)
let rng = newRng()
let ma = MultiAddress.init("/ip4/127.0.0.1/tcp/8080/onion3/a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcad:80").tryGet()
let serverSwitch = TorSwitch.new(torServer, rng, @[ma], {ReuseAddr})
# setup the custom proto
let testProto = TestProto.new()
serverSwitch.mount(testProto)
await serverSwitch.start()
let serverPeerId = serverSwitch.peerInfo.peerId
let serverAddress = serverSwitch.peerInfo.addrs
proc startClient() {.async.} =
let clientSwitch = TorSwitch.new(torServer = torServer, rng= rng, flags = {ReuseAddr})
let conn = await clientSwitch.dial(serverPeerId, serverAddress, TestCodec)
await conn.write("client")
var resp: array[6, byte]
await conn.readExactly(addr resp, 6)
check string.fromBytes(resp) == "server"
await conn.close()
await clientSwitch.stop()
await startClient()
await serverSwitch.stop()
test "It's not possible to add another transport in TorSwitch":
let torSwitch = TorSwitch.new(torServer = torServer, rng= rng, flags = {ReuseAddr})
expect(AssertionDefect):
torSwitch.addTransport(TcpTransport.new(upgrade = Upgrade()))
waitFor torSwitch.stop()
proc transProvider(): Transport =
TorTransport.new(torServer, {ReuseAddr}, Upgrade())
commonTransportTest(
transProvider,
"/ip4/127.0.0.1/tcp/8080/onion3/a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcad:80",
"/ip4/127.0.0.1/tcp/8081/onion3/a2mncbqsbullu7thgm4e6zxda2xccmcgzmaq44oayhdtm6rav5vovcae:81")