cloudflare / cloudflare/quiche
Handshake failure waits 3 seconds before connection closes.
- Dominant language
- Rust
- Stars
- 11.8k
- Forks
- 1.1k
- Avg merge
- 3d 7h
- Merged PRs (30d)
- 16
Description
I'm running some tests to make sure that when a connection fails during a handshake to see if everything is handled as expected and the connection is cleaned up. What I'm expecting is when the handshake fails, a close frame is sent, both sides enter a draining state and then close and i'm expecting this all to happen relatively quickly.
This is working as expected in most cases. Except for one edge case. When the server provides a self signed `ed25519` certificate and the client rejects this with a `TlsFail` error due to it being self signed. The client sends a close frame as expected and enters the draining state. The server processes this and enters the draining state as expected. But It waits for about 3 seconds for the `timeout()` and `on_timeout()` handling before entering the closed state. The client connection enters the closed state very quickly.
In contrast, with the same test but using a `RSA` signed certificate, The same process happens but the server connection doesn't wait the 3 seconds the `ed25519` example does.
For reference, here are the packets that are sent over the network.
```
// server is the 55555 port
// Packets using RSA cert
index, time, src port, bytes, ...
1 0.000000000 57087 1242 Initial, PKN: 0, CRYPTO
2 0.002199797 55555 250 Retry
3 0.003286059 57087 1242 Initial, PKN: 1, CRYPTO
4 0.007740237 55555 1242 Handshake, PKN: 0, CRYPTO
5 0.007906972 55555 412 Handshake, PKN: 1, CRYPTO
6 0.009247469 57087 1242 Handshake, PKN: 0, ACK
7 0.010162245 57087 113 Handshake, PKN: 1, CC
// packets using ed25519 cert
index, time, port, bytes, ...
1 0.000000000 58044 1242 Initial, PKN: 0, CRYPTO
2 0.003642721 55555 250 Retry
3 0.004872892 58044 1242 Initial, PKN: 1, CRYPTO
4 0.007808086 55555 1242 Handshake, PKN: 0, CRYPTO
5 0.009175480 58044 1242 Initial, PKN: 2, CC
```
So I have a few questions.
1. Is the extra 3 second timeout before the server connection enters the closed state a bug with `quiche`? Specifically when using a `ed25519` certificate?
2. Could it be some problem with my internal logic and event handling?
3. What is actually expected to happen when a handshake fails? from the internal logic perspective and packets perspective. Is there some part of the docs that explain this behaviour?
I can provide some logging of the internal logic but it's not very clean. Right now I just need more context of what is expected to happen.
Contributor guide
Research direction
Start by tracing the handshake-failure path through the timeout() and on_timeout() handling, comparing the RSA and ed25519 cases described in the packet traces. Determine whether the delayed server close is expected QUIC behavior or a quiche bug, and document the expected connection states and packets; the issue provides no file or test entry point.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- networking
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100