-
Notifications
You must be signed in to change notification settings - Fork 55
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(transport): add experimental QUIC Transport (not production ready) #725
Conversation
Co-authored-by: markspanbroek <mark@spanbroek.net>
Unfortunately, nim-quic relies on questionable which doesn't work on nim devel So even though this branch works, it should not be merged until this get fixed |
We should not be using Questionable and the likes, are totally fine in a high level application, where the amount of "busyness" related logic might become high (Codex, Nimbus, etc...), but not in a low level dependency such as |
# Conflicts: # .pinned # libp2p.nim # libp2p.nimble # libp2p/wire.nim # tests/testswitch.nim
_: type QuicStream, stream: Stream, oaddr: Opt[MultiAddress], peerId: PeerId | ||
): QuicStream = | ||
let quicstream = QuicStream(stream: stream, observedAddr: oaddr, peerId: peerId) | ||
procCall P2PConnection(quicstream).initStream() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should specify an objName for quicstream
before calling initStream
. https://github.com/vacp2p/nim-libp2p/blob/master/libp2p/stream/connection.nim#L56-L57
except QuicError: | ||
raise newLPStreamEOFError() | ||
except CatchableError: | ||
raise newLPStreamEOFError() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
After a recent discussion with @Ivansete-status, I think those errors need a small rework, they lack precision (not in this PR though). But nevertheless, everytime you use LPStreamEOFError
you should try to use one of those error instead.
# Session | ||
type QuicSession* = ref object of P2PConnection | ||
connection: QuicConnection |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure to understand why you need two P2PConnections here (with QuicSession and QuicStream). It's a bit confusing. QuicSession
looks like ConnManager to me.
And I think it's better to create your custom Connection
in libp2p/streams instead of here.
|
||
# Stream | ||
type QuicStream* = ref object of P2PConnection | ||
stream: Stream |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not a huge fan of this un-prefixed Stream
. Maybe renaming it QuicStream
and renaming the current QuicStream
into LPQuicStream
will be clearer.
handleFut: Future[void] | ||
|
||
method newStream*( | ||
m: QuicMuxer, name: string = "", lazy: bool = false |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think the lazy
flag is an option here. Maybe add a log if someone tries to use it.
try: | ||
while not m.quicSession.atEof: | ||
let incomingStream = await m.quicSession.getStream(Direction.In) | ||
asyncSpawn m.handleStream(incomingStream) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you find an alternative to the asyncspawn, it would be great.
type QuicUpgrade = ref object of Upgrade | ||
|
||
type QuicTransport* = ref object of Transport | ||
listener: Listener |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same as above, not a fan of un-prefixed object like that. QuicListener is great.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is defined in nim-quic.
QUIC_V1.match(address) | ||
|
||
method start*(transport: QuicTransport, addrs: seq[MultiAddress]) {.async.} = | ||
doAssert transport.listener.isNil, "start() already called" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should this really be a doAssert
? Raising an LPError should be a better idea.
for c in transport.connections: | ||
await c.close() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What about something like that: await allFutures(transport.connections.mapIt(it.close))
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there any semantic difference? Not sure if it adds enough value to justify the change.
let connection = await dial(initTAddress(address).tryGet) | ||
return transport.wrapConnection(connection) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should probably check if transport.running == true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Approved in order to work on the comments in separate/smaller PRs.
Our quic effort is blocked by bearssl not supporting TLS1.3, but since Mark did most of the work to implement Quic here: #563 and on nim-quic, this PR is going to bring encryption-less Quic into nim-libp2p
This allows us to test it, and make sure it doesn't bitrot.
Heavily WiP:
observed address
and port 0 resolving)Since encryption is not yet supported, we're not compatible with any other libp2ps, and have to rely on home made protocols to retrieve the peer's id