mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2025-08-10 00:57:02 +02:00
MINOR: quic: adjust request reject when MUX is already freed
When the MUX is freed, the quic-conn layer may stay active until all streams acknowledgment are processed. In this interval, if a new stream is opened by the client, the quic-conn is thus now responsible to handle it. This is done by the emission of a STOP_SENDING. This process is closely related to HTTP/3 protocol despite being handled by the quic-conn layer. This highlights a flaw in our QUIC architecture which should be adjusted. To reflect this situation, the function qc_stop_sending_frm_enqueue() is renamed qc_h3_request_reject(). Also, internal H3 treatment such as uni-directional bypass has been moved inside the function. This commit is only a refactor. However, bug fix on next patches will rely on it so it should be backported up to 2.6.
This commit is contained in:
parent
5faf577997
commit
38836b6b3d
@ -2697,24 +2697,33 @@ static void qc_cc_err_count_inc(struct quic_conn *qc, struct quic_frame *frm)
|
||||
TRACE_LEAVE(QUIC_EV_CONN_CLOSE, qc);
|
||||
}
|
||||
|
||||
/* Enqueue a STOP_SENDING frame to send into 1RTT packet number space
|
||||
* frame list to send.
|
||||
* Return 1 if succeeded, 0 if not.
|
||||
/* Cancel a request on connection <qc> for stream id <id>. This is useful when
|
||||
* the client opens a new stream but the MUX has already been released. A
|
||||
* STOP_SENDING frame is prepared for emission.
|
||||
*
|
||||
* TODO this function is closely related to H3. Its place should be in H3 layer
|
||||
* instead of quic-conn but this requires an architecture adjustment.
|
||||
*
|
||||
* Returns 1 on sucess else 0.
|
||||
*/
|
||||
static int qc_stop_sending_frm_enqueue(struct quic_conn *qc, uint64_t id)
|
||||
static int qc_h3_request_reject(struct quic_conn *qc, uint64_t id)
|
||||
{
|
||||
int ret = 0;
|
||||
struct quic_frame *frm;
|
||||
struct quic_enc_level *qel = &qc->els[QUIC_TLS_ENC_LEVEL_APP];
|
||||
uint64_t app_error_code;
|
||||
const uint64_t app_error_code = H3_REQUEST_REJECTED;
|
||||
|
||||
TRACE_ENTER(QUIC_EV_CONN_PRSHPKT, qc);
|
||||
|
||||
/* TODO: the mux may be released, we cannot have more
|
||||
* information about the application error code to send
|
||||
* at this time.
|
||||
/* Do not emit rejection for unknown unidirectional stream as it is
|
||||
* forbidden to close some of them (H3 control stream and QPACK
|
||||
* encoder/decoder streams).
|
||||
*/
|
||||
app_error_code = H3_REQUEST_REJECTED;
|
||||
if (quic_stream_is_uni(id)) {
|
||||
ret = 1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
frm = qc_frm_alloc(QUIC_FT_STOP_SENDING);
|
||||
if (!frm) {
|
||||
TRACE_ERROR("failed to allocate quic_frame", QUIC_EV_CONN_PRSHPKT, qc);
|
||||
@ -2935,19 +2944,10 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
|
||||
}
|
||||
else {
|
||||
TRACE_DEVEL("No mux for new stream", QUIC_EV_CONN_PRSHPKT, qc);
|
||||
if (qc->app_ops == &h3_ops && quic_stream_is_uni(stream->id)) {
|
||||
/* Do not send STOP_SENDING frames for h3 unidirectional streams.
|
||||
* TODO: this test should be removed when the connection closure
|
||||
* will be more clean.
|
||||
* At quic_conn level there is no mean to know that an application
|
||||
* want to forbid stream closure requests to receivers. This is the
|
||||
* case for the Control and QPACK h3 unidirectional streams.
|
||||
*/
|
||||
goto leave;
|
||||
}
|
||||
|
||||
if (!qc_stop_sending_frm_enqueue(qc, stream->id))
|
||||
if (qc->app_ops == &h3_ops) {
|
||||
if (!qc_h3_request_reject(qc, stream->id))
|
||||
TRACE_ERROR("could not enqueue STOP_SENDING frame", QUIC_EV_CONN_PRSHPKT, qc);
|
||||
}
|
||||
/* This packet will not be acknowledged */
|
||||
goto leave;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user