Proposal: 1-RTT Handshakes (incl. Identify)
Nobody has claimed this yet.
- Dominant language
- No language data
- Stars
- 1.8k
- Forks
- 320
- Avg merge
- 11d 15h
- Merged PRs (30d)
- 1
Description
A (libp2p) QUIC handshake takes 1 RTT, a libp2p TCP handshake incl. takes 4 RTTs (3 RTTs when using the inlined muxer negotiation). That's not the whole story however. After the handshake, implementations might wait for Identify to finish before actually making the connection available to the application. Since Identify is a request-response protocol (peer A opens a /ipfs/id/1.0.0 stream, and then waits for the response), this consumes another round-trip.
The 0.5-RTT optimization
TLS 1.3 allows the server to send application data right after receiving the client's first flight (which is 0.5 RTTs after the client started the handshake, hence the name). At this point, the server possesses the keys to encrypt application data packets, however, as it hasn't received the client's certificate yet, it doesn't know who it's sending the data. For the client, data sent in 0.5 RTT is indistinguishable from data sent after handshake completion (unless looking at packet timing), so there's no changes needed on the client side to accept 0.5-RTT data.
The Go standard library doesn't expose an API to use 0.5-RTT data, but quic-go will do, starting with the next release: https://github.com/lucas-clemente/quic-go/issues/3634.
Identify: Request vs Push
Unfortunately, this doesn't allow us to get the handshake down to 1 RTT, since Identify itself is request-response. There is a push variant, Identify Push (/ipfs/id/push/1.0.0), which allows peers to push their Identify message instead of waiting for the incoming identify stream. If the server used that variant in 0.5-RTT data, the client would finish the handshake (incl. Identify) within just a single round trip.
Legacy clients will continue using the regular Identify protocol, and we don't necessarily want to send them our Identify data twice.
Legacy servers won't send the Identify push message, and clients need to decide if they want to start the regular Identify request or not.
We can solve this problem by distinguishing between the current Identify mode and the push mode suggested here. QUIC currently uses the "libp2p" ALPN. By minting a new ALPN identifier, e.g. "libp2p+idpush", peers could negotiate the new behavior (or fall back to the old behavior) in an unambiguous way.
Required Spec Changes
- specify the new ALPN for libp2p+QUIC, link the Identify and the QUIC (or TLS) document
cc @MarcoPolo @mxinden @thomaseizinger @elenaf9 @p-shahi @achingbrain @Stebalien @Menduist
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the existing libp2p QUIC and Identify specifications referenced by the issue, then trace how the current "libp2p" ALPN is defined. Specify the new ALPN and document negotiation and fallback behavior for Identify Push versus regular Identify.
Written by the indexing model from the issue text.
Assessment
- Domain
- networking
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100