Re: SETTINGS_ENABLE_CONNECT_PROTOCOL and new protocols

I think there's some interesting nuance in the dichotomy between hop-by-hop
vs end-to-end properties of HTTP. Unfortunately Section 7 of RFC 8441
roughly says "don't use extended CONNECT across intermediaries". However,
as discussed on the MASQUE mailing list, there is real interest in using
CONNECT-UDP across intermediaries. And CONNECT-UDP relies on extended
CONNECT, so we need to make that work.

Pseudo-headers are a hop-by-hop wire-format property of HTTP/2 and 3.
Sending a header that contains a colon but isn't one of the RFC7540
pseudo-headers makes your request malformed. In my understanding,
SETTINGS_ENABLE_CONNECT_PROTOCOL was introduced to make the :protocol
pseudo-header no longer malformed. Conceptually, it's a hop-by-hop way of
saying "I won't treat your request as malformed". It doesn't provide any
guidance as to whether the sender of the setting actually supports any
protocol, or whether it'll reject such requests or not.

In contrast, whether any given protocol is supported is an end-to-end
property. That's because, for protocols that only use the request stream,
the intermediary can blindly shovel bytes back and forth and support
protocols it's not aware of. In a world where everything is TCP, that's all
we need - we're done. If the intermediary supports extended CONNECT, it can
happily forward the stream without having to know the protocol.
Unfortunately, both MASQUE and WebTransport throw some wrenches in those
gears. The first one is QUIC DATAGRAM frames: now the intermediary needs to
also know how to forward those, and that's where the H3_DATAGRAM setting
comes in. A setting is a good fit here because QUIC DATAGRAM frames are a
per-hop concept. WebTransport-over-h3 throws even more wrenches in the
gears, because it allows for custom uses of QUIC streams which aren't
within HTTP semantics, and again that's where we introduce
the ENABLE_WEBTRANSPORT setting. Again those streams are per-hop.

Conceptually, I think defining a new extended CONNECT protocol is very
similar to defining a new HTTP method. HTTP methods are end-to-end: when we
introduce a new HTTP method, we don't need a setting because HTTP semantics
already tell intermediaries that they can forward methods that they don't
understand.

Based on this train of thought, I think it makes more sense to have
settings for specific features (i.e. QUIC DATAGRAM frame when ALPN=h3) then
for whole-stack protocols, because features are hop-by-hop whereas
whole-stack is end-to-end.

I'm not sure it's really possible to solve the "as a client I want to know
all the feature set of this server" because the first intermediary might
know what all its backends support.

David

On Mon, Nov 1, 2021 at 11:45 PM Martin Thomson <mt@lowentropy.net> wrote:

> SETTINGS_ENABLE_CONNECT_PROTOCOL is defined as enabling the :protocol
> pseudo-header field on CONNECT.  The implication being that any protocol is
> OK once this setting is negotiated.
>
> In reviewing WebTransport proposals, I realized that this is probably a
> mistake.  There, Victor (I think) realized that you need to negotiate the
> use of :protocol AND the use of the specific protocol.  Otherwise, you
> might attempt to use extended CONNECT when the server does not support some
> of the extra fancy stuff that is in WebTransport.
>
> That leads me to ask:
>
> Should this setting be defined as **extended CONNECT for WebSockets**
> rather than extended CONNECT more generally?
>
> A generic thing might be useful if the purpose of the exchange is to
> negotiate for use of the bidirectional channel that is established by
> CONNECT.  That's all WebSockets does.  Maybe that's enough for a bunch of
> different cases.
>
> A generic thing is not sufficient if there are other things going on in
> the protocol as a result.  WebTransport needs additional negotiation as it
> uses datagrams (and sometimes other streams).  Datagrams are the main thing
> here, but I don't know if we should limit our thinking to that, especially
> if we might want to consider partial reliability or other transport-level
> features.
>
> The proposed solution for WebTransport is to provide a setting that covers
> the whole package needed by WebTransport.  Is that a better pattern in
> general?  Should we retcon SETTINGS_ENABLE_CONNECT_PROTOCOL to
> SETTINGS_ENABLE_WEBSOCKETS to follow this pattern?  Or, is this only a
> problem that "special" protocols need to concern themselves with?  Those
> that need more than just the "CONNECT stream".
>
> I struggle with the view that datagrams might be the only new and special
> thing.  For one, they are not in the current WebTransport for HTTP/3
> proposal.  Also, it seems like with MASQUE and WebTransport, all uses of
> extended CONNECT require some special handling.
>
> Now, you might say that these "special" protocols might just need to
> separately negotiate the features they use, like datagrams or non-request
> streams.  That might work, but these protocols are not all the same.
> Support for one does not immediately imply support for all others, even if
> they use the same basic protocol features.  For instance, the datagrams
> they exchange cannot be generically handled without understanding the
> details of the protocol.
>
> That leads me to think that maybe we need to treat this as a whole-stack
> thing.  A setting per :protocol value is pretty unambiguous.  What do
> others think?  Should we update the setting definition in RFC 8441?
>
>
>

Received on Wednesday, 3 November 2021 01:03:30 UTC