@@ -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 */
628629static 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