2022-07-01 18:19:57 +00:00
|
|
|
# Nim-LibP2P
|
2024-03-21 07:19:57 +00:00
|
|
|
# Copyright (c) 2023-2024 Status Research & Development GmbH
|
2022-07-01 18:19:57 +00:00
|
|
|
# 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.
|
2021-01-20 17:28:32 +00:00
|
|
|
|
2022-10-29 21:26:44 +00:00
|
|
|
{.push gcsafe.}
|
2023-06-07 11:12:49 +00:00
|
|
|
{.push raises: [].}
|
2021-05-21 16:27:01 +00:00
|
|
|
|
2023-05-18 08:24:17 +00:00
|
|
|
import std/[sequtils, strutils]
|
2021-01-20 17:28:32 +00:00
|
|
|
import pkg/[chronos, chronicles, metrics]
|
|
|
|
|
|
|
|
import
|
|
|
|
../stream/connection,
|
|
|
|
../protocols/secure/secure,
|
|
|
|
../protocols/identify,
|
2023-03-08 11:30:19 +00:00
|
|
|
../muxers/muxer,
|
2021-01-20 17:28:32 +00:00
|
|
|
../multistream,
|
2021-05-21 16:27:01 +00:00
|
|
|
../connmanager,
|
2021-09-08 09:07:46 +00:00
|
|
|
../errors,
|
|
|
|
../utility
|
2021-01-20 17:28:32 +00:00
|
|
|
|
|
|
|
export connmanager, connection, identify, secure, multistream
|
|
|
|
|
2024-03-21 07:19:57 +00:00
|
|
|
declarePublicCounter(
|
|
|
|
libp2p_failed_upgrades_incoming, "incoming connections failed upgrades"
|
|
|
|
)
|
|
|
|
declarePublicCounter(
|
|
|
|
libp2p_failed_upgrades_outgoing, "outgoing connections failed upgrades"
|
|
|
|
)
|
2021-01-20 17:28:32 +00:00
|
|
|
|
2021-05-21 16:27:01 +00:00
|
|
|
logScope:
|
|
|
|
topics = "libp2p upgrade"
|
|
|
|
|
2021-01-20 17:28:32 +00:00
|
|
|
type
|
2021-05-21 16:27:01 +00:00
|
|
|
UpgradeFailedError* = object of LPError
|
2021-01-20 17:28:32 +00:00
|
|
|
|
|
|
|
Upgrade* = ref object of RootObj
|
|
|
|
ms*: MultistreamSelect
|
|
|
|
secureManagers*: seq[Secure]
|
|
|
|
|
2023-04-14 14:23:19 +00:00
|
|
|
method upgrade*(
|
2024-03-21 07:19:57 +00:00
|
|
|
self: Upgrade, conn: Connection, peerId: Opt[PeerId]
|
|
|
|
): Future[Muxer] {.async: (raises: [CancelledError, LPError], raw: true), base.} =
|
|
|
|
raiseAssert("Not implemented!")
|
2021-01-20 17:28:32 +00:00
|
|
|
|
2021-03-18 15:20:36 +00:00
|
|
|
proc secure*(
|
2024-03-21 07:19:57 +00:00
|
|
|
self: Upgrade, conn: Connection, peerId: Opt[PeerId]
|
|
|
|
): Future[Connection] {.async: (raises: [CancelledError, LPError]).} =
|
2021-03-18 15:20:36 +00:00
|
|
|
if self.secureManagers.len <= 0:
|
2024-03-21 07:19:57 +00:00
|
|
|
raise (ref UpgradeFailedError)(msg: "No secure managers registered!")
|
2021-01-20 17:28:32 +00:00
|
|
|
|
2023-03-08 11:30:19 +00:00
|
|
|
let codec =
|
2024-03-21 07:19:57 +00:00
|
|
|
if conn.dir == Out:
|
|
|
|
await self.ms.select(conn, self.secureManagers.mapIt(it.codec))
|
|
|
|
else:
|
|
|
|
await MultistreamSelect.handle(conn, self.secureManagers.mapIt(it.codec))
|
2021-01-20 17:28:32 +00:00
|
|
|
if codec.len == 0:
|
2024-03-21 07:19:57 +00:00
|
|
|
raise (ref UpgradeFailedError)(msg: "Unable to negotiate a secure channel!")
|
2021-01-20 17:28:32 +00:00
|
|
|
|
|
|
|
trace "Securing connection", conn, codec
|
2021-03-18 15:20:36 +00:00
|
|
|
let secureProtocol = self.secureManagers.filterIt(it.codec == codec)
|
2021-01-20 17:28:32 +00:00
|
|
|
|
|
|
|
# ms.select should deal with the correctness of this
|
|
|
|
# let's avoid duplicating checks but detect if it fails to do it properly
|
|
|
|
doAssert(secureProtocol.len > 0)
|
|
|
|
|
2024-03-21 07:19:57 +00:00
|
|
|
await secureProtocol[0].secure(conn, peerId)
|