v0.x

The 1-RTT rule strict servers enforce

RFC 9001 §4.1.1 says a client must not send 1-RTT data before the handshake is confirmed on its side. Some servers check.

One of the first interop bugs we hit looked like random connection drops against one provider and none against another. The cause was ordering.

The rule

RFC 9001 §4.1.1: a client must not send 1-RTT application data until it has sent its own Handshake Finished. Lenient servers buffer early packets and sort it out; strict servers drop them — and the request silently never arrives.

The fix

javascript
// Gate application data on our own Finished
if (!conn.handshake_finished_sent) {
  conn.pending_app_frames.push(frame);
  return;
}
sendOneRtt(frame);

The wire diagram on the home page shows the order: Handshake Finished from the client comes before the first SETTINGS + HEADERS. Coalescing them into the same UDP datagram is fine — the order inside it is what counts.

colocohen

Author of QUICO, LemonTLS and a family of pure-JavaScript network servers.