You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by ma...@apache.org on 2022/07/07 02:27:51 UTC
[trafficserver] 03/12: Improve connection closing
This is an automated email from the ASF dual-hosted git repository.
maskit pushed a commit to branch quiche
in repository https://gitbox.apache.org/repos/asf/trafficserver.git
commit 47f904797bc64df2f531aaeb51218326a3e875e3
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Fri Jun 10 12:58:55 2022 +0900
Improve connection closing
---
iocore/net/P_QUICNetVConnection_quiche.h | 1 +
iocore/net/QUICNetVConnection_quiche.cc | 96 +++++++++++++++++++++++---------
2 files changed, 71 insertions(+), 26 deletions(-)
diff --git a/iocore/net/P_QUICNetVConnection_quiche.h b/iocore/net/P_QUICNetVConnection_quiche.h
index 2aeb05621..400d363a9 100644
--- a/iocore/net/P_QUICNetVConnection_quiche.h
+++ b/iocore/net/P_QUICNetVConnection_quiche.h
@@ -166,6 +166,7 @@ private:
void _handle_read_ready();
void _handle_write_ready();
+ void _handle_interval();
void _switch_to_established_state();
diff --git a/iocore/net/QUICNetVConnection_quiche.cc b/iocore/net/QUICNetVConnection_quiche.cc
index a5f41b376..535135abb 100644
--- a/iocore/net/QUICNetVConnection_quiche.cc
+++ b/iocore/net/QUICNetVConnection_quiche.cc
@@ -79,14 +79,12 @@ QUICNetVConnection::remove_connection_ids()
void
QUICNetVConnection::destroy(EThread *t)
{
- // QUICConDebug("Destroy connection");
- /* TODO: Uncomment these blocks after refactoring read / write process
- if (from_accept_thread) {
- quicNetVCAllocator.free(this);
- } else {
- THREAD_FREE(this, quicNetVCAllocator, t);
- }
- */
+ QUICConDebug("Destroy connection");
+ if (from_accept_thread) {
+ quicNetVCAllocator.free(this);
+ } else {
+ THREAD_FREE(this, quicNetVCAllocator, t);
+ }
}
void
@@ -97,29 +95,23 @@ QUICNetVConnection::set_local_addr()
void
QUICNetVConnection::free(EThread *t)
{
- /* TODO: Uncmment these blocks after refactoring read / write process
- this->_udp_con = nullptr;
- this->_packet_handler = nullptr;
+ QUICConDebug("Free connection");
+ this->_packet_handler->close_connection(this);
- _unschedule_packet_write_ready();
+ this->_udp_con = nullptr;
+ this->_packet_handler = nullptr;
- delete this->_handshake_handler;
- delete this->_application_map;
- delete this->_hs_protocol;
- delete this->_loss_detector;
- delete this->_frame_dispatcher;
- delete this->_stream_manager;
- delete this->_congestion_controller;
- if (this->_alt_con_manager) {
- delete this->_alt_con_manager;
- }
+ quiche_conn_free(this->_quiche_con);
- super::clear();
- */
+ delete this->_application_map;
+ this->_application_map = nullptr;
+ delete this->_stream_manager;
+ this->_stream_manager = nullptr;
+
+ super::clear();
this->_context->trigger(QUICContext::CallbackEvent::CONNECTION_CLOSE);
ALPNSupport::clear();
TLSBasicSupport::clear();
- this->_packet_handler->close_connection(this);
}
void
@@ -145,7 +137,11 @@ QUICNetVConnection::state_handshake(int event, Event *data)
// Reschedule WRITE_READY
this->_schedule_packet_write_ready(true);
break;
+ case EVENT_INTERVAL:
+ this->_handle_interval();
+ break;
default:
+ QUICConDebug("Unhandleed event: %d", event);
break;
}
@@ -165,7 +161,18 @@ QUICNetVConnection::state_established(int event, Event *data)
// Reschedule WRITE_READY
this->_schedule_packet_write_ready(true);
break;
+ case EVENT_INTERVAL:
+ this->_handle_interval();
+ break;
+ case VC_EVENT_EOS:
+ case VC_EVENT_ERROR:
+ case VC_EVENT_ACTIVE_TIMEOUT:
+ case VC_EVENT_INACTIVITY_TIMEOUT:
+ _unschedule_packet_write_ready();
+ this->closed = 1;
+ break;
default:
+ QUICConDebug("Unhandleed event: %d", event);
break;
}
return EVENT_DONE;
@@ -281,6 +288,8 @@ QUICNetVConnection::acceptEvent(int event, Event *e)
action_.continuation->handleEvent(NET_EVENT_ACCEPT, this);
this->_schedule_packet_write_ready();
+ this->thread->schedule_in(this, HRTIME_MSECONDS(quiche_conn_timeout_as_millis(this->_quiche_con)));
+
return EVENT_DONE;
}
@@ -407,7 +416,7 @@ QUICNetVConnection::negotiated_application_name() const
bool
QUICNetVConnection::is_closed() const
{
- return false;
+ return quiche_conn_is_closed(this->_quiche_con);
}
bool
@@ -538,6 +547,41 @@ QUICNetVConnection::_handle_write_ready()
} while (written > 0);
}
+void
+QUICNetVConnection::_handle_interval()
+{
+ quiche_conn_on_timeout(this->_quiche_con);
+
+ if (quiche_conn_is_closed(this->_quiche_con)) {
+ this->_ctable->erase(this->_quic_connection_id, this);
+ this->_ctable->erase(this->_original_quic_connection_id, this);
+
+ if (quiche_conn_is_timed_out(this->_quiche_con)) {
+ 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);
+
+ } else {
+ // Just schedule timeout event again if the connection is still open
+ this->thread->schedule_in(this, HRTIME_MSECONDS(quiche_conn_timeout_as_millis(this->_quiche_con)));
+ }
+}
+
int
QUICNetVConnection::populate_protocol(std::string_view *results, int n) const
{