153 lines
5.0 KiB
Nim
153 lines
5.0 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.
|
|
|
|
when (NimMajor, NimMinor) < (1, 4):
|
|
{.push raises: [Defect].}
|
|
else:
|
|
{.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":
|
|
when (NimMajor, NimMinor, NimPatch) < (1, 4, 0):
|
|
type AssertionDefect = AssertionError
|
|
|
|
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")
|