From 0098937630257bb4f4fa9c7e05a53303ccad141f Mon Sep 17 00:00:00 2001 From: Dmitri Tikhonov Date: Tue, 17 Nov 2020 11:04:32 -0500 Subject: [PATCH] Fix: if push promise fails, do not invoke hset destructor --- src/liblsquic/lsquic_full_conn.c | 13 +++++++++---- src/liblsquic/lsquic_stream.c | 8 ++++++++ src/liblsquic/lsquic_stream.h | 3 +++ 3 files changed, 20 insertions(+), 4 deletions(-) diff --git a/src/liblsquic/lsquic_full_conn.c b/src/liblsquic/lsquic_full_conn.c index 43586d4..d2fa53b 100644 --- a/src/liblsquic/lsquic_full_conn.c +++ b/src/liblsquic/lsquic_full_conn.c @@ -4084,10 +4084,15 @@ full_conn_ci_push_stream (struct lsquic_conn *lconn, void *hset, if (0 != lsquic_headers_stream_push_promise(conn->fc_pub.u.gquic.hs, dep_stream->id, pushed_stream->id, path, host, headers)) { - /* Since the failure to write to HEADERS stream results in aborting - * the connection, we do not bother rolling back. - */ - LSQ_ERROR("could not send push promise"); + /* If forget we ever had the hset pointer: */ + lsquic_stream_drop_hset_ref(pushed_stream); + /* Now roll back stream creation and return stream ID: */ + if (pushed_stream->sm_hash_el.qhe_flags & QHE_HASHED) + lsquic_hash_erase(conn->fc_pub.all_streams, + &pushed_stream->sm_hash_el); + lsquic_stream_destroy(pushed_stream); + conn->fc_last_stream_id -= 2; + LSQ_INFO("could not send push promise"); return -1; } diff --git a/src/liblsquic/lsquic_stream.c b/src/liblsquic/lsquic_stream.c index 6538853..4a3d675 100644 --- a/src/liblsquic/lsquic_stream.c +++ b/src/liblsquic/lsquic_stream.c @@ -536,6 +536,14 @@ drop_buffered_data (struct lsquic_stream *stream) } +void +lsquic_stream_drop_hset_ref (struct lsquic_stream *stream) +{ + if (stream->uh) + stream->uh->uh_hset = NULL; +} + + static void destroy_uh (struct lsquic_stream *stream) { diff --git a/src/liblsquic/lsquic_stream.h b/src/liblsquic/lsquic_stream.h index f7b7c93..4486ef6 100644 --- a/src/liblsquic/lsquic_stream.h +++ b/src/liblsquic/lsquic_stream.h @@ -606,4 +606,7 @@ lsquic_stream_verify_len (struct lsquic_stream *, unsigned long long); #define lsquic_stream_is_blocked(stream_) ((stream_)->blocked_off && \ (stream_)->blocked_off == (stream_)->max_send_off) +void +lsquic_stream_drop_hset_ref (struct lsquic_stream *); + #endif