There are two places that handle receiving CONNECTION_CLOSE frames in Quinn.
This is in process_early_payload (called during the handshake):
|
if let Frame::Close(_) = frame { |
|
trace!("draining"); |
|
self.state = State::Draining; |
|
break; |
|
} |
This is in process_payload (outside the handshake):
|
if let Some(reason) = close { |
|
self.error = Some(reason.into()); |
|
self.state = State::Draining; |
|
self.close = true; |
|
} |
The former doesn't actually queue a CONNECTION_CLOSE frame when it receives one.
This seems weird to me, as this breaks graceful close during handshakes.
I.e. if the server closes the connection during the handshake, the client will receive that CONNECTION_CLOSE, but not respond with one of its own, leaving the server hanging. Thus the server ends up draining the connection for longer than might be strictly necessary, keeping state around for 3 * PTO.
There are two places that handle receiving CONNECTION_CLOSE frames in Quinn.
This is in
process_early_payload(called during the handshake):quinn/quinn-proto/src/connection/mod.rs
Lines 2482 to 2486 in 76020ba
This is in
process_payload(outside the handshake):quinn/quinn-proto/src/connection/mod.rs
Lines 3072 to 3076 in 76020ba
The former doesn't actually queue a CONNECTION_CLOSE frame when it receives one.
This seems weird to me, as this breaks graceful close during handshakes.
I.e. if the server closes the connection during the handshake, the client will receive that CONNECTION_CLOSE, but not respond with one of its own, leaving the server hanging. Thus the server ends up draining the connection for longer than might be strictly necessary, keeping state around for 3 * PTO.