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 2017/12/01 02:14:38 UTC

[trafficserver] 02/02: Make state transition solid

This is an automated email from the ASF dual-hosted git repository.

maskit pushed a commit to branch quic-latest
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit a0ec809922cf7b1f1736d6eb71dbc5bf6f6da462
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Fri Dec 1 11:12:05 2017 +0900

    Make state transition solid
---
 iocore/net/P_QUICNetVConnection.h |  4 +++
 iocore/net/QUICNetVConnection.cc  | 71 ++++++++++++++++++++++++++++++---------
 2 files changed, 60 insertions(+), 15 deletions(-)

diff --git a/iocore/net/P_QUICNetVConnection.h b/iocore/net/P_QUICNetVConnection.h
index 9e4b594..c80a2b6 100644
--- a/iocore/net/P_QUICNetVConnection.h
+++ b/iocore/net/P_QUICNetVConnection.h
@@ -257,7 +257,11 @@ private:
   void _handle_error(QUICErrorUPtr error);
   QUICPacketUPtr _dequeue_recv_packet(QUICPacketCreationResult &result);
 
+  int _complete_handshake_if_possible();
+  void _switch_to_handshake_state();
   void _switch_to_established_state();
+  void _switch_to_closing_state();
+  void _switch_to_close_state();
 
   QUICStatelessToken _token;
 };
diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc
index 2e148c3..9522cc3 100644
--- a/iocore/net/QUICNetVConnection.cc
+++ b/iocore/net/QUICNetVConnection.cc
@@ -302,8 +302,7 @@ QUICNetVConnection::close(QUICConnectionErrorUPtr error)
       this->handler == reinterpret_cast<ContinuationHandler>(&QUICNetVConnection::state_connection_closing)) {
     // do nothing
   } else {
-    DebugQUICCon("Enter state_connection_closing");
-    SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_closing);
+    this->_switch_to_closing_state();
     if (error->cls == QUICErrorClass::APPLICATION) {
       this->transmit_frame(QUICFrameFactory::create_application_close_frame(std::move(error)));
     } else {
@@ -336,9 +335,7 @@ QUICNetVConnection::handle_frame(std::shared_ptr<const QUICFrame> frame)
     // BLOCKED frame is for debugging. Nothing to do here.
     break;
   case QUICFrameType::CONNECTION_CLOSE:
-    DebugQUICCon("Enter state_connection_closed");
-    SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_closed);
-    this_ethread()->schedule_imm(this, QUIC_EVENT_SHUTDOWN, nullptr);
+    this->_switch_to_close_state();
     break;
   default:
     DebugQUICCon("Unexpected frame type: %02x", static_cast<unsigned int>(frame->type()));
@@ -370,8 +367,7 @@ QUICNetVConnection::state_pre_handshake(int event, Event *data)
   this->set_inactivity_timeout(HRTIME_SECONDS(params->no_activity_timeout_in()));
   this->add_to_active_queue();
 
-  DebugQUICCon("Enter state_handshake");
-  SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_handshake);
+  this->_switch_to_handshake_state();
   return this->handleEvent(event, data);
 }
 
@@ -383,7 +379,7 @@ QUICNetVConnection::state_handshake(int event, Event *data)
 
   if (this->_handshake_handler && this->_handshake_handler->is_completed()) {
     this->_switch_to_established_state();
-    return this->state_connection_established(event, data);
+    return this->handleEvent(event, data);
   }
 
   QUICErrorUPtr error = QUICErrorUPtr(new QUICNoError());
@@ -485,9 +481,7 @@ QUICNetVConnection::state_connection_closing(int event, Event *data)
 
   // FIXME Enter closed state if CONNECTION_CLOSE was ACKed
   if (true) {
-    DebugQUICCon("Enter state_connection_closed");
-    SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_closed);
-    this_ethread()->schedule_imm(this, QUIC_EVENT_SHUTDOWN, nullptr);
+    this->_switch_to_close_state();
   }
 
   return EVENT_DONE;
@@ -974,9 +968,17 @@ QUICNetVConnection::_close_packet_write_ready(Event *data)
   this->_packet_write_ready = nullptr;
 }
 
-void
-QUICNetVConnection::_switch_to_established_state()
+int
+QUICNetVConnection::_complete_handshake_if_possible()
 {
+  if (this->handler != reinterpret_cast<NetVConnHandler>(&QUICNetVConnection::state_handshake)) {
+    return 0;
+  }
+
+  if (!(this->_handshake_handler && this->_handshake_handler->is_completed())) {
+    return -1;
+  }
+
   this->_init_flow_control_params(this->_handshake_handler->local_transport_parameters(),
                                   this->_handshake_handler->remote_transport_parameters());
 
@@ -995,6 +997,45 @@ QUICNetVConnection::_switch_to_established_state()
     endpoint->handleEvent(NET_EVENT_ACCEPT, this);
   }
 
-  DebugQUICCon("Enter state_connection_established");
-  SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_established);
+  return 0;
+}
+
+void
+QUICNetVConnection::_switch_to_handshake_state()
+{
+  DebugQUICCon("Enter state_handshake");
+  SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_handshake);
+}
+
+void
+QUICNetVConnection::_switch_to_established_state()
+{
+  if (this->_complete_handshake_if_possible() == 0) {
+    DebugQUICCon("Enter state_connection_established");
+    SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_established);
+  } else {
+    // Illegal state change
+    ink_assert(!"Handshake has to be completed");
+  }
+}
+
+void
+QUICNetVConnection::_switch_to_closing_state()
+{
+  if (this->_complete_handshake_if_possible() != 0) {
+    DebugQUICCon("Switching state without handshake completion");
+  }
+  DebugQUICCon("Enter state_connection_closing");
+  SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_closing);
+}
+
+void
+QUICNetVConnection::_switch_to_close_state()
+{
+  if (this->_complete_handshake_if_possible() != 0) {
+    DebugQUICCon("Switching state without handshake completion");
+  }
+  DebugQUICCon("Enter state_connection_closed");
+  SET_HANDLER((NetVConnHandler)&QUICNetVConnection::state_connection_closed);
+  this_ethread()->schedule_imm(this, QUIC_EVENT_SHUTDOWN, nullptr);
 }

-- 
To stop receiving notification emails like this one, please contact
"commits@trafficserver.apache.org" <co...@trafficserver.apache.org>.