This is an automated email from the ASF dual-hosted git repository. cmcfarlen pushed a commit to branch 10.0.x in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit f029bf1bb7280ca8fcd676364a80b6595d9d6cc8 Author: Masakazu Kitajo <[email protected]> AuthorDate: Mon May 6 08:39:33 2024 -0600 Send EOS event when QUIC connection becomes draining state (#11317) (cherry picked from commit 7334b7f63578bd11b4cc678be6cde6c483decde4) --- src/iocore/net/P_QUICNetVConnection.h | 2 ++ src/iocore/net/QUICNetVConnection.cc | 63 +++++++++++++++++++++-------------- 2 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/iocore/net/P_QUICNetVConnection.h b/src/iocore/net/P_QUICNetVConnection.h index 9a28351787..644bc6f987 100644 --- a/src/iocore/net/P_QUICNetVConnection.h +++ b/src/iocore/net/P_QUICNetVConnection.h @@ -200,6 +200,8 @@ private: void _close_quiche_timeout(Event *data); Event *_quiche_timeout = nullptr; + void _schedule_closing_event(); + void _handle_read_ready(); void _handle_write_ready(); void _handle_interval(); diff --git a/src/iocore/net/QUICNetVConnection.cc b/src/iocore/net/QUICNetVConnection.cc index 78aa76f376..98c3deaed0 100644 --- a/src/iocore/net/QUICNetVConnection.cc +++ b/src/iocore/net/QUICNetVConnection.cc @@ -187,6 +187,10 @@ QUICNetVConnection::state_handshake(int event, Event *data) break; } + if (this->closed != 1 && (quiche_conn_is_closed(this->_quiche_con) || quiche_conn_is_draining(this->_quiche_con))) { + this->_schedule_closing_event(); + } + return EVENT_DONE; } @@ -223,6 +227,11 @@ QUICNetVConnection::state_established(int event, Event *data) QUICConDebug("Unhandled event: %d", event); break; } + + if (this->closed != 1 && (quiche_conn_is_closed(this->_quiche_con) || quiche_conn_is_draining(this->_quiche_con))) { + this->_schedule_closing_event(); + } + return EVENT_DONE; } @@ -509,10 +518,8 @@ QUICNetVConnection::is_handshake_completed() const void QUICNetVConnection::net_read_io(NetHandler * /* nh ATS_UNUSED */, EThread * /* lthread ATS_UNUSED */) { - if (quiche_conn_is_readable(this->_quiche_con)) { - SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread()); - this->handleEvent(QUIC_EVENT_PACKET_READ_READY, nullptr); - } + SCOPED_MUTEX_LOCK(lock, this->mutex, this_ethread()); + this->handleEvent(QUIC_EVENT_PACKET_READ_READY, nullptr); } int64_t @@ -602,6 +609,32 @@ QUICNetVConnection::_close_quiche_timeout(Event *data) this->_quiche_timeout = nullptr; } +void +QUICNetVConnection::_schedule_closing_event() +{ + QUICConDebug("Scheduling closing event"); + if (quiche_conn_is_timed_out(this->_quiche_con)) { + QUICConDebug("QUIC Idle timeout detected"); + this->thread->schedule_imm(this, VC_EVENT_INACTIVITY_TIMEOUT); + return; + } + + bool is_app; + uint64_t error_code; + const uint8_t *reason; + size_t reason_len; + bool has_error = quiche_conn_peer_error(this->_quiche_con, &is_app, &error_code, &reason, &reason_len) || + quiche_conn_local_error(this->_quiche_con, &is_app, &error_code, &reason, &reason_len); + if (has_error && error_code != static_cast<uint64_t>(QUICTransErrorCode::NO_ERROR)) { + QUICConDebug("is_app=%d error_code=%" PRId64 " reason=%.*s", is_app, error_code, static_cast<int>(reason_len), reason); + this->thread->schedule_imm(this, VC_EVENT_ERROR); + return; + } + + // If it's not timeout nor error, it's probably eos + this->thread->schedule_imm(this, VC_EVENT_EOS); +} + void QUICNetVConnection::_handle_read_ready() { @@ -683,27 +716,7 @@ QUICNetVConnection::_handle_interval() quiche_conn_on_timeout(this->_quiche_con); if (quiche_conn_is_closed(this->_quiche_con)) { - if (quiche_conn_is_timed_out(this->_quiche_con)) { - QUICConDebug("QUIC Idle timeout detected"); - this->thread->schedule_imm(this, VC_EVENT_INACTIVITY_TIMEOUT); - return; - } - - bool is_app; - uint64_t error_code; - const uint8_t *reason; - size_t reason_len; - bool has_error = quiche_conn_peer_error(this->_quiche_con, &is_app, &error_code, &reason, &reason_len) || - quiche_conn_local_error(this->_quiche_con, &is_app, &error_code, &reason, &reason_len); - if (has_error && error_code != static_cast<uint64_t>(QUICTransErrorCode::NO_ERROR)) { - QUICConDebug("is_app=%d error_code=%" PRId64 " reason=%.*s", is_app, error_code, static_cast<int>(reason_len), reason); - this->thread->schedule_imm(this, VC_EVENT_ERROR); - return; - } - - // If it's not timeout nor error, it's probably eos - this->thread->schedule_imm(this, VC_EVENT_EOS); - + this->_schedule_closing_event(); } else { // Just schedule timeout event again if the connection is still open this->_schedule_quiche_timeout();
