diff --git a/libp2p/switch.nim b/libp2p/switch.nim index c6d7467..1118818 100644 --- a/libp2p/switch.nim +++ b/libp2p/switch.nim @@ -12,28 +12,59 @@ import chronos import connection, transport, stream/lpstream, multistream, protocol, - peerinfo, multiaddress + peerinfo, multiaddress, + identify, muxers/muxer type + UnableToSecureError = object of CatchableError + UnableToIdentifyError = object of CatchableError + Switch* = ref object of RootObj peerInfo*: PeerInfo connections*: TableRef[string, Connection] transports*: seq[Transport] protocols*: seq[LPProtocol] + muxers*: seq[MuxerProvider] ms*: MultisteamSelect + identity*: Identify -proc newSwitch*(peerInfo: PeerInfo, transports: seq[Transport]): Switch = +proc newSwitch*(peerInfo: PeerInfo, + transports: seq[Transport], + identity: Identify, + muxers: seq[MuxerProvider]): Switch = new result result.peerInfo = peerInfo result.ms = newMultistream() result.transports = transports result.connections = newTable[string, Connection]() - result.protocols = newSeq[LPProtocol]() + result.identity = identity + result.muxers = muxers + + result.ms.addHandler(IdentifyCodec, identity) proc secure(s: Switch, conn: Connection) {.async, gcsafe.} = ## secure the incoming connection discard +proc identify(s: Switch, conn: Connection, peerInfo: PeerInfo) {.async, gcsafe.} = + ## identify the connection + s.peerInfo.protocols = s.ms.list() # update protos before engagin in identify + await s.identity.identify(conn) + +proc mux(s: Switch, conn: Connection): Future[bool] {.async, gcsafe.} = + ## mux incoming connection + result = true + +proc handleConn(s: Switch, conn: Connection) {.async, gcsafe.} = + ## perform upgrade flow + try: + result = s.ms.handle(conn) # handler incoming connection + await s.secure(conn) + if await s.mux(conn): + await s.identify(conn) + finally: + await conn.close() + proc dial*(s: Switch, peer: PeerInfo, proto: string = ""): Future[Connection] {.async.} = for t in s.transports: # for each transport for a in peer.addrs: # for each address @@ -57,8 +88,7 @@ proc mount*[T: LPProtocol](s: Switch, proto: T) = proc start*(s: Switch) {.async.} = proc handle(conn: Connection): Future[void] {.async, closure, gcsafe.} = - await s.secure(conn) # secure the connection - await s.ms.handle(conn) # fire up the ms handler + await s.handleConn(conn) for t in s.transports: # for each transport for a in s.peerInfo.addrs: diff --git a/tests/testnative.nim b/tests/testnative.nim index 69cc2b9..e2f8bbe 100644 --- a/tests/testnative.nim +++ b/tests/testnative.nim @@ -2,4 +2,4 @@ import unittest import testvarint, testbase32, testbase58, testbase64 import testrsa, testecnist, tested25519, testsecp256k1, testcrypto import testmultibase, testmultihash, testmultiaddress, testcid, testpeer -import testidentify, testtransport, testmultistream, testswitch, testbufferstream +import testidentify, testtransport, testmultistream, testbufferstream