-
Notifications
You must be signed in to change notification settings - Fork 85
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
Proposal: add a new codepoint for QUIC v1 (RFC 9000), and for future incompatible versions #145
Comments
I guess ideally, we go with this option but somehow minimize the 1 RTT penalty. What do you think of this idea:
This should give node operators some time to notice the issue and upgrade their software accordingly. Making an informed decision on |
You can't do that: You can't update old nodes, so the node operators who need to see the warning will never see it. Instead, you'd just be spamming the logs of node operators of updated nodes, potentially with multiple messages per second. Even worse, these messages wouldn't be actionable. |
Hmm okay, I assumed that people will update at some point but yeah, if there are many operators who don't update at all, then this is definitely an issue.
I mean, that is fixable. You can just emit the log only once per peer. Also, you'd remove the log again in the version that prefers QUICv1 so updated nodes would not emit that. I am a bit on the fence here. On the one hand, adding a new protocol is a legitimate upgrade path. On the other hand, it feels like a bit of a waste to use when the situation is: a) temporary Can we make an estimate of how long the grace-period of a time-based trigger that switches to v1 would have to be to have most of the network prefer v1? Are we talking weeks, months or years? Another, more sophisticated mechanism for such kind of upgrades is to have nodes keep track1 of how many of their peers support v1 and switch to preferring that once it hits a configured threshold. Assuming that nodes connect to a representative subset of the network, this would make the switch gracefully as soon as a configured threshold is capable of v1. This is similar to Bitcoin's softfork activation techniques. Footnotes
|
That’s totally fine. We don’t want to penalize nodes that run up-to-date software though, which is what we’d do if we switched to dialing v1 by default.
It’s not any more temporary than any other update of QUIC from one incompatible version to the other. I find it quite instructive to think about what we’d what to do once an incompatible QUIC version is specified, e.g one that’s using a different handshake protocol: As I’ve described in my original post, we’d want to specify a new code point in that case. Thus, minting a new code point for QUIC v1 seems consistent. |
Should we then be more elaborate in the naming of the new code point? Like I am okay with a new code point, it is a valid upgrade / negotiation technique and really the only annoying thing is the aesthetics and documentation effort.
I would still find it interesting to back this with some data. Does |
@elenaf9 What would your implementation strategy be on the Rust side? Can you give an estimate how much work this would be? I wrote up what's needed in go-libp2p in libp2p/go-libp2p#1841. |
@mxinden @MarcoPolo I'm in favor of moving forward with this proposal, but it would be helpful to get your input here. |
First off, thanks for the detailed write-up @marten-seemann!
For the record, does quinn support draft-29 or does it not @elenaf9?
To be able to make an informed decision, can someone add numbers to "large number of nodes [running draft-29 in the IPFS network". Unfortunately I don't have this data with kademlia-exporter.max-inden.de/. @dennis-tra maybe?
I think renaming the text representation of the
I think we should be consistent, i.e. either interpret Overall I don't have a strong opinion here. My intuition tells me to:
|
These are the go-ipfs v0.7.0 nodes, so it's a very large fraction of the IPFS network (30-40%).
The cost is only paid by nodes that upgraded, so the incentives are severely misaligned here. |
Thanks Marten! I think this is worth doing sooner rather than later. I think I’m in agreement with the original post. Here’s a bit of clarification on the exact semantics since I think we’ve been discussing a lot of different things in this thread (that’s a good thing!). This issue is only about adding a new code point for I think we should add the new codepoint as soon as possible so that rust-libp2p can start using it and we can start advertising it in go-libp2p. The new codepoint allows dialers to know ahead of time what version to use. Then there’s the very closely related issue of:
(I’m defining new nodes as nodes post this upgrade; old nodes as nodes prior to this upgrade) Option i. is strictly better than ii. because we can avoid the 1RTT penalty by only dialing quic-v1 if the other node explicitly advertises it, which will be the case if we agree on a new this new codepoint sooner and have rust-libp2p use the I think codepoints are cheap. The way we represent a list of multiaddrs is a bit inefficient, but we can optimize this in the future if it becomes a problem.
Agreed. Let’s keep the current codepoint and string tl;dr I agree the new codepoint is a useful addition. I don’t see any major downsides to introducing it. Let’s do it. |
Thank you for your comprehensive response, @MarcoPolo!
That makes sense. The hope is that in the long term (as QUIC draft-29 is phased out), the |
Apologies for the late reply here.
Quinn supports draft-29, however it does not support version negotiation on the client side. Instead, when initiating a new outbound connection we have to set the QUIC version in the client config. If the server sends back a Version negotiation packet because it does not support that version the connection attempt will error with
Given the above, it wouldn't be much work to support both the new and the old-codepoint. When initiating a new dial we'd check the codepoint, in case of
What's the difference between dropping draft-29 support in 6 months compared to dropping it right now? I understand that go-ipfs v0.7 makes up a significant portion of the IPFS network, however go-ipfs v0.7 is two years old. If those nodes did not upgrade for all that time do we expect anything to change in the next 6 months? |
No we still would want a new codepoint so that new nodes can know before dialing if the node speaks v1 or draft 29. If we don’t adopt a new codepoint and assume everyone uses quicv1 then you incur a penalty when communicating with (the many) old nodes. |
Okay makes sense. Don't have a strong opinion on this; adding a new codepoint sounds reasonable 👍. Will do a PR for it on rust-multiaddr. |
With multiformats/multiaddr#145 the `quic` codepoint should be interpreted as QUIC draft-29. For QUIC v1 (RFC9000) the new codepoint `quic-v1` should be used. Quinn supports both, draft-29 and v1 as server, for clients however the version has to be set when dialing. Right now we use the default, v1. Proper support for `Protocol::QUIC` / draft-29 will be added in a follow-up PR.
multiformats/multiaddr#145 ipfs/kubo#9410 License: MIT Signed-off-by: Marcin Rataj <lidel@lidel.org>
This PR adds support for `/quic-v1` which will be enabled by default in Kubo 0.18 (ipfs/kubo#9417, ipfs/kubo#9410). @achingbrain @tinytb FYSA an important caveat is that WebTransport addrs will be `/quic-v1/webtransport` (as noted in ipfs/kubo#9410). Ref. - ipfs/kubo#9410 - multiformats/multiaddr#145 Signed-off-by: Marcin Rataj <lidel@lidel.org>
iiuc we executed on is there anything else to be done here, or can we close this? |
This has been fully resolved and released. |
Current Status
libp2p started deploying QUIC a few years ago, when RFC 9000 was not deployed yet. Back then, we deployed QUIC draft-29. Since node operators are slow to update their go-ipfs nodes, draft-29 is now the most deployed version.
*: There's a 1 RTT penalty if the version offered on the initial connection attempt doesn't match the nodes version, as Version Negotiation is performed.
Currently, go-libp2p has support for QUIC draft-29 and QUIC v1. Since draft-29 is the most commonly deployed version (and supported by all nodes on the network), we use that version for dialing new connections.
What happens when rust-libp2p gains QUIC support
rust-libp2p is adding QUIC support, and quinn only supports RFC 9000. If we don't do anything, this means:
Proposal: add a new QUIC v1 code point
We could add a new code point for QUIC v1 (string representation:
quicv1
). The existing code point would be reinterpreted to mean QUIC draft-29.Nodes that support multiple versions can (and should!) offer them on the same port. There's no need to worry about demultiplexing, since QUIC packets contain the version number and any QUIC stack will be able to handle packets from different QUIC versions (if it's a multi-version stack).
But what about QUIC v2
Does this mean that we need to add a new code point for every new QUIC versions? Wouldn't that be wasteful. Yes and no.
The IETF is currently working on specifying QUIC v2, and quic-go already has support for that QUIC version. We don't need a new code point though, because QUIC v2 is a compatible version (to QUIC v1). The exact definition of what constitutes compatibility between QUIC versions is subtle, but as a rule of thumb, if there's a transformation of the ClientHello from one version to a ClientHello of the other version, chances are that the versions are compatible. QUIC versions that use TLS 1.3 (or successors) are likely to be compatible.
Using Compatible Version Negotiation (shipping as an RFC very soon), it is possible to do a version upgrade between two compatible versions without incurring any round trip penalty. Thus, it's fine to continue advertising QUIC v1, as the connection can seamlessly be upgraded to v2 during the handshake.
Only when / if QUIC v2 becomes a dominant version on the internet, AND there are good reasons to not use QUIC v1 any more, would it make sense to introduce a v2 code point, so that compatible version negotiation can be skipped.
Hypothetical: an incompatible QUIC version is defined
A QUIC that uses a different handshake protocol than TLS 1.3 would almost certainly not be be compatible with QUIC v1. Assuming that libp2p would want to support both versions, it would make sense to introduce a new codepoint for that QUIC version, as we'd incur an additional roundtrip for version negotiation when nodes offer an unsupported version.
The text was updated successfully, but these errors were encountered: