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();

Reply via email to