Handle GOAWAY gracefully in MasqueH2Connection PiperOrigin-RevId: 923377735
diff --git a/quiche/quic/masque/masque_connection_pool.cc b/quiche/quic/masque/masque_connection_pool.cc index d3803c8..abc4cd5 100644 --- a/quiche/quic/masque/masque_connection_pool.cc +++ b/quiche/quic/masque/masque_connection_pool.cc
@@ -358,7 +358,8 @@ ConnectionState * connection, GetOrCreateConnectionState(std::string(authority->second), mtls)); auto pending_request = std::make_unique<PendingRequest>(); - if (connection->connection() != nullptr) { + if (connection->connection() != nullptr && + !connection->connection()->aborted()) { QUICHE_LOG(INFO) << ENDPOINT << "Reusing existing connection " << connection->connection()->info() << " to " << authority->second;
diff --git a/quiche/quic/masque/masque_h2_connection.cc b/quiche/quic/masque/masque_h2_connection.cc index c856a56..8413215 100644 --- a/quiche/quic/masque/masque_h2_connection.cc +++ b/quiche/quic/masque/masque_h2_connection.cc
@@ -100,6 +100,13 @@ void MasqueH2Connection::Abort(absl::Status error) { QUICHE_CHECK(!error.ok()); + if (has_closed_gracefully_) { + QUICHE_LOG(INFO) + << ENDPOINT + << "Connection already closed gracefully, ignoring new error: " + << error.message(); + return; + } if (aborted()) { QUICHE_LOG(ERROR) << ENDPOINT << "Connection already aborted, ignoring new error: " @@ -549,6 +556,28 @@ << last_accepted_stream_id << " error_code: " << Http2ErrorCodeToString(error_code) << " opaque_data length: " << opaque_data.size(); + for (auto it = h2_streams_.begin(); it != h2_streams_.end();) { + if (it->first > last_accepted_stream_id) { + if (!it->second->callback_fired) { + visitor_->OnStreamFailure( + this, it->first, + absl::InternalError( + absl::StrCat("Stream ", it->first, + " cancelled due to GOAWAY with error code ", + Http2ErrorCodeToString(error_code)))); + } + h2_streams_.erase(it++); + } else { + ++it; + } + } + if (h2_streams_.empty() && !has_closed_gracefully_) { + QUICHE_LOG(INFO) << ENDPOINT + << "Received GOAWAY and all streams closed, closing " + "connection gracefully"; + has_closed_gracefully_ = true; + visitor_->OnConnectionFinished(this, absl::OkStatus()); + } return true; }
diff --git a/quiche/quic/masque/masque_h2_connection.h b/quiche/quic/masque/masque_h2_connection.h index ee9fe95..1a93e0b 100644 --- a/quiche/quic/masque/masque_h2_connection.h +++ b/quiche/quic/masque/masque_h2_connection.h
@@ -65,7 +65,7 @@ ~MasqueH2Connection(); - bool aborted() const { return !error_.ok(); } + bool aborted() const { return !error_.ok() || has_closed_gracefully_; } // Call when there is more data to be read from SSL. void OnTransportReadable(); // Call when there is more data to be written to SSL. @@ -155,6 +155,7 @@ SSL* ssl_; std::unique_ptr<http2::adapter::OgHttp2Adapter> h2_adapter_; const bool is_server_; + bool has_closed_gracefully_ = false; const std::string info_; bool tls_connected_ = false; absl::Status error_ = absl::OkStatus();