Skip to content

Commit d2a313b

Browse files
committed
BUG/MINOR: quic: ignore AGAIN ncbuf err when parsing CRYPTO frames
This fix follows this previous one: BUG/MINOR: quic: reorder fragmented RX CRYPTO frames by their offsets which is not sufficient when a client fragments and mixes its CRYPTO frames AND leaveswith holes by packets. ngtcp2 (and perhaps chrome) splits theire CRYPTO frames but without hole by packet. In such a case, the CRYPTO parsing leads to QUIC_RX_RET_FRM_AGAIN errors which cannot be fixed when the peer resends its packets. Indeed, even if the peer resends its frames in a different order, this does not help because since the previous commit, the CRYPTO frames are ordered on haproxy side. This issue was detected thanks to the interopt tests with quic-go as client. This client fragments its CRYPTO frames, mixes them, and generate holes, and most of the times with the retry test. To fix this, when a QUIC_RX_RET_FRM_AGAIN error is encountered, the CRYPTO frames parsing is not stop. This leaves chances to the next CRYPTO frames to be parsed. Must be backported as far as 2.6 as the commit mentioned above.
1 parent 2c351df commit d2a313b

File tree

1 file changed

+6
-4
lines changed

1 file changed

+6
-4
lines changed

src/quic_conn.c

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3249,7 +3249,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
32493249
struct quic_frame *frm = NULL;
32503250
const unsigned char *pos, *end;
32513251
enum quic_rx_ret_frm ret;
3252-
int fast_retrans = 0;
3252+
int fast_retrans = 0, cf_err = 0;
32533253

32543254
TRACE_ENTER(QUIC_EV_CONN_PRSHPKT, qc);
32553255
/* Skip the AAD */
@@ -3514,9 +3514,8 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
35143514

35153515
case QUIC_RX_RET_FRM_AGAIN:
35163516
TRACE_STATE("AGAIN encountered", QUIC_EV_CONN_PRSHPKT, qc);
3517-
/* avoid freeing without eb_delete() */
3518-
frm = NULL;
3519-
goto err;
3517+
cf_err = 1;
3518+
break;
35203519

35213520
case QUIC_RX_RET_FRM_DONE:
35223521
TRACE_PROTO("frame handled", QUIC_EV_CONN_PRSAFRM, qc, frm);
@@ -3534,6 +3533,9 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
35343533
qc_frm_free(&frm);
35353534
}
35363535

3536+
if (cf_err)
3537+
goto err;
3538+
35373539
/* Error should be returned if some frames cannot be parsed. */
35383540
BUG_ON(!eb_is_empty(&cf_frms_tree));
35393541

0 commit comments

Comments
 (0)