feat: allow skipping encryption and custom muxer factory in upgrader#1395
feat: allow skipping encryption and custom muxer factory in upgrader#1395ckousik wants to merge 3 commits intolibp2p:masterfrom
Conversation
|
@mxinden @MarcoPolo I've used the new upgrader interface as discussed in discord. https://discordapp.com/channels/806902334369824788/942671304530747402/10200250514179564221 |
|
ah whoops! I didn't see this PR when I made #1396. My apologies |
MarcoPolo
left a comment
There was a problem hiding this comment.
Can we also include the await for async newStream? https://github.com/libp2p/js-libp2p/pull/1396/files#diff-c199200bb38fc06cbe1654f84bb2cfaed1cf0aa9bc9ed71f646932604cbd9252R422
| } | ||
| encryptedConn = protectedConn | ||
| if (!skipEncryption) { | ||
| ({ |
There was a problem hiding this comment.
Can we make this a const declaration so we don't shadow outer vars (I think this is confusing).
| // If the transport natively supports encryption, skip connection | ||
| // protector and encryption | ||
|
|
||
| // Protect | ||
| let protectedConn = maConn | ||
| const protector = this.components.getConnectionProtector() | ||
| if (!skipEncryption) { | ||
| const protector = this.components.getConnectionProtector() | ||
|
|
||
| if (protector != null) { | ||
| protectedConn = await protector.protect(maConn) | ||
| if (protector != null) { | ||
| protectedConn = await protector.protect(maConn) | ||
| } |
There was a problem hiding this comment.
We still want to do connection protection here - it's use case is a little different to encrypting the whole channel, instead you're essentially making a private network on top of the encrypted connection because you'll need the PSK to communicate any data.
That is, I can support XYX connection encryption scheme (noise, etc) and connect to a remote node, but I also need to know the PSK to connect to a remote node that uses protected connections.
There was a problem hiding this comment.
This will break if we're using native muxing since there isn't a single underlying "connection". But I agree that we should do this even with native encryption. Maybe skip this if we have a custom stream muxer? fwiw on go-libp2p the QUIC transport doesn't support PSK.
There was a problem hiding this comment.
@achingbrain Please correct me if I have misunderstood here: For a connection that does not have native encryption, we use the PreSharedKeyConnectionProtector to wrap the plaintext stream. Then, the selected encryption scheme runs on top of the already encrypted stream. Is this done for nodes to limit which other nodes can connect to them?
As @MarcoPolo has mentioned, we do not have a single underlying stream in the webrtc spec. Instead, we create an ephemeral data channel for the Noise handshake. Subsequent streams only use the native DTLS encryption.
There was a problem hiding this comment.
In go-libp2p, we don't support PSK in QUIC or WebTransport.
There was a problem hiding this comment.
We probably can't support a PSK with native encryption without giving this more thought. I think this change is okay.
There was a problem hiding this comment.
See libp2p/js-libp2p-interfaces#290 (comment) - it's a small change but I think we need to split skipping connection protection out into it's own option - it makes the logic in the changes here easier to follow and also leaves the door open for transports that do their own encryption and muxing but also support PSK.
|
Can we move this out of draft @ckousik ? |
|
I can resolve merge conflicts after libp2p/js-libp2p-interfaces#290 is merged. |
achingbrain
left a comment
There was a problem hiding this comment.
LGTM, some small nits and needs libp2p/js-libp2p-interfaces#290 landing first.
| // Protect | ||
| let protectedConn = maConn | ||
| const protector = this.components.getConnectionProtector() | ||
| if ((opts?.muxerFactory) == null) { |
There was a problem hiding this comment.
After the suggested change in the interface repo we can make this decision on explicit settings rather than the lack of presence of an overriding muxer factory:
| if ((opts?.muxerFactory) == null) { | |
| if (opts.skipProtection !== true) { |
| protocol: cryptoProtocol | ||
| } = await this._encryptOutbound(protectedConn, remotePeerId)) | ||
| encryptedConn = protectedConn | ||
| if (!opts?.skipEncryption) { |
There was a problem hiding this comment.
I think this is a bit easier to read. The linter will also probably complain about not handling boolean values explicitly.
| if (!opts?.skipEncryption) { | |
| if (opts?.skipEncryption === false) { |
There was a problem hiding this comment.
Wouldn't this be false if opts is undefined or opts.skipEncryption is undefined?
There was a problem hiding this comment.
What I mean is that we want the default behavior to be to not skip encryption so we should do opts?.skipEncryption !== true. example
| // Multiplex the connection | ||
| if (this.muxers.size > 0) { | ||
| upgradedConn = encryptedConn | ||
| if ((opts?.muxerFactory) != null) { |
There was a problem hiding this comment.
Doe we need the extra parentheses?
| if ((opts?.muxerFactory) != null) { | |
| if (opts?.muxerFactory != null) { |
| upgradedConn, | ||
| muxerFactory, | ||
| remotePeer | ||
| remotePeer, |
There was a problem hiding this comment.
I think this will upset the linter. You can run npm run lint locally to check.
| remotePeer, | |
| remotePeer |
| "@libp2p/interface-registrar": "^2.0.3", | ||
| "@libp2p/interface-stream-muxer": "^2.0.2", | ||
| "@libp2p/interface-transport": "^1.0.3", | ||
| "@libp2p/interface-stream-muxer": "file:../js-libp2p-interfaces/packages/interface-stream-muxer", |
There was a problem hiding this comment.
| "@libp2p/interface-stream-muxer": "file:../js-libp2p-interfaces/packages/interface-stream-muxer", | |
| "@libp2p/interface-stream-muxer": "^3.0.0", |
| "@libp2p/interface-stream-muxer": "^2.0.2", | ||
| "@libp2p/interface-transport": "^1.0.3", | ||
| "@libp2p/interface-stream-muxer": "file:../js-libp2p-interfaces/packages/interface-stream-muxer", | ||
| "@libp2p/interface-transport": "file:../js-libp2p-interfaces/packages/interface-transport", |
There was a problem hiding this comment.
| "@libp2p/interface-transport": "file:../js-libp2p-interfaces/packages/interface-transport", | |
| "@libp2p/interface-transport": "^2.0.0", |
|
@ckousik I'd love to help here, but I can't push to this branch. |
Me neither - @ckousik I noticed the same thing about your PR to |
|
@achingbrain Should I close this PR and reopen ? |
|
I copied this to: #1411 with the requested changes. |
@achingbrain Since the fork is owned by the little-bear-labs org, I do not get that option at all. |
|
superseded by #1411 |

Updates the
DefaultUpgraderto use the newUpgraderOptionswhich allows skipping encryption and/or adding a custom muxer factory for transports which inherently support encryption and muxing.