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

Provide a way to specify a subprotocol in client-server #26

Closed
vasilvv opened this issue Jan 18, 2019 · 14 comments · Fixed by #87
Closed

Provide a way to specify a subprotocol in client-server #26

vasilvv opened this issue Jan 18, 2019 · 14 comments · Fixed by #87
Labels
hard Things to discuss and think about

Comments

@vasilvv
Copy link
Contributor

vasilvv commented Jan 18, 2019

WebSockets have a subprotocol mechanism which works similar to ALPN (see https://tools.ietf.org/html/rfc6455#section-1.9). Perhaps we should provide web applications using this API the same functionality directly via ALPN, e.g., if the client asks for "foo" and "bar", we provide ALPNs "wq:foo" and "wq:bar".

@pthatcherg
Copy link
Contributor

That would require sending something over a stream (or datagram?). But the app can do that itself and we don't need to define anything. In other words, a higher-level WebSocket-like API could implement that on top of our lower-level API.

However, if we wanted to use transport parameters for this, we would want to add special support for it. Would this make sense as a transport parameter?

@vasilvv
Copy link
Contributor Author

vasilvv commented Jan 24, 2019

Would this make sense as a transport parameter?

I actually wanted to just use the TLS ALPN fields for that (with a namespace prefix, of course, so that you can't negotiate non-web ALPNs with this).

@pthatcherg
Copy link
Contributor

Oh, sorry, I didn't understand your first comment.

So basically you want to stuff extra things in the ALPN. Does that mean that the server sends back an ALPN value to the client (a response to the given ALPN)? And the client can send more than one ALPN value?

Sorry for my ignorance of ALPNs :).

@aboba
Copy link
Collaborator

aboba commented Jan 25, 2019

How does protocol multiplexing fit into the ALPN discussion? ALPN usage is clear if an RTCQuicTransport is only used for one purpose (e.g. CSQUIC, HTTP, etc.) but if we are to allow "pooled connections" where an RTCQuicTransport is used for HTTP and CSQUIC, then how what ALPN is used and does this open security holes?

@vasilvv
Copy link
Contributor Author

vasilvv commented Jan 29, 2019

ALPN works the following way. Client sends a list of protocols that it supports, and the server picks one of them. In QUIC, if the client and the server don't have a protocol in common, it's a fatal error.

So, for example, the client could request applications "foo" and "bar" from the API, and the User Agent would send ALPNs "wq:foo" and "wq:bar" in its client handshake as an offer. The server would have to pick one of them or abort the connection.

@pthatcherg
Copy link
Contributor

Seems like an interesting way to piggyback some info on the QUIC handshake. A web app could always do the same with messages/streams/datagrams after the QUIC handshake completes, but this is just slightly faster. So like all optimizations, the question is: is it worth it?

To know if it's worth it, it would be nice to know what kinds of subprotocols would be used. Basically, what use case would be faster that would make this extra complexity worth it?

@vasilvv
Copy link
Contributor Author

vasilvv commented Feb 27, 2019

I agree that we should think hard about what exactly do we need here any why. I am not entirely clear on this myself, but I will note the following consideration.

Both HTTP and WSP allow the client to specify sub-endpoint within the server host (as /path). This is convenient in deployments for composing reasons: you can have two servers maintained by different teams running as standalone processes, and you can then multiplex them using a reverse proxy (e.g. nginx), dispatching by path or subprotocol. This does require a standardized way to specify sub-endpoint.

@pthatcherg
Copy link
Contributor

My understanding of the use case: some JS wants to say QuicTransport("host", port, "chat") and another wants to say QuicTransport("host", port, "notifications"). It's the same host, but different services. Where do we put those services on the wire? The app could put that in a stream of its own, but that adds some app-level complexity and an RTT.

@pthatcherg
Copy link
Contributor

One issue with it being in the ALPN is that it won't be encrypted, which might be a surprise and problem for the app.

@pthatcherg
Copy link
Contributor

One alternative might be to do what we've always wanted to avoid: have QuicTransport allocate stream 1 and use that for sending sub protocols (and possibly other stuff). Maybe we should just reserve stream 1 for future extensiblity.

@pthatcherg
Copy link
Contributor

If it's not encrypted, and we're OK with that, we might as well use QUIC transport parameters, right?

@aboba
Copy link
Collaborator

aboba commented Mar 19, 2019

Need to add optional third parameter to the RTCQuicTransport constructor.

@dontcallmedom dontcallmedom transferred this issue from w3c/p2p-webtransport Jun 28, 2019
@pthatcherg pthatcherg added the hard Things to discuss and think about label Sep 13, 2019
@pthatcherg
Copy link
Contributor

Notes from a discussion:

Why a URL 3rd parameter? A place for CSP. Why? Because CSP is based on URLs.

Why not a 3rd parameter on QuicTransport? The JS/wasm can always do that anyway, perhaps when they do auth (so it might not be so onerous)

Why not 3rd parameter URL? A lot of things will expect it's an HTTP request, and we don't want to deal with cookies and storage.

Alternative: use "quic://$host:$port"

@vasilvv
Copy link
Contributor Author

vasilvv commented Oct 24, 2019

Why not a 3rd parameter on QuicTransport? The JS/wasm can always do that anyway, perhaps when they do auth (so it might not be so onerous)

So, I thought about this for a while, and I think I am currently leaning towards "add 3rd parameter" option.

From the design standpoint, our general goal has been roughly "provide the feature set one would get from using QUIC directly, but not more". So, for instance this principle bars cookies and HTTP auth, as QUIC by itself does not support those; but it does not preclude us from authenticating the server using WebPKI (in fact, we require that) or authenticating the client using a TLS certificate (we currently do not support that, but I do not see that much of a problem of supporting that if there are users who want that).

Multiplexing here is interesting because QUIC does support "third parameter" natively via ALPN, but we require ALPN to be fixed because of security restrictions. Thus, I feel like we should provide a replacement mechanism for this. The two options we've discussed so far are:

  1. Transmitting it as an ALPN suffix.
  2. Transmitting it together with origin on special stream.

I think the second option is preferable because then it gets encrypted.

vasilvv added a commit to vasilvv/web-transport that referenced this issue Dec 13, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
hard Things to discuss and think about
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants