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 2018/01/10 02:51:01 UTC

[trafficserver] 01/02: Fix QUICTransportParameters for client

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

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

commit 6cf85f5621715c6b79c1d035dce3a1f4681759e6
Author: Masaori Koshiba <ma...@apache.org>
AuthorDate: Wed Jan 10 11:50:00 2018 +0900

    Fix QUICTransportParameters for client
---
 iocore/net/quic/QUICConfig.cc                      | 27 +++++-
 iocore/net/quic/QUICConfig.h                       | 22 +++--
 iocore/net/quic/QUICHandshake.cc                   | 95 ++++++++++++++--------
 iocore/net/quic/QUICHandshake.h                    |  4 +-
 iocore/net/quic/QUICTransportParameters.cc         | 38 +++++----
 iocore/net/quic/QUICTransportParameters.h          |  1 +
 .../net/quic/test/test_QUICTransportParameters.cc  |  6 +-
 7 files changed, 130 insertions(+), 63 deletions(-)

diff --git a/iocore/net/quic/QUICConfig.cc b/iocore/net/quic/QUICConfig.cc
index 3d6f645..61e7411 100644
--- a/iocore/net/quic/QUICConfig.cc
+++ b/iocore/net/quic/QUICConfig.cc
@@ -34,6 +34,7 @@ void
 QUICConfigParams::initialize()
 {
   REC_EstablishStaticConfigInt32U(this->_no_activity_timeout_in, "proxy.config.quic.no_activity_timeout_in");
+  REC_EstablishStaticConfigInt32U(this->_no_activity_timeout_out, "proxy.config.quic.no_activity_timeout_out");
   REC_EstablishStaticConfigInt32U(this->_server_id, "proxy.config.quic.server_id");
 }
 
@@ -44,6 +45,12 @@ QUICConfigParams::no_activity_timeout_in() const
 }
 
 uint32_t
+QUICConfigParams::no_activity_timeout_out() const
+{
+  return this->_no_activity_timeout_out;
+}
+
+uint32_t
 QUICConfigParams::server_id() const
 {
   return this->_server_id;
@@ -62,15 +69,27 @@ QUICConfigParams::initial_max_stream_data() const
 }
 
 uint32_t
-QUICConfigParams::initial_max_stream_id_bidi() const
+QUICConfigParams::initial_max_stream_id_bidi_in() const
+{
+  return this->_initial_max_stream_id_bidi_in;
+}
+
+uint32_t
+QUICConfigParams::initial_max_stream_id_bidi_out() const
+{
+  return this->_initial_max_stream_id_bidi_out;
+}
+
+uint32_t
+QUICConfigParams::initial_max_stream_id_uni_in() const
 {
-  return this->_initial_max_stream_id_bidi;
+  return this->_initial_max_stream_id_uni_in;
 }
 
 uint32_t
-QUICConfigParams::initial_max_stream_id_uni() const
+QUICConfigParams::initial_max_stream_id_uni_out() const
 {
-  return this->_initial_max_stream_id_uni;
+  return this->_initial_max_stream_id_uni_out;
 }
 
 //
diff --git a/iocore/net/quic/QUICConfig.h b/iocore/net/quic/QUICConfig.h
index c6adba4..c4525a1 100644
--- a/iocore/net/quic/QUICConfig.h
+++ b/iocore/net/quic/QUICConfig.h
@@ -31,20 +31,26 @@ public:
   void initialize();
 
   uint32_t no_activity_timeout_in() const;
+  uint32_t no_activity_timeout_out() const;
   uint32_t initial_max_data() const;
   uint32_t initial_max_stream_data() const;
-  uint32_t initial_max_stream_id_bidi() const;
-  uint32_t initial_max_stream_id_uni() const;
+  uint32_t initial_max_stream_id_bidi_in() const;
+  uint32_t initial_max_stream_id_bidi_out() const;
+  uint32_t initial_max_stream_id_uni_in() const;
+  uint32_t initial_max_stream_id_uni_out() const;
   uint32_t server_id() const;
 
 private:
   // FIXME Fill appropriate values
