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

Early data, handshake promise, and ALPN negotiation #14

Open
mmastrac opened this issue Sep 28, 2023 · 4 comments
Open

Early data, handshake promise, and ALPN negotiation #14

mmastrac opened this issue Sep 28, 2023 · 4 comments

Comments

@mmastrac
Copy link
Contributor

The spec likely needs to deal with these three items which are necessary for creating HTTP/2 connections.

The socket options must allow outgoing connections to specify ALPN negotation strings and/or byte strings, and should return the negotiated values as part of a handshake.

In addition, a socket should be configured so that it may optionally send/receive data before the handshake promise completes.

@jasnell
Copy link
Collaborator

jasnell commented Sep 28, 2023

I touch on this a bit in #17 and #15 ...

Specifically, I think we absolutely want to have a mechanism for declaring the ALPN in the connect options (along with SNI), and we ought to be able to use socket.info.alpn / socket.info.sni metadata to identify the values that are negotiated when the handshake completes.

As for early data, the API is specifically designed to allow implementations to support early data. This was a key goal especially since I want to be able to use this API also to eventually support the implementation of QUIC in Node.js. Specifically, if we look at the pattern:

const enc = new TextEncoder();
const socket = connect('address:1234', { secureTransport: 'on' });
const writer = socket.writable.getWriter();
writer.write(enc.encode('foo'));
// ...

There is nothing in the API that says that the secure connection has to be fully established for the outbound writes to begin. What would be needed is some indicator that the implementation should wait to actually begin establishing the connection lazily when the writes start in order to support early data transmitted during the handshake... so something like...

const enc = new TextEncoder();
const socket = connect('address:1234', { secureTransport: 'early' });
const writer = socket.writable.getWriter();
writer.write(enc.encode('foo'));
// ...

This 'early' mode for secureTransport would be a clear indicator that the connection should support 0RTT/0.5RTT early data. We'd have to figure out some details, of course, but this is roughly the direction I had in mind. Absolutely open to other alternatives tho!

@mmastrac
Copy link
Contributor Author

mmastrac commented Sep 28, 2023

That's a good point -- early might be enough of a special case to justify its own initial mode like that. It could be specified that the first and only the first enqueued packet would be part of the early data.

An alternative API that may not be as ergonomic (though may be more composable) might be the ability to pass a Uint8Array | ReadableStream<Uint8Array> as an early data parameter when creating a TLS stream:

const socket = connect('address:1234', { secureTransport: 'on', earlyData: new ReadableStream({...}) });

@jasnell
Copy link
Collaborator

jasnell commented Sep 28, 2023

Yeah, I've played around with that approach for the QUIC api implementation and it is certainly workable. It's absolutely worth exploring both approaches.

@jasnell
Copy link
Collaborator

jasnell commented Nov 5, 2023

alpn has been added.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants