mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-11-11 22:11:04 +01:00
BUG/MEDIUM: h3: handle STOP_SENDING on control stream
Before this patch, STOP_SENDING reception was considered valid even on H3 control stream. This causes the emission in return of RESET_STREAM and eventually the closure and freeing of the QCS instance. This then causes a crash during connection closure as a GOAWAY frame is emitted on the control stream which is now released. To fix this crash, STOP_SENDING on the control stream is now properly rejected as specified by RFC 9114. The new app_ops close callback is used which in turn will generate a CONNECTION_CLOSE with error H3_CLOSED_CRITICAL_STREAM. This bug was detected in github issue #2006. Note that however it is triggered by an incorrect client behavior. It may be useful to determine which client behaves like this. If this case is too frequent, STOP_SENDING should probably be silently ignored. To reproduce this issue, quiche was patched to emit a STOP_SENDING on its send() function in quiche/src/lib.rs: pub fn send(&mut self, out: &mut [u8]) -> Result<(usize, SendInfo)> { - self.send_on_path(out, None, None) + let ret = self.send_on_path(out, None, None); + self.streams.mark_stopped(3, true, 0); + ret } This must be backported up to 2.6 along with the preceeding commit : MINOR: mux-quic/h3: define close callback
This commit is contained in:
parent
1e340ba6bc
commit
87f8766d3f
18
src/h3.c
18
src/h3.c
@ -1615,7 +1615,23 @@ static size_t h3_snd_buf(struct qcs *qcs, struct htx *htx, size_t count)
|
||||
*/
|
||||
static int h3_close(struct qcs *qcs, enum qcc_app_ops_close_side side)
|
||||
{
|
||||
/* TODO */
|
||||
struct h3s *h3s = qcs->ctx;
|
||||
struct h3c *h3c = h3s->h3c;;
|
||||
|
||||
/* RFC 9114 6.2.1. Control Streams
|
||||
*
|
||||
* The sender
|
||||
* MUST NOT close the control stream, and the receiver MUST NOT
|
||||
* request that the sender close the control stream. If either
|
||||
* control stream is closed at any point, this MUST be treated
|
||||
* as a connection error of type H3_CLOSED_CRITICAL_STREAM.
|
||||
*/
|
||||
if (qcs == h3c->ctrl_strm) {
|
||||
TRACE_ERROR("closure detected on control stream", H3_EV_H3S_END, qcs->qcc, qcs);
|
||||
qcc_emit_cc_app(qcs->qcc, H3_CLOSED_CRITICAL_STREAM, 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1232,6 +1232,13 @@ int qcc_recv_stop_sending(struct qcc *qcc, uint64_t id, uint64_t err)
|
||||
|
||||
qcs_idle_open(qcs);
|
||||
|
||||
if (qcc->app_ops->close) {
|
||||
if (qcc->app_ops->close(qcs, QCC_APP_OPS_CLOSE_SIDE_WR)) {
|
||||
TRACE_ERROR("closure rejected by app layer", QMUX_EV_QCC_RECV|QMUX_EV_QCS_RECV, qcc->conn, qcs);
|
||||
goto out;
|
||||
}
|
||||
}
|
||||
|
||||
/* RFC 9000 3.5. Solicited State Transitions
|
||||
*
|
||||
* An endpoint that receives a STOP_SENDING frame
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user