From: Amaury Denoyelle Date: Tue, 30 Jun 2026 16:29:07 +0000 (+0200) Subject: MINOR: mux_quic: use separate error code for STOP_SENDING X-Git-Url: http://git.kaiwu.me/doc/static/gitweb.js?a=commitdiff_plain;h=f2014ec4743f02f65387e6611fb7c999c685b149;p=haproxy.git MINOR: mux_quic: use separate error code for STOP_SENDING Prior to this patch, a single error code was registrable at the QCS level. This code was used both for RESET_STREAM and STOP_SENDING emission. It was specified via qcc_reset_stream(). This patch extends the API so that now a dedicated error code is implemented for STOP_SENDING as well. This may be necessary as both frames can be sent in different context, with a diverging error code. This patch is required to implement STOP_SENDING emission during shut callback when read channel is closed. --- diff --git a/include/haproxy/mux_quic-t.h b/include/haproxy/mux_quic-t.h index 78cc5041b..25bab15d9 100644 --- a/include/haproxy/mux_quic-t.h +++ b/include/haproxy/mux_quic-t.h @@ -198,7 +198,8 @@ struct qcs { struct wait_event wait_event; struct wait_event *subs; - uint64_t err; /* error code to transmit via RESET_STREAM */ + uint64_t rs_err; /* error code to transmit via RESET_STREAM */ + uint64_t ss_err; /* error code to transmit via STOP_SENDING */ int start; /* base timestamp for http-request timeout */ diff --git a/include/haproxy/mux_quic.h b/include/haproxy/mux_quic.h index ae4a58846..d79e2cc66 100644 --- a/include/haproxy/mux_quic.h +++ b/include/haproxy/mux_quic.h @@ -44,7 +44,7 @@ int qcc_release_stream_txbuf(struct qcs *qcs); int qcc_stream_can_send(const struct qcs *qcs); void qcc_reset_stream(struct qcs *qcs, int err, int term_evt); void qcc_send_stream(struct qcs *qcs, int urg, int count); -void qcc_abort_stream_read(struct qcs *qcs); +void qcc_abort_stream_read(struct qcs *qcs, int err); void qcc_update_shut_id(struct qcc *qcc, uint64_t val); int qcc_recv(struct qcc *qcc, uint64_t id, uint64_t len, uint64_t offset, char fin, char *data); diff --git a/src/h3.c b/src/h3.c index 6ce770846..3a1eb1124 100644 --- a/src/h3.c +++ b/src/h3.c @@ -283,7 +283,7 @@ static ssize_t h3_init_uni_stream(struct h3c *h3c, struct qcs *qcs, * streams that have unknown or unsupported types. */ TRACE_STATE("abort reading on unknown uni stream type", H3_EV_H3S_NEW, qcs->qcc->conn, qcs); - qcc_abort_stream_read(qcs); + qcc_abort_stream_read(qcs, H3_ERR_NO_ERROR); goto err; } @@ -1908,7 +1908,7 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin) /* FIN received, ensure body length is conform to any content-length header. */ if ((h3s->flags & H3_SF_HAVE_CLEN) && h3_check_body_size(qcs, 1)) { - qcc_abort_stream_read(qcs); + qcc_abort_stream_read(qcs, h3s->err); qcc_reset_stream(qcs, h3s->err, se_tevt_type_proto_err); goto done; } @@ -2133,7 +2133,7 @@ static ssize_t h3_rcv_buf(struct qcs *qcs, struct buffer *b, int fin) /* TODO Only unimplemented CONNECT reports H3_ERR_REQUEST_REJECTED here. */ const int tevt = (h3s->err == H3_ERR_REQUEST_REJECTED) ? 0 : se_tevt_type_proto_err; - qcc_abort_stream_read(qcs); + qcc_abort_stream_read(qcs, h3s->err); qcc_reset_stream(qcs, h3s->err, tevt); total += b_data(b); goto done; @@ -3141,8 +3141,7 @@ static size_t h3_snd_buf(struct qcs *qcs, struct buffer *buf, size_t count, char /* Generate a STOP_SENDING if full response transferred before * receiving the full request. */ - qcs->err = H3_ERR_NO_ERROR; - qcc_abort_stream_read(qcs); + qcc_abort_stream_read(qcs, H3_ERR_NO_ERROR); } #endif @@ -3368,7 +3367,7 @@ static int h3_attach(struct qcs *qcs, void *conn_ctx) BUG_ON(quic_stream_is_local(qcs->qcc, qcs->id)); TRACE_STATE("close stream outside of GOAWAY range", H3_EV_H3S_NEW, qcs->qcc->conn, qcs); - qcc_abort_stream_read(qcs); + qcc_abort_stream_read(qcs, H3_ERR_REQUEST_REJECTED); qcc_reset_stream(qcs, H3_ERR_REQUEST_REJECTED, 0); } diff --git a/src/mux_quic.c b/src/mux_quic.c index 550a02a8c..ae6c2da0d 100644 --- a/src/mux_quic.c +++ b/src/mux_quic.c @@ -207,7 +207,7 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type) qcs->wait_event.events = 0; qcs->subs = NULL; - qcs->err = 0; + qcs->rs_err = qcs->ss_err = 0; /* Reset all timers and start base one. */ tot_time_reset(&qcs->timer.base); @@ -238,7 +238,7 @@ static struct qcs *qcs_new(struct qcc *qcc, uint64_t id, enum qcs_type type) * accept or reject the new stream via its attach() operation. */ if (qcc->app_st >= QCC_APP_ST_SHUT && !qcc->app_ops->shutdown) { - qcc_abort_stream_read(qcs); + qcc_abort_stream_read(qcs, 0); qcc_reset_stream(qcs, 0, 0); goto out; } @@ -1749,7 +1749,7 @@ void qcc_reset_stream(struct qcs *qcs, int err, int tevt) TRACE_STATE("reset stream", QMUX_EV_QCS_END, qcc->conn, qcs); qcs->flags |= QC_SF_TO_RESET; - qcs->err = err; + qcs->rs_err = err; /* On BE side, a QCS may be resetted before any data emission. */ if (conn_is_back(qcs->qcc->conn)) @@ -1808,7 +1808,7 @@ void qcc_send_stream(struct qcs *qcs, int urg, int count) } /* Prepare for the emission of STOP_SENDING on . */ -void qcc_abort_stream_read(struct qcs *qcs) +void qcc_abort_stream_read(struct qcs *qcs, int err) { struct qcc *qcc = qcs->qcc; @@ -1819,6 +1819,7 @@ void qcc_abort_stream_read(struct qcs *qcs) TRACE_STATE("abort stream read", QMUX_EV_QCS_END, qcc->conn, qcs); qcs->flags |= (QC_SF_TO_STOP_SENDING|QC_SF_READ_ABORTED); + qcs->ss_err = err; _qcc_send_stream(qcs, 1); tasklet_wakeup(qcc->wait_event.tasklet); @@ -2795,7 +2796,7 @@ static int qcs_send_reset(struct qcs *qcs) } frm->reset_stream.id = qcs->id; - frm->reset_stream.app_error_code = qcs->err; + frm->reset_stream.app_error_code = qcs->rs_err; frm->reset_stream.final_size = qcs->tx.fc.off_real; LIST_APPEND(&frms, &frm->list); @@ -2847,7 +2848,7 @@ static int qcs_send_stop_sending(struct qcs *qcs) } frm->stop_sending.id = qcs->id; - frm->stop_sending.app_error_code = qcs->err; + frm->stop_sending.app_error_code = qcs->ss_err; LIST_APPEND(&frms, &frm->list); if (qcc_send_frames(qcs->qcc, &frms, 0)) { @@ -4809,8 +4810,9 @@ static int qcm_strm_show_sd(struct buffer *msg, struct sedesc *sd, const char *p if (!qcs) return ret; - chunk_appendf(msg, " qcs=%p .flg=%#x .id=%llu .st=%s .ctx=%p, .err=%#llx", - qcs, qcs->flags, (ull)qcs->id, qcs_st_to_str(qcs->st), qcs->ctx, (ull)qcs->err); + chunk_appendf(msg, " qcs=%p .flg=%#x .id=%llu .st=%s .ctx=%p, .err=%#llx/%#llx", + qcs, qcs->flags, (ull)qcs->id, qcs_st_to_str(qcs->st), qcs->ctx, + (ull)qcs->rs_err, (ull)qcs->ss_err); if (pfx) chunk_appendf(msg, "\n%s", pfx);