Skip to content

Commit 9713ae7

Browse files
committed
Determine which packet to drop for retry
When doing a retry after a version negotiation, we actually need to drop packet 1 rather than 0 to get a retransmit of the initial packet Reviewed-by: Saša Nedvědický <[email protected]> Reviewed-by: Tim Hudson <[email protected]> (Merged from openssl#26000)
1 parent d8e4291 commit 9713ae7

File tree

1 file changed

+18
-7
lines changed

1 file changed

+18
-7
lines changed

ssl/quic/quic_channel.c

+18-7
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,8 @@ static OSSL_TIME ch_determine_next_tick_deadline(QUIC_CHANNEL *ch);
6363
static int ch_retry(QUIC_CHANNEL *ch,
6464
const unsigned char *retry_token,
6565
size_t retry_token_len,
66-
const QUIC_CONN_ID *retry_scid);
66+
const QUIC_CONN_ID *retry_scid,
67+
int drop_later_pn);
6768
static int ch_restart(QUIC_CHANNEL *ch);
6869

6970
static void ch_cleanup(QUIC_CHANNEL *ch);
@@ -91,7 +92,8 @@ static void rxku_detected(QUIC_PN pn, void *arg);
9192
static int ch_retry(QUIC_CHANNEL *ch,
9293
const unsigned char *retry_token,
9394
size_t retry_token_len,
94-
const QUIC_CONN_ID *retry_scid);
95+
const QUIC_CONN_ID *retry_scid,
96+
int drop_later_pn);
9597
static void ch_update_idle(QUIC_CHANNEL *ch);
9698
static int ch_discard_el(QUIC_CHANNEL *ch,
9799
uint32_t enc_level);
@@ -2381,7 +2383,7 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only)
23812383

23822384
if (!ch_retry(ch, ch->qrx_pkt->hdr->data,
23832385
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))
23852387
ossl_quic_channel_raise_protocol_error(ch, OSSL_QUIC_ERR_INTERNAL_ERROR,
23862388
0, "handling retry packet");
23872389
break;
@@ -2472,6 +2474,7 @@ static void ch_rx_handle_packet(QUIC_CHANNEL *ch, int channel_only)
24722474
assert(0);
24732475
break;
24742476
}
2477+
24752478
}
24762479

24772480
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)
27902793
*/
27912794
static int ch_restart(QUIC_CHANNEL *ch)
27922795
{
2793-
27942796
/*
2795-
* Just pretend we lost our first initial packet, so it gets
2797+
* Just pretend we lost our initial packet, so it gets
27962798
* regenerated, with our updated protocol version number
27972799
*/
27982800
return ossl_ackm_mark_packet_pseudo_lost(ch->ackm, QUIC_PN_SPACE_INITIAL,
@@ -2803,9 +2805,11 @@ static int ch_restart(QUIC_CHANNEL *ch)
28032805
static int ch_retry(QUIC_CHANNEL *ch,
28042806
const unsigned char *retry_token,
28052807
size_t retry_token_len,
2806-
const QUIC_CONN_ID *retry_scid)
2808+
const QUIC_CONN_ID *retry_scid,
2809+
int drop_later_pn)
28072810
{
28082811
void *buf;
2812+
QUIC_PN pn = 0;
28092813

28102814
/*
28112815
* 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,
28412845
ch->retry_scid = *retry_scid;
28422846
ch->doing_retry = 1;
28432847

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+
28442855
/*
28452856
* We need to stimulate the Initial EL to generate the first CRYPTO frame
28462857
* 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,
28522863
* repeated retries.
28532864
*/
28542865
if (!ossl_ackm_mark_packet_pseudo_lost(ch->ackm, QUIC_PN_SPACE_INITIAL,
2855-
/*PN=*/0))
2866+
pn))
28562867
return 0;
28572868

28582869
/*

0 commit comments

Comments
 (0)