martinthomson / train-protocol

Choo Choo!
Other
0 stars 0 forks source link

the design should be QUIC-version neutral #8

Closed kazuho closed 2 weeks ago

kazuho commented 1 month ago

Current design requires changes to specification and the program being deployed to the middleboxes, each time a new QUIC version is deployed.

To paraphrase, we are introducing the incentive for middlebox vendors to block unknown versions of QUIC to which they cannot provide bandwidth information (or give preferential treatment to some versions of QUIC to which they can provide bandwidth).

I think what we need to design is a bandwidth notification mechanism that is neutral to QUIC versions.

One way of achieving that goal would be to use the special version number solely for exchanging the bandwidth information (or for triggering rewrites). To give an example, and endpoints would exchange QUIC v1 packets as-is, but occasionally also send QUIC vXXXX packets which would be rewritten by the middleboxes.

huitema commented 1 month ago

I agree that we risk building an ossification vector. We converge on a mechanism in which we negotiate a "TRAIN" version, as in:

With that rule, we would need different version numbers for TRAIN(of Version1), TRAIN(of Version2), etc. But the intermediaries will only recognize TRAIN(version1). Thus ossification.

The desired solution would have something like:

For the handshake, I think that implies some kind a train handshake before sending VN=TRAIN. Something like:

kazuho commented 1 month ago

@huitema Thank you for your comments. I think we are almost on the same page.

The desired solution would have something like:

Considering that the endpoints are never going to use version=TRAIN for exchanging data, I think the version does not need to be covered by Compatible Version Negotiation. The only information each endpoint need to notify to the peer is that it can decode BANDWIDTH frames.

For the handshake, I think that implies some kind a train handshake before sending VN=TRAIN. Something like:

While we can define when version=TRAIN packets should be sent, I am not sure if it's worth defining.

I might argue that they can be sent at any moment, regardless of the peer having support for train. Doing so has no negative effect (modulo the cost of sending a packet that never gets used), while having the benefit of hiding endpoints' capabilities from getting exposed onto the network.

Endpoints that are capable of handling version=TRAIN packets will buffer the bandwidth information, and sends the BANDWIDTH frame once 1-RTT keys become available (and if the peer has sent the TP).