summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHugo Landau <hlandau@openssl.org>2023-04-18 19:30:55 +0100
committerHugo Landau <hlandau@openssl.org>2023-05-12 14:47:12 +0100
commit5d27e7e9ae7135f8ba92498e3c4e7f9b77f2f8e3 (patch)
treec9cf4fcc867692c2c13d629a64961940a18d03db
parent13ac037d0148b6e461ca635bb1c627a4b759318a (diff)
downloadopenssl-new-5d27e7e9ae7135f8ba92498e3c4e7f9b77f2f8e3.tar.gz
QUIC FIFD: Ensure QUIC_STREAM is updated after QUIC_SSTREAM loss
Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/20765)
-rw-r--r--include/internal/quic_fifd.h8
-rw-r--r--ssl/quic/quic_fifd.c22
-rw-r--r--ssl/quic/quic_txp.c16
-rw-r--r--test/quic_fifd_test.c6
4 files changed, 46 insertions, 6 deletions
diff --git a/include/internal/quic_fifd.h b/include/internal/quic_fifd.h
index 4a42449bbe..ae9e32882a 100644
--- a/include/internal/quic_fifd.h
+++ b/include/internal/quic_fifd.h
@@ -37,6 +37,9 @@ struct quic_fifd_st {
QUIC_TXPIM_PKT *pkt,
void *arg);
void *regen_frame_arg;
+ void (*sstream_updated)(uint64_t stream_id,
+ void *arg);
+ void *sstream_updated_arg;
};
int ossl_quic_fifd_init(QUIC_FIFD *fifd,
@@ -53,7 +56,10 @@ int ossl_quic_fifd_init(QUIC_FIFD *fifd,
uint64_t stream_id,
QUIC_TXPIM_PKT *pkt,
void *arg),
- void *regen_frame_arg);
+ void *regen_frame_arg,
+ void (*sstream_updated)(uint64_t stream_id,
+ void *arg),
+ void *sstream_updated_arg);
void ossl_quic_fifd_cleanup(QUIC_FIFD *fifd); /* (no-op) */
diff --git a/ssl/quic/quic_fifd.c b/ssl/quic/quic_fifd.c
index e7241f60a8..ced7e31813 100644
--- a/ssl/quic/quic_fifd.c
+++ b/ssl/quic/quic_fifd.c
@@ -26,7 +26,10 @@ int ossl_quic_fifd_init(QUIC_FIFD *fifd,
uint64_t stream_id,
QUIC_TXPIM_PKT *pkt,
void *arg),
- void *regen_frame_arg)
+ void *regen_frame_arg,
+ void (*sstream_updated)(uint64_t stream_id,
+ void *arg),
+ void *sstream_updated_arg)
{
if (cfq == NULL || ackm == NULL || txpim == NULL
|| get_sstream_by_id == NULL || regen_frame == NULL)
@@ -39,6 +42,8 @@ int ossl_quic_fifd_init(QUIC_FIFD *fifd,
fifd->get_sstream_by_id_arg = get_sstream_by_id_arg;
fifd->regen_frame = regen_frame;
fifd->regen_frame_arg = regen_frame_arg;
+ fifd->sstream_updated = sstream_updated;
+ fifd->sstream_updated_arg = sstream_updated_arg;
return 1;
}
@@ -89,6 +94,7 @@ static void on_lost(void *arg)
size_t i, num_chunks = ossl_quic_txpim_pkt_get_num_chunks(pkt);
QUIC_SSTREAM *sstream;
QUIC_CFQ_ITEM *cfq_item, *cfq_item_next;
+ int sstream_updated;
/* STREAM and CRYPTO stream chunks, FIN and stream FC frames */
for (i = 0; i < num_chunks; ++i) {
@@ -98,12 +104,18 @@ static void on_lost(void *arg)
if (sstream == NULL)
continue;
- if (chunks[i].end >= chunks[i].start)
+ sstream_updated = 0;
+
+ if (chunks[i].end >= chunks[i].start) {
ossl_quic_sstream_mark_lost(sstream,
chunks[i].start, chunks[i].end);
+ sstream_updated = 1;
+ }
- if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX)
+ if (chunks[i].has_fin && chunks[i].stream_id != UINT64_MAX) {
ossl_quic_sstream_mark_lost_fin(sstream);
+ sstream_updated = 1;
+ }
if (chunks[i].has_stop_sending && chunks[i].stream_id != UINT64_MAX)
fifd->regen_frame(OSSL_QUIC_FRAME_TYPE_STOP_SENDING,
@@ -129,6 +141,10 @@ static void on_lost(void *arg)
chunks[i].stream_id,
pkt,
fifd->regen_frame_arg);
+
+ if (sstream_updated && chunks[i].stream_id != UINT64_MAX)
+ fifd->sstream_updated(chunks[i].stream_id,
+ fifd->sstream_updated_arg);
}
/* GCR */
diff --git a/ssl/quic/quic_txp.c b/ssl/quic/quic_txp.c
index 786d25ecf6..97a88c3ff1 100644
--- a/ssl/quic/quic_txp.c
+++ b/ssl/quic/quic_txp.c
@@ -310,6 +310,7 @@ static QUIC_SSTREAM *get_sstream_by_id(uint64_t stream_id, uint32_t pn_space,
void *arg);
static void on_regen_notify(uint64_t frame_type, uint64_t stream_id,
QUIC_TXPIM_PKT *pkt, void *arg);
+static void on_sstream_updated(uint64_t stream_id, void *arg);
static int sstream_is_pending(QUIC_SSTREAM *sstream);
static int txp_el_pending(OSSL_QUIC_TX_PACKETISER *txp, uint32_t enc_level,
uint32_t archetype,
@@ -365,7 +366,8 @@ OSSL_QUIC_TX_PACKETISER *ossl_quic_tx_packetiser_new(const OSSL_QUIC_TX_PACKETIS
if (!ossl_quic_fifd_init(&txp->fifd,
txp->args.cfq, txp->args.ackm, txp->args.txpim,
get_sstream_by_id, txp,
- on_regen_notify, txp)) {
+ on_regen_notify, txp,
+ on_sstream_updated, txp)) {
OPENSSL_free(txp);
return NULL;
}
@@ -1120,6 +1122,18 @@ static void on_regen_notify(uint64_t frame_type, uint64_t stream_id,
}
}
+static void on_sstream_updated(uint64_t stream_id, void *arg)
+{
+ OSSL_QUIC_TX_PACKETISER *txp = arg;
+ QUIC_STREAM *s;
+
+ s = ossl_quic_stream_map_get_by_id(txp->args.qsm, stream_id);
+ if (s == NULL)
+ return;
+
+ ossl_quic_stream_map_update_state(txp->args.qsm, s);
+}
+
static int txp_generate_pre_token(OSSL_QUIC_TX_PACKETISER *txp,
struct tx_helper *h,
QUIC_TXPIM_PKT *tpkt,
diff --git a/test/quic_fifd_test.c b/test/quic_fifd_test.c
index d3d13bf53f..ccf01fb89b 100644
--- a/test/quic_fifd_test.c
+++ b/test/quic_fifd_test.c
@@ -40,6 +40,9 @@ static void regen_frame(uint64_t frame_type, uint64_t stream_id,
regen_frame_p(frame_type, stream_id, pkt, arg);
}
+static void sstream_updated(uint64_t stream_id, void *arg)
+{}
+
typedef struct info_st {
QUIC_FIFD fifd;
OSSL_ACKM *ackm;
@@ -329,7 +332,8 @@ static int test_fifd(int idx)
|| !TEST_true(ossl_quic_fifd_init(&info.fifd, info.cfq, info.ackm,
info.txpim,
get_sstream_by_id, NULL,
- regen_frame, NULL)))
+ regen_frame, NULL,
+ sstream_updated, NULL)))
goto err;
for (i = 0; i < OSSL_NELEM(info.sstream); ++i)