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/12 09:27:18 UTC

[trafficserver] 02/02: Send transport parameters on NewSessionTicket messages too

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 a897358589476006deddf729f5b71ec0d340b284
Author: Masakazu Kitajo <ma...@apache.org>
AuthorDate: Fri Jan 12 18:23:54 2018 +0900

    Send transport parameters on NewSessionTicket messages too
---
 iocore/net/QUICNetProcessor.cc             |   3 +-
 iocore/net/quic/QUICHandshake.cc           | 105 +++++++++++++++++++----------
 iocore/net/quic/QUICHandshake.h            |   6 +-
 iocore/net/quic/QUICTransportParameters.cc |  75 +++++++++++++++++++--
 iocore/net/quic/QUICTransportParameters.h  |  12 ++++
 5 files changed, 158 insertions(+), 43 deletions(-)

diff --git a/iocore/net/QUICNetProcessor.cc b/iocore/net/QUICNetProcessor.cc
index a67cb41..31740f5 100644
--- a/iocore/net/QUICNetProcessor.cc
+++ b/iocore/net/QUICNetProcessor.cc
@@ -70,7 +70,8 @@ QUICNetProcessor::start(int, size_t stacksize)
   SSL_CTX_set_max_proto_version(this->_ssl_ctx, TLS1_3_VERSION);
   SSL_CTX_set_alpn_select_cb(this->_ssl_ctx, QUIC::ssl_select_next_protocol, nullptr);
   SSL_CTX_add_custom_ext(this->_ssl_ctx, QUICTransportParametersHandler::TRANSPORT_PARAMETER_ID,
-                         SSL_EXT_TLS_ONLY | SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS,
+                         SSL_EXT_TLS_ONLY | SSL_EXT_CLIENT_HELLO | SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS |
+                           SSL_EXT_TLS1_3_NEW_SESSION_TICKET,
                          &QUICTransportParametersHandler::add, &QUICTransportParametersHandler::free, nullptr,
                          &QUICTransportParametersHandler::parse, nullptr);
 
diff --git a/iocore/net/quic/QUICHandshake.cc b/iocore/net/quic/QUICHandshake.cc
index b52efc0..d80a6f8 100644
--- a/iocore/net/quic/QUICHandshake.cc
+++ b/iocore/net/quic/QUICHandshake.cc
@@ -110,7 +110,7 @@ QUICHandshake::~QUICHandshake()
 QUICErrorUPtr
 QUICHandshake::start(QUICPacketFactory *packet_factory)
 {
-  this->_load_local_transport_parameters(QUIC_SUPPORTED_VERSIONS[0]);
+  this->_load_local_client_transport_parameters(QUIC_SUPPORTED_VERSIONS[0]);
   packet_factory->set_version(QUIC_SUPPORTED_VERSIONS[0]);
   return QUICErrorUPtr(new QUICNoError());
 }
