@@ -63,7 +63,8 @@ static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch);
63
63
static int ch_retry (QUIC_CHANNEL * ch ,
64
64
const unsigned char * retry_token ,
65
65
size_t retry_token_len ,
66
- const QUIC_CONN_ID * retry_scid );
66
+ const QUIC_CONN_ID * retry_scid ,
67
+ int drop_later_pn );
67
68
static int ch_restart (QUIC_CHANNEL * ch );
68
69
69
70
static void ch_cleanup (QUIC_CHANNEL * ch );
@@ -91,7 +92,8 @@ static void rxku_detected(QUIC_PN pn, void *arg);
91
92
static int ch_retry (QUIC_CHANNEL * ch ,
92
93
const unsigned char * retry_token ,
93
94
size_t retry_token_len ,
94
- const QUIC_CONN_ID * retry_scid );
95
+ const QUIC_CONN_ID * retry_scid ,
96
+ int drop_later_pn );
95
97
static void ch_update_idle (QUIC_CHANNEL * ch );
96
98
static int ch_discard_el (QUIC_CHANNEL * ch ,
97
99
uint32_t enc_level );
@@ -2381,7 +2383,7 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only)
2381
2383
2382
2384
if (!ch_retry (ch , ch -> qrx_pkt -> hdr -> data ,
2383
2385
ch -> qrx_pkt -> hdr -> len - QUIC_RETRY_INTEGRITY_TAG_LEN ,
2384
- & ch -> qrx_pkt -> hdr -> src_conn_id ))
2386
+ & ch -> qrx_pkt -> hdr -> src_conn_id , old_have_processed_any_pkt ))
2385
2387
ossl_quic_channel_raise_protocol_error (ch , OSSL_QUIC_ERR_INTERNAL_ERROR ,
2386
2388
0 , "handling retry packet" );
2387
2389
break ;
@@ -2472,6 +2474,7 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only)
2472
2474
assert (0 );
2473
2475
break ;
2474
2476
}
2477
+
2475
2478
}
2476
2479
2477
2480
static void ch_rx_handle_version_neg (QUIC_CHANNEL * ch , OSSL_QRX_PKT * pkt )
@@ -2790,9 +2793,8 @@ static void free_token(const unsigned char *buf, size_t buf_len, void *arg)
2790
2793
*/
2791
2794
static int ch_restart (QUIC_CHANNEL * ch )
2792
2795
{
2793
-
2794
2796
/*
2795
- * Just pretend we lost our first initial packet, so it gets
2797
+ * Just pretend we lost our initial packet, so it gets
2796
2798
* regenerated, with our updated protocol version number
2797
2799
*/
2798
2800
return ossl_ackm_mark_packet_pseudo_lost (ch -> ackm , QUIC_PN_SPACE_INITIAL ,
@@ -2803,9 +2805,11 @@ static int ch_restart(QUIC_CHANNEL *ch)
2803
2805
static int ch_retry (QUIC_CHANNEL * ch ,
2804
2806
const unsigned char * retry_token ,
2805
2807
size_t retry_token_len ,
2806
- const QUIC_CONN_ID * retry_scid )
2808
+ const QUIC_CONN_ID * retry_scid ,
2809
+ int drop_later_pn )
2807
2810
{
2808
2811
void * buf ;
2812
+ QUIC_PN pn = 0 ;
2809
2813
2810
2814
/*
2811
2815
* RFC 9000 s. 17.2.5.1: "A client MUST discard a Retry packet that contains
@@ -2841,6 +2845,13 @@ static int ch_retry(QUIC_CHANNEL *ch,
2841
2845
ch -> retry_scid = * retry_scid ;
2842
2846
ch -> doing_retry = 1 ;
2843
2847
2848
+ /*
2849
+ * If a retry isn't our first response, we need to drop packet number
2850
+ * one instead (i.e. the case where we did version negotiation first
2851
+ */
2852
+ if (drop_later_pn == 1 )
2853
+ pn = 1 ;
2854
+
2844
2855
/*
2845
2856
* We need to stimulate the Initial EL to generate the first CRYPTO frame
2846
2857
* again. We can do this most cleanly by simply forcing the ACKM to consider
@@ -2852,7 +2863,7 @@ static int ch_retry(QUIC_CHANNEL *ch,
2852
2863
* repeated retries.
2853
2864
*/
2854
2865
if (!ossl_ackm_mark_packet_pseudo_lost (ch -> ackm , QUIC_PN_SPACE_INITIAL ,
2855
- /*PN=*/ 0 ))
2866
+ pn ))
2856
2867
return 0 ;
2857
2868
2858
2869
/*
0 commit comments