Re: SETTINGS_ENABLE_CONNECT_PROTOCOL and new protocols

Hi Martin,

On Tue, Nov 02, 2021 at 05:41:33PM +1100, Martin Thomson 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?

This is a good question indeed. In haproxy after figuring that we were
incorrectly reusing some backend H2 connections that do not support WS
and that we ought to include the knowledge of support of extended CONNECT
in the choice of connection, we also noted that there will be an issue if
later another protocol wants to use the extended CONNECT because a single
boolean will not let us know which protocol the server supports. For now
we're considering that all this is WS but I'm already anticipating fun
things in the future.

> 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.

Yep, we'd need something similar to ALPN in fact, because that's exactly
what it is in reality, while we're negotiating the ability to establish
a tunnel we don't know what protocol the application layer supports.

> 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?

We risk to quickly get out of settings ID this way.

> Or, is this only a
> problem that "special" protocols need to concern themselves with?  Those that
> need more than just the "CONNECT stream".  

I suspect that we'd need something that more resembles a negotiation.
But settings can be sent at once in both directions. But we could state
that servers supporting some protocol extensions ought to wait for the
client's settings frame before advertising their support for a requested
application-layer protocol. Or we could have another setting back to
indicate which one was chosen. The only thing is that we only have 32 bits
to encode plenty of protocols and this would require some registration.

Or maybe we could have a sequence like this one, where when a client
advertises support for such an extended CONNECT, a new frame of type
ALPN advertises the list of protocols supported over CONNECT:

   client  --------> SETTINGS_ENABLE_APPLICATION_PROTOCOL -------->
           <----- "ALPN" frame indicating supported protocols <---- server

But even with that I wouldn't be surprised that some want to advertise
support for nothing in return (empty string maybe) and others would
advertise support for everything (plain transparent tunnels).

> 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.

CONNECT has always required special handling, since HTTP/1 anyway. It's
pure protocol encapsulation, and each time we think we've covered it all
we discover yet another layer on top of it that needs to be known upfront
or be negotiated.

> 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.

And it's not always trivial when you want to deal with idle connections,
sometimes you would like to know which ones support what before deciding
to use them.

> 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?

It is unambiguous but could be bothersome to manage and retrofit into
existing components each time we create a new one. At least having a
setting with a protocol ID would be better but then we could end up
with fun stuff like tunnels advertising all 2^32 possibilities, which
might be stupid as well.

But I do think that it deserves a little bit of discussion to see what
could be done. I wouldn't be surprised if we end up with a new setting
that broadly covers :protocol with ext CONNECT but mandates advertising
protocol support, and that the current one only goes deprecated.

Willy

Received on Tuesday, 2 November 2021 07:36:05 UTC