@@ -126,7 +126,7 @@ QUICHandshake::start(const QUICPacket *initial_packet, QUICPacketFactory *packet
     if (initial_packet->version()) {
       if (this->_version_negotiator->negotiate(initial_packet) == QUICVersionNegotiationStatus::NEGOTIATED) {
         QUICHSDebug("Version negotiation succeeded: %x", initial_packet->version());
-        this->_load_local_transport_parameters(initial_packet->version());
+        this->_load_local_server_transport_parameters(initial_packet->version());
         packet_factory->set_version(this->_version_negotiator->negotiated_version());
       } else {
         this->_client_qc->transmit_packet(
@@ -226,10 +226,45 @@ QUICHandshake::set_transport_parameters(std::shared_ptr<QUICTransportParametersI
   ink_assert(false);
 }
 
+void
+QUICHandshake::set_transport_parameters(std::shared_ptr<QUICTransportParametersInNewSessionTicket> 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>
-QUICHandshake::local_transport_parameters()
+QUICHandshake::local_transport_parameters(bool with_version)
 {
-  return this->_local_transport_parameters;
+  if (with_version) {
+    return this->_local_transport_parameters;
+  } else {
+    QUICConfig::scoped_config params;
+    QUICTransportParametersInNewSessionTicket *tp = new QUICTransportParametersInNewSessionTicket();
+
+    // 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()));
+    tp->set(QUICTransportParameterId::STATELESS_RESET_TOKEN, this->_reset_token.buf(), QUICStatelessResetToken::LEN);
+
+    // 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});
+
+    return std::unique_ptr<QUICTransportParameters>(tp);
+  }
 }
 
 std::shared_ptr<const QUICTransportParameters>
@@ -360,45 +395,45 @@ QUICHandshake::state_closed(int event, void *data)
 {
   return EVENT_DONE;
 }
-
 void
-QUICHandshake::_load_local_transport_parameters(QUICVersion version)
+QUICHandshake::_load_local_server_transport_parameters(QUICVersion negotiated_version)
 {
   QUICConfig::scoped_config params;
+  QUICTransportParametersInEncryptedExtensions *tp = new QUICTransportParametersInEncryptedExtensions(negotiated_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()));
+  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);
+}
 
-  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});
+void
+QUICHandshake::_load_local_client_transport_parameters(QUICVersion initial_version)
+{
+  QUICConfig::scoped_config params;
 
-    this->_local_transport_parameters = std::unique_ptr<QUICTransportParameters>(tp);
-  } else {
-    QUICTransportParametersInClientHello *tp = new QUICTransportParametersInClientHello(version);
+  QUICTransportParametersInClientHello *tp = new QUICTransportParametersInClientHello(initial_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()));
+  // 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());
+  // 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);
-  }
+  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 75f2d5d..9c2e450 100644
--- a/iocore/net/quic/QUICHandshake.h
+++ b/iocore/net/quic/QUICHandshake.h
@@ -75,7 +75,7 @@ public:
   QUICVersion negotiated_version();
   const char *negotiated_cipher_suite();
   void negotiated_application_name(const uint8_t **name, unsigned int *len);
-  std::shared_ptr<const QUICTransportParameters> local_transport_parameters();
+  std::shared_ptr<const QUICTransportParameters> local_transport_parameters(bool with_version = true);
   std::shared_ptr<const QUICTransportParameters> remote_transport_parameters();
 
   bool is_version_negotiated();
@@ -83,6 +83,7 @@ public:
 
   void set_transport_parameters(std::shared_ptr<QUICTransportParametersInClientHello> tp);
   void set_transport_parameters(std::shared_ptr<QUICTransportParametersInEncryptedExtensions> tp);
+  void set_transport_parameters(std::shared_ptr<QUICTransportParametersInNewSessionTicket> tp);
 
 private:
   SSL *_ssl                                                             = nullptr;
@@ -92,7 +93,8 @@ private:
 
   QUICVersionNegotiator *_version_negotiator = nullptr;
 
-  void _load_local_transport_parameters(QUICVersion negotiated_version);
+  void _load_local_server_transport_parameters(QUICVersion negotiated_version);
+  void _load_local_client_transport_parameters(QUICVersion initial_version);
 
   QUICErrorUPtr _do_handshake(bool initial = false);
 
diff --git a/iocore/net/quic/QUICTransportParameters.cc b/iocore/net/quic/QUICTransportParameters.cc
index a75895d..4a511b2 100644
--- a/iocore/net/quic/QUICTransportParameters.cc
+++ b/iocore/net/quic/QUICTransportParameters.cc
@@ -475,6 +475,69 @@ QUICTransportParametersInEncryptedExtensions::_validate_parameters() const
 }
 
 //
