From: Amaury Denoyelle Date: Mon, 4 Nov 2024 16:27:39 +0000 (+0100) Subject: MINOR: quic: extend return value of CRYPTO parsing X-Git-Tag: v3.0.7~48 X-Git-Url: http://git.haproxy.org/?a=commitdiff_plain;h=19c4b37c9fa38d4ec8675b5533efa65b0ec4247c;p=haproxy-3.0.git MINOR: quic: extend return value of CRYPTO parsing qc_handle_crypto_frm() is the function used to handled a newly received CRYPTO frame. Change its API to use a newly dedicated return type. This allows to report if the frame was properly handled, ignored if already parsed previously or rejected after a fatal error. This commit does not have any functional changes. However, it allows to simplify qc_handle_crypto_frm() API by removing as output parameter. Also, this patch will be necessary to support multiple iteration of packet parsing for CRYPTO frames. (cherry picked from commit d65e782c8cd2f8554404dd1424e2d64f3786edb1) Signed-off-by: Christopher Faulet --- diff --git a/include/haproxy/quic_rx-t.h b/include/haproxy/quic_rx-t.h index 6b5a0c4..6639364 100644 --- a/include/haproxy/quic_rx-t.h +++ b/include/haproxy/quic_rx-t.h @@ -58,4 +58,10 @@ struct quic_rx_packet { unsigned int time_received; }; +enum quic_rx_ret_frm { + QUIC_RX_RET_FRM_DONE = 0, /* frame handled correctly */ + QUIC_RX_RET_FRM_DUP, /* frame ignored as already handled previously */ + QUIC_RX_RET_FRM_FATAL, /* error during frame handling, packet must not be acknowledged */ +}; + #endif /* _HAPROXY_RX_T_H */ diff --git a/src/quic_rx.c b/src/quic_rx.c index 02b899e..fdc354c 100644 --- a/src/quic_rx.c +++ b/src/quic_rx.c @@ -657,17 +657,22 @@ static int qc_handle_strm_frm(struct quic_rx_packet *pkt, return !ret; } -/* Parse CRYPTO frame coming with packet at connectionn. - * Returns 1 if succeeded, 0 if not. Also set <*fast_retrans> to 1 if the - * speed up handshake completion may be run after having received duplicated - * CRYPTO data. +/* Parse CRYPTO frame coming with packet at connection. + * + * Returns 0 on success or a negative error code. A positive value is used to + * indicate that the current frame cannot be handled immediately, but it could + * be solved by running a new packet parsing iteration. + * + * Also set <*fast_retrans> as output parameter to 1 if the speed up handshake + * completion may be run after having received duplicated CRYPTO data. */ -static int qc_handle_crypto_frm(struct quic_conn *qc, - struct qf_crypto *crypto_frm, struct quic_rx_packet *pkt, - struct quic_enc_level *qel, int *fast_retrans) +static enum quic_rx_ret_frm qc_handle_crypto_frm(struct quic_conn *qc, + struct qf_crypto *crypto_frm, + struct quic_rx_packet *pkt, + struct quic_enc_level *qel) { - int ret = 0; enum ncb_ret ncb_ret; + enum quic_rx_ret_frm ret = QUIC_RX_RET_FRM_DONE; /* XXX TO DO: is used only for the traces. */ struct quic_rx_crypto_frm cfdebug = { .offset_node.key = crypto_frm->offset, @@ -684,10 +689,8 @@ static int qc_handle_crypto_frm(struct quic_conn *qc, if (crypto_frm->offset + crypto_frm->len <= cstream->rx.offset) { /* Nothing to do */ TRACE_PROTO("Already received CRYPTO data", - QUIC_EV_CONN_RXPKT, qc, pkt, &cfdebug); - if (qc_is_listener(qc) && qel == qc->iel && - !(qc->flags & QUIC_FL_CONN_HANDSHAKE_SPEED_UP)) - *fast_retrans = 1; + QUIC_EV_CONN_RXPKT, qc, pkt, &cfdebug); + ret = QUIC_RX_RET_FRM_DUP; goto done; } @@ -702,7 +705,7 @@ static int qc_handle_crypto_frm(struct quic_conn *qc, if (!quic_get_ncbuf(ncbuf) || ncb_is_null(ncbuf)) { TRACE_ERROR("CRYPTO ncbuf allocation failed", QUIC_EV_CONN_PRSHPKT, qc); - goto leave; + goto err; } /* crypto_frm->offset > cstream-trx.offset */ @@ -718,7 +721,7 @@ static int qc_handle_crypto_frm(struct quic_conn *qc, TRACE_ERROR("cannot bufferize frame due to gap size limit", QUIC_EV_CONN_PRSHPKT, qc); } - goto leave; + goto err; } /* Reschedule with TASK_HEAVY if CRYPTO data ready for decoding. */ @@ -728,10 +731,12 @@ static int qc_handle_crypto_frm(struct quic_conn *qc, } done: - ret = 1; - leave: TRACE_LEAVE(QUIC_EV_CONN_PRSHPKT, qc); return ret; + + err: + TRACE_DEVEL("leaving on error", QUIC_EV_CONN_PRSHPKT, qc); + return QUIC_RX_RET_FRM_FATAL; } /* Handle RETIRE_CONNECTION_ID frame from frame. @@ -811,6 +816,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, { struct quic_frame *frm = NULL; const unsigned char *pos, *end; + enum quic_rx_ret_frm ret; int fast_retrans = 0; TRACE_ENTER(QUIC_EV_CONN_PRSHPKT, qc); @@ -889,8 +895,20 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt, break; } case QUIC_FT_CRYPTO: - if (!qc_handle_crypto_frm(qc, &frm->crypto, pkt, qel, &fast_retrans)) + ret = qc_handle_crypto_frm(qc, &frm->crypto, pkt, qel); + switch (ret) { + case QUIC_RX_RET_FRM_FATAL: goto err; + case QUIC_RX_RET_FRM_DUP: + if (qc_is_listener(qc) && qel == qc->iel && + !(qc->flags & QUIC_FL_CONN_HANDSHAKE_SPEED_UP)) { + fast_retrans = 1; + } + break; + case QUIC_RX_RET_FRM_DONE: + /* nothing to do here */ + break; + } break; case QUIC_FT_NEW_TOKEN: /* TODO */