diff options
author | Hugo Landau <hlandau@openssl.org> | 2023-04-18 19:30:55 +0100 |
---|---|---|
committer | Hugo Landau <hlandau@openssl.org> | 2023-05-12 14:47:12 +0100 |
commit | b89c81e43b88c48d7cb5ce48665bab6c36ae02ac (patch) | |
tree | 8e05251eac8cce369d6daf6d1197037940b8a945 /ssl | |
parent | 90cecc406f58b229ffa9c8e8473eaa6924c4a5d5 (diff) |
QUIC QSM: Handle STOP_SENDING correctly
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20765)
Diffstat (limited to 'ssl')
-rw-r--r-- | ssl/quic/quic_rx_depack.c | 9 | ||||
-rw-r--r-- | ssl/quic/quic_stream_map.c | 24 |
2 files changed, 26 insertions, 7 deletions
diff --git a/ssl/quic/quic_rx_depack.c b/ssl/quic/quic_rx_depack.c index a81f47d6d9..2bc4e146e8 100644 --- a/ssl/quic/quic_rx_depack.c +++ b/ssl/quic/quic_rx_depack.c @@ -172,7 +172,14 @@ static int depack_do_frame_stop_sending(PACKET *pkt, } stream->peer_stop_sending = 1; - ossl_quic_stream_map_update_state(&ch->qsm, stream); + + /* + * RFC 9000 s. 3.5: Receiving a STOP_SENDING frame means we must respond in + * turn with a RESET_STREAM frame for the same part of the stream. The other + * part is unaffected. + */ + ossl_quic_stream_map_reset_stream_send_part(&ch->qsm, stream, + frame_data.app_error_code); return 1; } diff --git a/ssl/quic/quic_stream_map.c b/ssl/quic/quic_stream_map.c index a9c616ea9f..2f58b2a51a 100644 --- a/ssl/quic/quic_stream_map.c +++ b/ssl/quic/quic_stream_map.c @@ -271,14 +271,12 @@ void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) should_be_active = allowed_by_stream_limit - && !s->peer_stop_sending - && !s->peer_reset_stream - && ((s->rstream != NULL - && (s->want_max_stream_data - || ossl_quic_rxfc_has_cwm_changed(&s->rxfc, 0))) + && ((!s->peer_reset_stream && s->rstream != NULL + && (s->want_max_stream_data + || ossl_quic_rxfc_has_cwm_changed(&s->rxfc, 0))) || s->want_stop_sending || s->want_reset_stream - || stream_has_data_to_send(s)); + || (!s->peer_stop_sending && stream_has_data_to_send(s))); if (should_be_active) stream_map_mark_active(qsm, s); @@ -286,6 +284,20 @@ void ossl_quic_stream_map_update_state(QUIC_STREAM_MAP *qsm, QUIC_STREAM *s) stream_map_mark_inactive(qsm, s); } +void ossl_quic_stream_map_reset_stream_send_part(QUIC_STREAM_MAP *qsm, + QUIC_STREAM *qs, + uint64_t aec) +{ + if (qs->reset_stream) + return; + + qs->reset_stream = 1; + qs->reset_stream_aec = aec; + qs->want_reset_stream = 1; + + ossl_quic_stream_map_update_state(qsm, qs); +} + QUIC_STREAM *ossl_quic_stream_map_peek_accept_queue(QUIC_STREAM_MAP *qsm) { return accept_head(&qsm->accept_list); |