+// QUICTransportParametersInNewSessionTicket
+//
+
+QUICTransportParametersInNewSessionTicket::QUICTransportParametersInNewSessionTicket(const uint8_t *buf, size_t len)
+{
+  this->_load(buf, len);
+  this->_print();
+}
+
+void
+QUICTransportParametersInNewSessionTicket::_store(uint8_t *buf, uint16_t *len) const
+{
+  // no additional fields defined
+  len = 0;
+}
+
+std::ptrdiff_t
+QUICTransportParametersInNewSessionTicket::_parameters_offset(const uint8_t *buf) const
+{
+  return 0;
+}
+
+int
+QUICTransportParametersInNewSessionTicket::_validate_parameters() const
+{
+  if (QUICTransportParameters::_validate_parameters() < 0) {
+    return 0;
+  }
+
+  decltype(this->_parameters)::const_iterator ite;
+
+  // MUSTs
+  if ((ite = this->_parameters.find(QUICTransportParameterId::STATELESS_RESET_TOKEN)) != this->_parameters.end()) {
+    if (ite->second->len() != 2) {
+      return -1;
+    }
+  } else {
+    return -2;
+  }
+
+  // MAYs
+  if ((ite = this->_parameters.find(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_BIDI)) != this->_parameters.end()) {
+    if (ite->second->len() != 4) {
+      return -3;
+    }
+    if ((QUICTypeUtil::read_nbytes_as_uint(ite->second->data(), ite->second->len()) & 0x03) != 1) {
+      return -4;
+    }
+  }
+
+  if ((ite = this->_parameters.find(QUICTransportParameterId::INITIAL_MAX_STREAM_ID_UNI)) != this->_parameters.end()) {
+    if (ite->second->len() != 4) {
+      return -5;
+    }
+    if ((QUICTypeUtil::read_nbytes_as_uint(ite->second->data(), ite->second->len()) & 0x03) != 3) {
+      return -6;
+    }
+  }
+
+  return 0;
+}
+
+//
 // QUICTransportParametersHandler
 //
 
@@ -484,7 +547,8 @@ QUICTransportParametersHandler::add(SSL *s, unsigned int ext_type, unsigned int
 {
   QUICHandshake *hs = static_cast<QUICHandshake *>(SSL_get_ex_data(s, QUIC::ssl_quic_hs_index));
   *out              = reinterpret_cast<const unsigned char *>(ats_malloc(TRANSPORT_PARAMETERS_MAXIMUM_SIZE));
-  hs->local_transport_parameters()->store(const_cast<uint8_t *>(*out), reinterpret_cast<uint16_t *>(outlen));
+  bool with_version = (context == SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS);
+  hs->local_transport_parameters(with_version)->store(const_cast<uint8_t *>(*out), reinterpret_cast<uint16_t *>(outlen));
 
   return 1;
 }
@@ -502,14 +566,15 @@ QUICTransportParametersHandler::parse(SSL *s, unsigned int ext_type, unsigned in
   QUICHandshake *hs = static_cast<QUICHandshake *>(SSL_get_ex_data(s, QUIC::ssl_quic_hs_index));
 
   switch (context) {
-  case SSL_EXT_CLIENT_HELLO: {
+  case SSL_EXT_CLIENT_HELLO:
     hs->set_transport_parameters(std::make_shared<QUICTransportParametersInClientHello>(in, inlen));
     break;
-  }
-  case SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS: {
+  case SSL_EXT_TLS1_3_ENCRYPTED_EXTENSIONS:
     hs->set_transport_parameters(std::make_shared<QUICTransportParametersInEncryptedExtensions>(in, inlen));
     break;
-  }
+  case SSL_EXT_TLS1_3_NEW_SESSION_TICKET:
+    hs->set_transport_parameters(std::make_shared<QUICTransportParametersInNewSessionTicket>(in, inlen));
+    break;
   default:
     // Do nothing
     break;
diff --git a/iocore/net/quic/QUICTransportParameters.h b/iocore/net/quic/QUICTransportParameters.h
index 46aa1b4..11bc8b0 100644
--- a/iocore/net/quic/QUICTransportParameters.h
+++ b/iocore/net/quic/QUICTransportParameters.h
@@ -147,6 +147,18 @@ protected:
   QUICVersion _versions[256]      = {};
 };
 
+class QUICTransportParametersInNewSessionTicket : public QUICTransportParameters
+{
+public:
+  QUICTransportParametersInNewSessionTicket() : QUICTransportParameters(){};
+  QUICTransportParametersInNewSessionTicket(const uint8_t *buf, size_t len);
+
+protected:
+  std::ptrdiff_t _parameters_offset(const uint8_t *buf) const override;
+  int _validate_parameters() const override;
+  void _store(uint8_t *buf, uint16_t *len) const override;
+};
+
 class QUICTransportParametersHandler
 {
 public:

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