From 073941c5a5a9d47a4065379b761c34024d460c3c Mon Sep 17 00:00:00 2001 From: Akshay K Date: Fri, 16 Jul 2021 20:28:07 -0400 Subject: [PATCH] http2: on receiving rst_stream with cancel code add it to pending list PR-URL: https://github.com/nodejs/node/pull/39423 Fixes: https://github.com/nodejs/node/issues/38964 Reviewed-By: James M Snell Reviewed-By: Matteo Collina --- src/node_http2.cc | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/node_http2.cc b/src/node_http2.cc index 57dac5f597590d..b02319e8eb55ae 100644 --- a/src/node_http2.cc +++ b/src/node_http2.cc @@ -2118,6 +2118,25 @@ int Http2Stream::SubmitPriority(const Http2Priority& priority, void Http2Stream::SubmitRstStream(const uint32_t code) { CHECK(!this->is_destroyed()); code_ = code; + + // If RST_STREAM frame is received and stream is not writable + // because it is busy reading data, don't try force purging it. + // Instead add the stream to pending stream list and process + // the pending data when it is safe to do so. This is to avoid + // double free error due to unwanted behavior of nghttp2. + // Ref:https://github.com/nodejs/node/issues/38964 + + // Add stream to the pending list if it is received with scope + // below in the stack. The pending list may not get processed + // if RST_STREAM received is not in scope and added to the list + // causing endpoint to hang. + if (session_->is_in_scope() && + !is_writable() && is_reading()) { + session_->AddPendingRstStream(id_); + return; + } + + // If possible, force a purge of any currently pending data here to make sure // it is sent before closing the stream. If it returns non-zero then we need // to wait until the current write finishes and try again to avoid nghttp2