start adding more tests + minor fixes (#419)

* start adding more tests + minor fixes

* add wrong secure negotiation test

* add noise failed handshake test
This commit is contained in:
Giovanni Petrantoni 2020-11-04 23:24:41 +09:00 committed by GitHub
parent e496802943
commit 7cc42ce219
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 91 additions and 3 deletions

View File

@ -321,7 +321,7 @@ proc internalConnect(s: Switch,
lock.release() lock.release()
if isNil(conn): # None of the addresses connected if isNil(conn): # None of the addresses connected
raise newException(CatchableError, "Unable to establish outgoing link") raise newException(DialFailedError, "Unable to establish outgoing link")
if conn.closed() or conn.atEof(): if conn.closed() or conn.atEof():
# This can happen when the other ends drops us # This can happen when the other ends drops us

View File

@ -32,6 +32,8 @@ template checkTrackers*() =
if tracker.isLeaked(): if tracker.isLeaked():
checkpoint tracker.dump() checkpoint tracker.dump()
fail() fail()
# Also test the GC is not fooling with us
GC_fullCollect()
type RngWrap = object type RngWrap = object
rng: ref BrHmacDrbgContext rng: ref BrHmacDrbgContext

View File

@ -28,6 +28,7 @@ import ../libp2p/[switch,
muxers/muxer, muxers/muxer,
muxers/mplex/mplex, muxers/mplex/mplex,
protocols/secure/noise, protocols/secure/noise,
protocols/secure/secio,
protocols/secure/secure] protocols/secure/secure]
import ./helpers import ./helpers
@ -47,7 +48,7 @@ method init(p: TestProto) {.gcsafe.} =
p.codec = TestCodec p.codec = TestCodec
p.handler = handle p.handler = handle
proc createSwitch(ma: MultiAddress; outgoing: bool): (Switch, PeerInfo) = proc createSwitch(ma: MultiAddress; outgoing: bool, secio: bool = false): (Switch, PeerInfo) =
var peerInfo: PeerInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get()) var peerInfo: PeerInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get())
peerInfo.addrs.add(ma) peerInfo.addrs.add(ma)
let identify = newIdentify(peerInfo) let identify = newIdentify(peerInfo)
@ -58,7 +59,10 @@ proc createSwitch(ma: MultiAddress; outgoing: bool): (Switch, PeerInfo) =
let mplexProvider = newMuxerProvider(createMplex, MplexCodec) let mplexProvider = newMuxerProvider(createMplex, MplexCodec)
let transports = @[Transport(TcpTransport.init())] let transports = @[Transport(TcpTransport.init())]
let muxers = [(MplexCodec, mplexProvider)].toTable() let muxers = [(MplexCodec, mplexProvider)].toTable()
let secureManagers = [Secure(newNoise(rng, peerInfo.privateKey, outgoing = outgoing))] let secureManagers = if secio:
[Secure(newSecio(rng, peerInfo.privateKey))]
else:
[Secure(newNoise(rng, peerInfo.privateKey, outgoing = outgoing))]
let switch = newSwitch(peerInfo, let switch = newSwitch(peerInfo,
transports, transports,
identify, identify,
@ -109,6 +113,43 @@ suite "Noise":
check: check:
waitFor(testListenerDialer()) == true waitFor(testListenerDialer()) == true
test "e2e: handle write + noise (wrong prologue)":
proc testListenerDialer(): Future[bool] {.async.} =
let
server = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
serverInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [server])
serverNoise = newNoise(rng, serverInfo.privateKey, outgoing = false)
proc connHandler(conn: Connection) {.async, gcsafe.} =
let sconn = await serverNoise.secure(conn, false)
try:
await sconn.write("Hello!")
finally:
await sconn.close()
await conn.close()
let
transport1: TcpTransport = TcpTransport.init()
asyncCheck await transport1.listen(server, connHandler)
let
transport2: TcpTransport = TcpTransport.init()
clientInfo = PeerInfo.init(PrivateKey.random(ECDSA, rng[]).get(), [transport1.ma])
clientNoise = newNoise(rng, clientInfo.privateKey, outgoing = true, commonPrologue = @[1'u8, 2'u8, 3'u8])
conn = await transport2.dial(transport1.ma)
var sconn: Connection = nil
expect(NoiseDecryptTagError):
sconn = await clientNoise.secure(conn, true)
await conn.close()
await transport1.close()
await transport2.close()
result = true
check:
waitFor(testListenerDialer()) == true
test "e2e: handle read + noise": test "e2e: handle read + noise":
proc testListenerDialer(): Future[bool] {.async.} = proc testListenerDialer(): Future[bool] {.async.} =
let let
@ -228,6 +269,38 @@ suite "Noise":
check: check:
waitFor(testSwitch()) == true waitFor(testSwitch()) == true
test "e2e test wrong secure negotiation":
proc testSwitch(): Future[bool] {.async, gcsafe.} =
let ma1: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
let ma2: MultiAddress = Multiaddress.init("/ip4/0.0.0.0/tcp/0").tryGet()
var peerInfo1, peerInfo2: PeerInfo
var switch1, switch2: Switch
var awaiters: seq[Future[void]]
(switch1, peerInfo1) = createSwitch(ma1, false)
let testProto = new TestProto
testProto.init()
testProto.codec = TestCodec
switch1.mount(testProto)
(switch2, peerInfo2) = createSwitch(ma2, true, true) # secio, we want to fail
awaiters.add(await switch1.start())
awaiters.add(await switch2.start())
expect(UpgradeFailedError):
let conn = await switch2.dial(switch1.peerInfo, TestCodec)
await allFuturesThrowing(
switch1.stop(),
switch2.stop())
await allFuturesThrowing(awaiters)
result = true
check:
waitFor(testSwitch()) == true
# test "interop with rust noise": # test "interop with rust noise":
# when true: # disable cos in CI we got no interop server/client # when true: # disable cos in CI we got no interop server/client
# proc testListenerDialer(): Future[bool] {.async.} = # proc testListenerDialer(): Future[bool] {.async.} =

View File

@ -598,3 +598,16 @@ suite "Switch":
await allFuturesThrowing(awaiters) await allFuturesThrowing(awaiters)
waitFor(testSwitch()) waitFor(testSwitch())
test "connect to inexistent peer":
proc testSwitch() {.async, gcsafe.} =
let switch2 = newStandardSwitch(secureManagers = [SecureProtocol.Noise])
let sfut = await switch2.start()
let someAddr = MultiAddress.init("/ip4/127.128.0.99").get()
let seckey = PrivateKey.random(ECDSA, rng[]).get()
let somePeer = PeerInfo.init(secKey, [someAddr])
expect(DialFailedError):
let conn = await switch2.dial(somePeer, TestCodec)
await switch2.stop()
waitFor(testSwitch())