Skip to content
This repository has been archived by the owner on Aug 11, 2020. It is now read-only.

TODO: Implement QuicClientSession auto-resumption capability #219

Open
jasnell opened this issue Dec 5, 2019 · 0 comments
Open

TODO: Implement QuicClientSession auto-resumption capability #219

jasnell opened this issue Dec 5, 2019 · 0 comments

Comments

@jasnell
Copy link
Member

jasnell commented Dec 5, 2019

QUIC's support for 0RTT allows sessions to be reestablished in a zero-round trip flow. This is enabled by the client retaining TLS session and configuration information from the prior session and using that retained information when creating a new connection.

Currently, a QuicClientSession is automatically destroy (and be unusable) once the connection is destroyed. This means that in order to resume a TLS session, you have to create a new QuicClientSession instance with the correct parameters at the start... something like..

const socket = socket.createSocket({ /** ... **/ })
const client1 = socket.connect( { /** .. **/ })
client1.on('sessionTicket', () => {/** retain details });

// then later when client1 is destroyed...

const client2 = socket.connect( { /** pass in retained details **/ })

What would be far more useful and ergonomic for the majority of cases is if QuicClientSession supported an optional automatic resumption capability that would retain session information and keep the QuicClientSession alive between disconnections. This would require a significant new event lifecycle for QuicClientSession objects and a bit more complicated handling for state related to QuicStream instances.

Specifically something like this:

const socket = socket.createSocket({ /** .. **/ })
const client = socket.connect( { autoresume: true, /** .. **/ } );
client.on('secure', () => {
  // Invoked every time the TLS handshake for a new connection completes
});
client.on('disconnect', () => {
  // Rather than being destroyed and emitting 'close' when the underlying
  // QUIC connection is terminated, the 'disconnect' event would be emitted.
  // At this point, the QuicClientSession is dormant and all existing QuicStream
  // instances have been closed. The QuicClientSession will retain the information
  // necessary to resume a 0RTT session immediately the next time a connection
  // is needed to perform and operation (e.g. opening a new QuicStream)

  // Creates a new pending QuicStream and triggers 0RTT establishment of a
  // new underlying QUIC connection using the retained TLS session details.
  const newStream = client.openStream();
});

// To actually close an autoresume QuicClientSession, the client user code must
// explicitly call close(). Alternatively, if the current QUIC connection closes
// with a non-zero error code, it will not be auto-resumed and will destroy and
// close immediately.
client.close();

Autoresume would not be supported for server QuicSession instances at all. Once the servers side of the QUIC connection is dead, it's dead and no session state is retained.

A key question that needs to be answered is whether this is best implemented at the C++ or JavaScript side.

On the JavaScript side, we implement this by allowing the underlying c++ QuicSession handle to be destroyed when a connection dies, and then recreated on demand when it is needed again. For the C++ side, it becomes more complicated to implement but the QuicSession handle would be retained and reused, with it's internal state being cleared on disconnection and reestablished on autoresume. The latter is a much larger and more complicated change but is potentially more efficient. It's not clear yet if there's enough of a performance difference between the two options. I'm inclined at the moment to go with the first (JavaScript) option.

It is important to keep in mind that the local port and network associated with the original connection may change by the time we autoresume. That is, the QuicClientSession could be moved to a different QuicSocket (different local UDP port), or the network path to the destination may have changed. Processing the autoresume would likely trigger a new DNS resolve on the target hostname.

If the network path is no longer reachable, the name cannot be re-resolved, etc, then the attempt to autoresume will fail and the QuicClientSession will be destroyed.

The option for user code to store the TLS session details itself and resume manually by creating a new QuicClientSession object will still be possible.

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

No branches or pull requests

1 participant