Skip to content

Commit ed8214e

Browse files
committed
BUG/MINOR: quic: repeat packet parsing to deal with fragmented CRYPTO
1 parent 804594d commit ed8214e

File tree

1 file changed

+32
-5
lines changed

1 file changed

+32
-5
lines changed

src/quic_rx.c

Lines changed: 32 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,7 @@ static int qc_handle_strm_frm(struct quic_rx_packet *pkt,
617617
}
618618

619619
/* Parse <frm> CRYPTO frame coming with <pkt> packet at <qel> <qc> connection.
620+
* <iter> indicates the current iteration of packet parsing, starting at 0.
620621
*
621622
* Returns 0 on success or a negative error code. A positive value is used to
622623
* indicate that the current frame cannot be handled immediately, but it could
@@ -627,7 +628,8 @@ static int qc_handle_strm_frm(struct quic_rx_packet *pkt,
627628
*/
628629
static int qc_handle_crypto_frm(struct quic_conn *qc,
629630
struct qf_crypto *crypto_frm, struct quic_rx_packet *pkt,
630-
struct quic_enc_level *qel, int *fast_retrans)
631+
struct quic_enc_level *qel, int *fast_retrans,
632+
int iter)
631633
{
632634
int ret = -1;
633635
enum ncb_ret ncb_ret;
@@ -649,8 +651,10 @@ static int qc_handle_crypto_frm(struct quic_conn *qc,
649651
TRACE_PROTO("Already received CRYPTO data",
650652
QUIC_EV_CONN_RXPKT, qc, pkt, &cfdebug);
651653
if (qc_is_listener(qc) && qel == qc->iel &&
652-
!(qc->flags & QUIC_FL_CONN_HANDSHAKE_SPEED_UP))
654+
!(qc->flags & QUIC_FL_CONN_HANDSHAKE_SPEED_UP) &&
655+
iter == 0) {
653656
*fast_retrans = 1;
657+
}
654658
goto done;
655659
}
656660

@@ -776,6 +780,7 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
776780
struct quic_frame frm;
777781
const unsigned char *pos, *end;
778782
int fast_retrans = 0, ret = 0;
783+
int iter = 0, crypto_parsing_stage = 0;
779784

780785
TRACE_ENTER(QUIC_EV_CONN_PRSHPKT, qc);
781786
/* Skip the AAD */
@@ -796,12 +801,17 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
796801
goto err;
797802
}
798803

799-
while (pos < end) {
804+
while (pos < end && iter < 10) {
800805
if (!qc_parse_frm(&frm, pkt, &pos, end, qc)) {
801806
// trace already emitted by function above
802807
goto err;
803808
}
804809

810+
if (iter > 0 && frm.type != QUIC_FT_CRYPTO) {
811+
TRACE_STATE("ignore non crypto frame on reparsing", QUIC_EV_CONN_PRSHPKT, qc);
812+
continue;
813+
}
814+
805815
switch (frm.type) {
806816
case QUIC_FT_PADDING:
807817
break;
@@ -849,9 +859,18 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
849859
}
850860
case QUIC_FT_CRYPTO:
851861
{
852-
ret = qc_handle_crypto_frm(qc, &frm.crypto, pkt, qel, &fast_retrans);
853-
if (ret != 0)
862+
ret = qc_handle_crypto_frm(qc, &frm.crypto, pkt, qel, &fast_retrans, iter);
863+
if (ret < 0) {
854864
goto err;
865+
}
866+
else if (ret > 0 && crypto_parsing_stage < 1) {
867+
TRACE_STATE("crypto stage set to 1", QUIC_EV_CONN_PRSHPKT, qc);
868+
crypto_parsing_stage = 1;
869+
}
870+
else if (crypto_parsing_stage == 1) {
871+
TRACE_STATE("crypto stage set to 2", QUIC_EV_CONN_PRSHPKT, qc);
872+
crypto_parsing_stage = 2;
873+
}
855874
break;
856875
}
857876
case QUIC_FT_NEW_TOKEN:
@@ -998,6 +1017,14 @@ static int qc_parse_pkt_frms(struct quic_conn *qc, struct quic_rx_packet *pkt,
9981017
/* Unknown frame type must be rejected by qc_parse_frm(). */
9991018
ABORT_NOW();
10001019
}
1020+
1021+
BUG_ON(pos > end);
1022+
if (pos == end && crypto_parsing_stage == 2) {
1023+
TRACE_STATE("reparse packet crypto frames", QUIC_EV_CONN_PRSHPKT, qc);
1024+
pos = pkt->data + pkt->aad_len;
1025+
crypto_parsing_stage = 0;
1026+
++iter;
1027+
}
10011028
}
10021029

10031030
if (fast_retrans && qc->iel && qc->hel) {

0 commit comments

Comments
 (0)