-  uint32_t _no_activity_timeout_in     = 0;
-  uint32_t _initial_max_data           = 131072;
-  uint32_t _initial_max_stream_data    = 2048;
-  uint32_t _initial_max_stream_id_bidi = 100;
-  uint32_t _initial_max_stream_id_uni  = 102;
-  uint32_t _server_id                  = 0;
+  uint32_t _no_activity_timeout_in         = 30;
+  uint32_t _no_activity_timeout_out        = 30;
+  uint32_t _initial_max_data               = 131072;
+  uint32_t _initial_max_stream_data        = 2048;
+  uint32_t _initial_max_stream_id_bidi_in  = 100;
+  uint32_t _initial_max_stream_id_bidi_out = 101;
+  uint32_t _initial_max_stream_id_uni_in   = 102;
+  uint32_t _initial_max_stream_id_uni_out  = 103;
+  uint32_t _server_id                      = 0;
 };
 
 class QUICConfig
diff --git a/iocore/net/quic/QUICHandshake.cc b/iocore/net/quic/QUICHandshake.cc
index b2ff6e6..f47b4a2 100644
--- a/iocore/net/quic/QUICHandshake.cc
+++ b/iocore/net/quic/QUICHandshake.cc
@@ -178,7 +178,7 @@ QUICHandshake::negotiated_application_name(const uint8_t **name, unsigned int *l
 }
 
 void
