diff options
Diffstat (limited to 'ssl/quic/quic_stream_map.c')
-rw-r--r-- | ssl/quic/quic_stream_map.c | 68 |
1 files changed, 62 insertions, 6 deletions
diff --git a/ssl/quic/quic_stream_map.c b/ssl/quic/quic_stream_map.c index cbc947398f..9fc5ca9f87 100644 --- a/ssl/quic/quic_stream_map.c +++ b/ssl/quic/quic_stream_map.c @@ -53,12 +53,16 @@ static QUIC_STREAM *list_next(QUIC_STREAM_LIST_NODE *l, QUIC_STREAM_LIST_NODE *n return (QUIC_STREAM *)(((char *)n) - off); } -#define active_next(l, s) list_next((l), &(s)->active_node, \ - offsetof(QUIC_STREAM, active_node)) -#define accept_next(l, s) list_next((l), &(s)->accept_node, \ - offsetof(QUIC_STREAM, accept_node)) -#define accept_head(l) list_next((l), (l), \ - offsetof(QUIC_STREAM, accept_node)) +#define active_next(l, s) list_next((l), &(s)->active_node, \ + offsetof(QUIC_STREAM, active_node)) +#define accept_next(l, s) list_next((l), &(s)->accept_node, \ + offsetof(QUIC_STREAM, accept_node)) +#define ready_for_gc_next(l, s) list_next((l), &(s)->ready_for_gc_node, \ + offsetof(QUIC_STREAM, ready_for_gc_node)) +#define accept_head(l) list_next((l), (l), \ + offsetof(QUIC_STREAM, accept_node)) +#define ready_for_gc_head(l) list_next((l), (l), \ + offsetof(QUIC_STREAM, ready_for_gc_node)) static unsigned long hash_stream(const QUIC_STREAM *s) { @@ -83,6 +87,8 @@ int ossl_quic_stream_map_init(QUIC_STREAM_MAP *qsm, qsm->map = lh_QUIC_STREAM_new(hash_stream, cmp_stream); qsm->active_list.prev = qsm->active_list.next = &qsm->active_list; qsm->accept_list.prev = qsm->accept_list.next = &qsm->accept_list; + qsm->ready_for_gc_list.prev = qsm->ready_for_gc_list.next + = &qsm->ready_for_gc_list; qsm->rr_stepping = 1; qsm->rr_counter = 0; qsm->rr_cur = NULL; @@ -145,6 +151,13 @@ void ossl_quic_stream_map_release(QUIC_STREAM_MAP *qsm, QUIC_STREAM *stream) if (stream == NULL) return; + if (stream->active_node.next != NULL) + list_remove(&qsm->active_list, &stream->active_node); + if (stream->accept_node.next != NULL) + list_remove(&qsm->accept_list, &stream->accept_node); + if (stream->ready_for_gc_node.next != NULL) + list_remove(&qsm->ready_for_gc_list, &stream->ready_for_gc_node); + ossl_quic_sstream_free(stream->sstream); stream->sstream = NULL; @@ -228,6 +241,31 @@ static int stream_has_data_to_send(QUIC_STREAM *s) return (shdr.is_fin && shdr.len == 0) || shdr.offset < fc_limit; } +static int qsm_ready_for_gc(QUIC_STREAM_MAP *qsm, QUIC_STREAM *qs) +{ + int recv_stream_fully_drained = 0; /* TODO(QUIC): Optimisation */ + + /* + * If sstream has no FIN, we auto-reset it at marked-for-deletion time, so + * we don't need to worry about that here. + */ + assert(!qs->deleted + || qs->sstream == NULL + || qs->reset_stream + || ossl_quic_sstream_get_final_size(qs, NULL)); + + return + qs->deleted + && (qs->rstream == NULL + || recv_stream_fully_drained + || qs->acked_stop_sending) + && (qs->sstream == NULL + || (!qs->reset_stream + && ossl_quic_sstream_is_totally_acked(qs->sstream)) + || (qs->reset_stream + && qs->acked_reset_stream)); +} + void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) { int should_be_active, allowed_by_stream_limit = 1; @@ -243,8 +281,15 @@ void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) allowed_by_stream_limit = (stream_ordinal < stream_limit); } + if (!s->ready_for_gc) { + s->ready_for_gc = qsm_ready_for_gc(qsm, s); + if (s->ready_for_gc) + list_insert_tail(&qsm->ready_for_gc_list, &s->ready_for_gc_node); + } + should_be_active = allowed_by_stream_limit + && !s->ready_for_gc && ((!s->peer_reset_stream && s->rstream != NULL && (s->want_max_stream_data || ossl_quic_rxfc_has_cwm_changed(&s->rxfc, 0))) @@ -325,6 +370,17 @@ size_t ossl_quic_stream_map_get_accept_queue_len(QUIC_STREAM_MAP *qsm) return qsm->num_accept; } +void ossl_quic_stream_map_gc(QUIC_STREAM_MAP *qsm) +{ + QUIC_STREAM *qs, *qsn; + + for (qs = ready_for_gc_head(&qsm->ready_for_gc_list); qs != NULL; qs = qsn) { + qsn = ready_for_gc_next(&qsm->ready_for_gc_list, qs); + + ossl_quic_stream_map_release(qsm, qs); + } +} + /* * QUIC Stream Iterator * ==================== |