Skip to content
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

[connect-tcp] Discuss use of the Capsule Protocol #2847

Merged
merged 8 commits into from
Aug 2, 2024
Merged

Conversation

bemasc
Copy link
Contributor

@bemasc bemasc commented Jul 26, 2024

No description provided.

@bemasc bemasc added the connect-tcp draft-ietf-httpbis-connect-tcp label Jul 26, 2024
When implementing this specification, clients and servers MUST NOT send a "Capsule-Protocol: ?1" header field.
When using the Capsule Protocol, TCP data is sent using a new Capsule Type named DATA ({{data-capsule}}). The DATA type is only applicable to Extended CONNECT protocols for which the use of the Capsule Protocol is optional. It conveys a payload that should be processed in the same way as ordinary stream contents when the Capsule Protocol is not in use.

A client that sends this header field MUST NOT send any data on the stream until it receives a response, because it does not know whether the server will treat the data as Capsule Protocol or TCP contents.
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This latency cost is unfortunate, and could be avoided by making Capsule Protocol mandatory to implement for servers. However, that would increase the implementation complexity for a minimal compliant server, and should not be done lightly.

@DavidSchinazi @mnot

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, current design allows you to do various optimisations such calling splice (2) to avoid making copies to / from userspace, or pass the socket to some other process (with TLS being offloaded to the kernel). If we are to mandate the use of Caspules, those optimisations become impossible.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A middle ground would be to keep this text, and later define a way for servers to commit to supporting the Capsule Protocol. Note that the HTTPS record would likely not work for this commitment, because it must be fully authenticated.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I share the performance concerns. Something Ilthat came up when I talked about this with @DavidSchinazi is the possibility of having a $humongous data frame that extends to the end of the stream, so that endpoints can opt out of needing capsule framing if they don't believe they need to send any other capsules.

I havent thought exactly about how that works across intermediaries for the different use cases we discussed during the IETF 120 neeting

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@LPardue

Something Ilthat came up when I talked about this with @DavidSchinazi is the possibility of having a $humongous data frame that extends to the end of the stream, so that endpoints can opt out of needing capsule framing if they don't believe they need to send any other capsules.

I'm not sure if that solves the performance concerns; the approach provides a escape hatch for senders, but it does not provide a way for the receivers to stay out from the business of decoding Capsules.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decoding capsules is pretty trivial. We're already decoding HTTP/3 frames and QUIC frames by the time we're reading this data stream.

Yeah, current design allows you to do various optimisations such calling splice (2) to avoid making copies to / from userspace, or pass the socket to some other process (with TLS being offloaded to the kernel). If we are to mandate the use of Caspules, those optimisations become impossible.

That's not true when you're using HTTP/2 or HTTP/3, and there is no reason to optimize HTTP/1.1 at this point.

I really do care about allowing the client to send data with the request. And we can't do that without requiring capsule support on the server: we just need to say that any server implementing this specification MUST NOT read the data stream if it doesn't agree with the value of the Capsule-Protocol header sent by the client.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I really do care about allowing the client to send data with the request.

OK, I've reworked this text to make that safe while keeping capsule support optional, based on your suggestion.

there is no reason to optimize HTTP/1.1 at this point.

I have heard that HTTP/3->HTTP/1.1 conversion at a gateway is a common pattern, so the performance of HTTP/1.1 may be significant even if it is not heavily used over the open internet.

When implementing this specification, clients and servers MUST NOT send a "Capsule-Protocol: ?1" header field.
When using the Capsule Protocol, TCP data is sent using a new Capsule Type named DATA ({{data-capsule}}). The DATA type is only applicable to Extended CONNECT protocols for which the use of the Capsule Protocol is optional. It conveys a payload that should be processed in the same way as ordinary stream contents when the Capsule Protocol is not in use.

A client that sends this header field MUST NOT send any data on the stream until it receives a response, because it does not know whether the server will treat the data as Capsule Protocol or TCP contents.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decoding capsules is pretty trivial. We're already decoding HTTP/3 frames and QUIC frames by the time we're reading this data stream.

Yeah, current design allows you to do various optimisations such calling splice (2) to avoid making copies to / from userspace, or pass the socket to some other process (with TLS being offloaded to the kernel). If we are to mandate the use of Caspules, those optimisations become impossible.

That's not true when you're using HTTP/2 or HTTP/3, and there is no reason to optimize HTTP/1.1 at this point.

I really do care about allowing the client to send data with the request. And we can't do that without requiring capsule support on the server: we just need to say that any server implementing this specification MUST NOT read the data stream if it doesn't agree with the value of the Capsule-Protocol header sent by the client.

draft-ietf-httpbis-connect-tcp.md Outdated Show resolved Hide resolved
draft-ietf-httpbis-connect-tcp.md Show resolved Hide resolved
draft-ietf-httpbis-connect-tcp.md Outdated Show resolved Hide resolved
draft-ietf-httpbis-connect-tcp.md Outdated Show resolved Hide resolved
draft-ietf-httpbis-connect-tcp.md Show resolved Hide resolved
bemasc and others added 2 commits August 1, 2024 09:04
Co-authored-by: David Schinazi <DavidSchinazi@users.noreply.github.com>
@bemasc bemasc marked this pull request as ready for review August 1, 2024 13:14

When implementing this specification, clients and servers MUST NOT send a "Capsule-Protocol: ?1" header field.
Server support for the Capsule Protocol is also OPTIONAL. If the request includes "Capsule-Protocol: ?1", and the server does not support the Capsule Protocol, the server MUST respond with a 4xx (Client Error) status and a "Capsule-Protocol: ?0" response header field, and MUST discard any data received on this request stream. Upon receiving such a response, the client MUST disable use of the Capsule Protocol with this URI Template for the remainder of the session and retry the request.
Copy link
Contributor

@DavidSchinazi DavidSchinazi Aug 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can't infer what end-to-end extensions a server supports from one request, because different requests can be routed to different backends even if they are sent over the same client-intermediary connection. For this to work I think we need to mandate server support.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's fine in this case. The client uses the capsule protocol until it encounters a request where that is rejected. Then, for the rest of the "session" it sticks to baseline. Once your server fleet is finished upgrading to capsule support, clients will use it reliably (if they support it).

If you want, we could soften the notion of a "session" to indicate that clients can retry after a reasonable amount of time.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"MUST disable for the rest of the session" is a bit strong. "MUST retry without the Capsule Protocol and MAY disable for all future requests" is all that's actually needed. Let implementations decide how aggressive they want to be about backing off in a heterogeneous environment.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@MikeBishop OK, I've made that change.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The current text still uses the word "session" without defining what that means. But at this point we're in the weeds, I'm ok with merging this and then figuring out the details in separate smaller issues/PRs

@bemasc bemasc merged commit d26f7c3 into main Aug 2, 2024
2 checks passed
@bemasc bemasc deleted the bemasc-capsule branch August 2, 2024 15:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
connect-tcp draft-ietf-httpbis-connect-tcp
Development

Successfully merging this pull request may close these issues.

5 participants