-QUICHandshake::set_transport_parameters(std::shared_ptr<QUICTransportParameters> tp)
+QUICHandshake::set_transport_parameters(std::shared_ptr<QUICTransportParametersInClientHello> tp)
 {
   // An endpoint MUST treat receipt of duplicate transport parameters as a connection error of type TRANSPORT_PARAMETER_ERROR.
   if (!tp->is_valid()) {
@@ -187,27 +187,33 @@ QUICHandshake::set_transport_parameters(std::shared_ptr<QUICTransportParameters>
     return;
   }
 
-  this->_remote_transport_parameters = std::move(tp);
+  this->_remote_transport_parameters = tp;
 
-  const QUICTransportParametersInClientHello *tp_in_ch =
-    dynamic_cast<const QUICTransportParametersInClientHello *>(this->_remote_transport_parameters.get());
-  if (tp_in_ch) {
-    // Version revalidation
-    if (this->_version_negotiator->validate(tp_in_ch) != QUICVersionNegotiationStatus::VALIDATED) {
-      QUICHSDebug("Version revalidation failed");
-      this->_abort_handshake(QUICTransErrorCode::VERSION_NEGOTIATION_ERROR);
-      return;
-    }
-    QUICHSDebug("Version negotiation validated: %x", tp_in_ch->initial_version());
+  // Version revalidation
+  if (this->_version_negotiator->validate(tp.get()) != QUICVersionNegotiationStatus::VALIDATED) {
+    QUICHSDebug("Version revalidation failed");
+    this->_abort_handshake(QUICTransErrorCode::VERSION_NEGOTIATION_ERROR);
     return;
   }
 
-  const QUICTransportParametersInEncryptedExtensions *tp_in_ee =
-    dynamic_cast<const QUICTransportParametersInEncryptedExtensions *>(this->_remote_transport_parameters.get());
-  if (tp_in_ee) {
-    // TODO Add client side implementation
+  QUICHSDebug("Version negotiation validated: %x", tp->initial_version());
+  return;
+}
+
+void
+QUICHandshake::set_transport_parameters(std::shared_ptr<QUICTransportParametersInEncryptedExtensions> tp)
+{
+  // An endpoint MUST treat receipt of duplicate transport parameters as a connection error of type TRANSPORT_PARAMETER_ERROR.
+  if (!tp->is_valid()) {
+    QUICHSDebug("Transport parameter is not valid");
+    this->_abort_handshake(QUICTransErrorCode::TRANSPORT_PARAMETER_ERROR);
     return;
   }
+
+  this->_remote_transport_parameters = tp;
+
+  // TODO Add client side implementation
+  ink_assert(false);
 }
 
 std::shared_ptr<const QUICTransportParameters>
@@ -222,6 +228,12 @@ QUICHandshake::remote_transport_parameters()
   return this->_remote_transport_parameters;
 }
 
+NetVConnectionContext_t
+QUICHandshake::netvc_context()
+{
+  return this->_netvc_context;
+}
+
 int
 QUICHandshake::state_initial(int event, Event *data)
 {
@@ -346,26 +358,43 @@ QUICHandshake::state_closed(int event, void *data)
 }
 
 void
-QUICHandshake::_load_local_transport_parameters(QUICVersion negotiated_version)
+QUICHandshake::_load_local_transport_parameters(QUICVersion version)
 {
   QUICConfig::scoped_config params;
 
-  // MUSTs
-  QUICTransportParametersInEncryptedExtensions *tp = new QUICTransportParametersInEncryptedExtensions(negotiated_version);
-
-  tp->set(QUICTransportParameterId::INITIAL_MAX_STREAM_DATA, params->initial_max_stream_data());
-  tp->set(QUICTransportParameterId::INITIAL_MAX_DATA, params->initial_max_data());
-  tp->set(QUICTransportParameterId::IDLE_TIMEOUT, static_cast<uint16_t>(params->no_activity_timeout_in()));
-  // These two are MUSTs if this is a server
-  tp->set(QUICTransportParameterId::STATELESS_RESET_TOKEN, this->_reset_token.buf(), 16);
-  tp->add_version(QUIC_SUPPORTED_VERSIONS[0]);
-
-  // MAYs
-  tp->set(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_BIDI, params->initial_max_stream_id_bidi());
-  tp->set(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_UNI, params->initial_max_stream_id_uni());
-  // this->_local_transport_parameters.add(QUICTransportParameterId::OMIT_CONNECTION_ID, {});
-  // this->_local_transport_parameters.add(QUICTransportParameterId::MAX_PACKET_SIZE, {{0x00, 0x00}, 2});
-  this->_local_transport_parameters = std::unique_ptr<QUICTransportParameters>(tp);
+  if (this->_netvc_context == NET_VCONNECTION_IN) {
+    QUICTransportParametersInEncryptedExtensions *tp = new QUICTransportParametersInEncryptedExtensions(version);
+
+    // MUSTs
+    tp->set(QUICTransportParameterId::INITIAL_MAX_STREAM_DATA, params->initial_max_stream_data());
+    tp->set(QUICTransportParameterId::INITIAL_MAX_DATA, params->initial_max_data());
+    tp->set(QUICTransportParameterId::IDLE_TIMEOUT, static_cast<uint16_t>(params->no_activity_timeout_in()));
+
+    // These two are MUSTs if this is a server
+    tp->set(QUICTransportParameterId::STATELESS_RESET_TOKEN, this->_reset_token.buf(), QUICStatelessResetToken::LEN);
+    tp->add_version(QUIC_SUPPORTED_VERSIONS[0]);
+
+    // MAYs
+    tp->set(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_BIDI, params->initial_max_stream_id_bidi_in());
+    tp->set(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_UNI, params->initial_max_stream_id_uni_in());
+    // this->_local_transport_parameters.add(QUICTransportParameterId::OMIT_CONNECTION_ID, {});
+    // this->_local_transport_parameters.add(QUICTransportParameterId::MAX_PACKET_SIZE, {{0x00, 0x00}, 2});
+
+    this->_local_transport_parameters = std::unique_ptr<QUICTransportParameters>(tp);
+  } else {
+    QUICTransportParametersInClientHello *tp = new QUICTransportParametersInClientHello(version);
+
+    // MUSTs
+    tp->set(QUICTransportParameterId::INITIAL_MAX_STREAM_DATA, params->initial_max_stream_data());
+    tp->set(QUICTransportParameterId::INITIAL_MAX_DATA, params->initial_max_data());
+    tp->set(QUICTransportParameterId::IDLE_TIMEOUT, static_cast<uint16_t>(params->no_activity_timeout_out()));
+
+    // MAYs
+    tp->set(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_BIDI, params->initial_max_stream_id_bidi_out());
+    tp->set(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_UNI, params->initial_max_stream_id_uni_out());
+
+    this->_local_transport_parameters = std::unique_ptr<QUICTransportParameters>(tp);
+  }
 }
 
 QUICErrorUPtr
diff --git a/iocore/net/quic/QUICHandshake.h b/iocore/net/quic/QUICHandshake.h
index 6c426f2..f6c5f49 100644
--- a/iocore/net/quic/QUICHandshake.h
+++ b/iocore/net/quic/QUICHandshake.h
@@ -71,11 +71,13 @@ public:
   void negotiated_application_name(const uint8_t **name, unsigned int *len);
   std::shared_ptr<const QUICTransportParameters> local_transport_parameters();
   std::shared_ptr<const QUICTransportParameters> remote_transport_parameters();
+  NetVConnectionContext_t netvc_context();
 
   bool is_version_negotiated();
   bool is_completed();
 
-  void set_transport_parameters(std::shared_ptr<QUICTransportParameters> tp);
+  void set_transport_parameters(std::shared_ptr<QUICTransportParametersInClientHello> tp);
+  void set_transport_parameters(std::shared_ptr<QUICTransportParametersInEncryptedExtensions> tp);
 
 private:
   SSL *_ssl                                                             = nullptr;
diff --git a/iocore/net/quic/QUICTransportParameters.cc b/iocore/net/quic/QUICTransportParameters.cc
index c81b5f6..846a664 100644
--- a/iocore/net/quic/QUICTransportParameters.cc
+++ b/iocore/net/quic/QUICTransportParameters.cc
@@ -296,16 +296,9 @@ QUICTransportParameters::store(uint8_t *buf, uint16_t *len) const
   *len = (p - buf);
 }
 
-//
-// QUICTransportParametersInClientHello
-//
-
-QUICTransportParametersInClientHello::QUICTransportParametersInClientHello(const uint8_t *buf, size_t len)
+void
+QUICTransportParameters::_print() const
 {
-  this->_initial_version = QUICTypeUtil::read_QUICVersion(buf);
-  this->_load(buf, len);
-
-  // Print all parameters
   for (auto &p : this->_parameters) {
     if (p.second->len() == 0) {
       Debug("quic_handsahke", "%s: (no value)", QUICDebugNames::transport_parameter_id(p.first));
@@ -319,6 +312,17 @@ QUICTransportParametersInClientHello::QUICTransportParametersInClientHello(const
   }
 }
 
+//
+// QUICTransportParametersInClientHello
+//
+
+QUICTransportParametersInClientHello::QUICTransportParametersInClientHello(const uint8_t *buf, size_t len)
+{
+  this->_initial_version = QUICTypeUtil::read_QUICVersion(buf);
+  this->_load(buf, len);
+  this->_print();
+}
+
 void
 QUICTransportParametersInClientHello::_store(uint8_t *buf, uint16_t *len) const
 {
@@ -351,19 +355,19 @@ QUICTransportParametersInClientHello::_validate_parameters() const
   // MAYs
   if ((ite = this->_parameters.find(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_BIDI)) != this->_parameters.end()) {
     if (ite->second->len() != 4) {
-      return -1;
+      return -2;
     }
     if ((QUICTypeUtil::read_nbytes_as_uint(ite->second->data(), ite->second->len()) & 0x03) != 1) {
-      return -1;
+      return -3;
     }
   }
 
   if ((ite = this->_parameters.find(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_UNI)) != this->_parameters.end()) {
     if (ite->second->len() != 4) {
-      return -1;
+      return -4;
     }
     if ((QUICTypeUtil::read_nbytes_as_uint(ite->second->data(), ite->second->len()) & 0x03) != 3) {
-      return -1;
+      return -5;
     }
   }
 
@@ -388,6 +392,7 @@ QUICTransportParametersInEncryptedExtensions::QUICTransportParametersInEncrypted
     this->_versions[i] = QUICTypeUtil::read_QUICVersion(buf + 5 + (i * 4));
   }
   this->_load(buf, len);
+  this->_print();
 }
 
 void
@@ -494,7 +499,12 @@ QUICTransportParametersHandler::parse(SSL *s, unsigned int ext_type, unsigned in
                                       X509 *x, size_t chainidx, int *al, void *parse_arg)
 {
   QUICHandshake *hs = static_cast<QUICHandshake *>(SSL_get_ex_data(s, QUIC::ssl_quic_hs_index));
-  hs->set_transport_parameters(std::make_shared<QUICTransportParametersInClientHello>(in, inlen));
+
+  if (hs->netvc_context() == NET_VCONNECTION_IN) {
+    hs->set_transport_parameters(std::make_shared<QUICTransportParametersInClientHello>(in, inlen));
+  } else {
+    hs->set_transport_parameters(std::make_shared<QUICTransportParametersInEncryptedExtensions>(in, inlen));
+  }
 
   return 1;
 }
diff --git a/iocore/net/quic/QUICTransportParameters.h b/iocore/net/quic/QUICTransportParameters.h
index 6bb052e..a3f8000 100644
--- a/iocore/net/quic/QUICTransportParameters.h
+++ b/iocore/net/quic/QUICTransportParameters.h
@@ -106,6 +106,7 @@ protected:
   virtual std::ptrdiff_t _parameters_offset(const uint8_t *buf) const = 0;
   virtual int _validate_parameters() const;
   virtual void _store(uint8_t *buf, uint16_t *len) const = 0;
+  void _print() const;
 
   std::map<QUICTransportParameterId, Value *> _parameters;
 };
diff --git a/iocore/net/quic/test/test_QUICTransportParameters.cc b/iocore/net/quic/test/test_QUICTransportParameters.cc
index 520c69e..2825f2d 100644
--- a/iocore/net/quic/test/test_QUICTransportParameters.cc
+++ b/iocore/net/quic/test/test_QUICTransportParameters.cc
@@ -30,7 +30,7 @@ TEST_CASE("QUICTransportParametersInClientHello_read", "[quic]")
   SECTION("OK")
   {
     uint8_t buf[] = {
-      0x05, 0x06, 0x07, 0x08, // iinitial version
+      0x05, 0x06, 0x07, 0x08, // initial version
       0x00, 0x1e,             // size of parameters
       0x00, 0x00,             // parameter id
       0x00, 0x04,             // length of value
@@ -77,7 +77,7 @@ TEST_CASE("QUICTransportParametersInClientHello_read", "[quic]")
   SECTION("Duplicate parameters")
   {
     uint8_t buf[] = {
-      0x05, 0x06, 0x07, 0x08, // iinitial version
+      0x05, 0x06, 0x07, 0x08, // initial version
       0x00, 0x10,             // size of parameters
       0x00, 0x00,             // parameter id
       0x00, 0x04,             // length of value
@@ -98,7 +98,7 @@ TEST_CASE("QUICTransportParametersInClientHello_write", "[quic]")
   uint16_t len;
 
   uint8_t expected[] = {
-    0x05, 0x06, 0x07, 0x08,                         // iinitial version
+    0x05, 0x06, 0x07, 0x08,                         // initial version
     0x00, 0x22,                                     // size of parameters
     0x00, 0x00,                                     // parameter id
     0x00, 0x04,                                     // length of value

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