trafficserver-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From shinr...@apache.org
Subject [trafficserver] 03/04: Update for QUIC integration.
Date Mon, 12 Aug 2019 17:16:16 GMT
This is an automated email from the ASF dual-hosted git repository.

shinrich pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit d7e90a462a28d40f6d9a457aa0c09e323c480684
Author: Susan Hinrichs <shinrich@oath.com>
AuthorDate: Tue Aug 6 20:38:08 2019 +0000

    Update for QUIC integration.
---
 iocore/net/P_QUICNetVConnection.h       | 14 ++++++++++++++
 iocore/net/P_QUICNextProtocolAccept.h   |  6 ++----
 iocore/net/QUICMultiCertConfigLoader.cc | 10 ++--------
 iocore/net/QUICNetVConnection.cc        | 32 ++++++++++++++++++++++++++++++++
 iocore/net/QUICNextProtocolAccept.cc    | 13 ++++---------
 iocore/net/quic/Mock.h                  | 28 ++++++++++++++++++++++++++++
 iocore/net/quic/QUICConnection.h        | 14 +++++++++-----
 proxy/http/HttpProxyServerMain.cc       | 10 ++++------
 src/traffic_server/InkAPI.cc            |  1 -
 src/traffic_server/traffic_server.cc    |  3 ---
 10 files changed, 95 insertions(+), 36 deletions(-)

diff --git a/iocore/net/P_QUICNetVConnection.h b/iocore/net/P_QUICNetVConnection.h
index 8ca2588..d9a0adb 100644
--- a/iocore/net/P_QUICNetVConnection.h
+++ b/iocore/net/P_QUICNetVConnection.h
@@ -168,6 +168,15 @@ public:
   int populate_protocol(std::string_view *results, int n) const override;
   const char *protocol_contains(std::string_view tag) const override;
 
+  int select_next_protocol(SSL *ssl, const unsigned char **out, unsigned char *outlen, const
unsigned char *in,
+                           unsigned inlen) const override;
+
+  void
+  setEnabledProtocols(const SessionProtocolSet &protos)
+  {
+    this->_protoenabled = protos;
+  }
+
   // QUICNetVConnection
   void registerNextProtocolSet(SSLNextProtocolSet *s);
 
@@ -187,6 +196,7 @@ public:
   uint32_t pmtu() const override;
   NetVConnectionContext_t direction() const override;
   SSLNextProtocolSet *next_protocol_set() const override;
+  const SessionProtocolSet &get_enabled_protocols() const override;
   std::string_view negotiated_application_name() const override;
   bool is_closed() const override;
 
@@ -236,6 +246,10 @@ private:
   uint32_t _pmtu = 1280;
 
   SSLNextProtocolSet *_next_protocol_set = nullptr;
+  SessionProtocolSet _protoenabled;
+  // Local copies of the npn strings
+  unsigned char *_npn = nullptr;
+  size_t _npnsz       = 0;
 
   // TODO: use custom allocator and make them std::unique_ptr or std::shared_ptr
   // or make them just member variables.
diff --git a/iocore/net/P_QUICNextProtocolAccept.h b/iocore/net/P_QUICNextProtocolAccept.h
index 5b03652..95752dd 100644
--- a/iocore/net/P_QUICNextProtocolAccept.h
+++ b/iocore/net/P_QUICNextProtocolAccept.h
@@ -40,13 +40,10 @@ public:
   // lifetime is at least as long as that of the acceptor.
   bool registerEndpoint(const char *protocol, Continuation *handler);
 
-  // Unregister the handler. Returns false if this protocol is not registered
-  // or if it is not registered for the specified handler.
-  bool unregisterEndpoint(const char *protocol, Continuation *handler);
+  void enableProtocols(const SessionProtocolSet &protos);
 
   SLINK(QUICNextProtocolAccept, link);
   SSLNextProtocolSet *getProtoSet();
-  SSLNextProtocolSet *cloneProtoSet();
 
   // noncopyable
   QUICNextProtocolAccept(const QUICNextProtocolAccept &) = delete;            // disabled
@@ -56,6 +53,7 @@ private:
   int mainEvent(int event, void *netvc);
 
   SSLNextProtocolSet protoset;
+  SessionProtocolSet protoenabled;
 
   friend struct QUICNextProtocolTrampoline;
 };
diff --git a/iocore/net/QUICMultiCertConfigLoader.cc b/iocore/net/QUICMultiCertConfigLoader.cc
index a948a6f..7a3fe2c 100644
--- a/iocore/net/QUICMultiCertConfigLoader.cc
+++ b/iocore/net/QUICMultiCertConfigLoader.cc
@@ -274,17 +274,11 @@ int
 QUICMultiCertConfigLoader::ssl_select_next_protocol(SSL *ssl, const unsigned char **out,
unsigned char *outlen,
                                                     const unsigned char *in, unsigned inlen,
void *)
 {
-  const unsigned char *npn;
-  unsigned npnsz     = 0;
   QUICConnection *qc = static_cast<QUICConnection *>(SSL_get_ex_data(ssl, QUIC::ssl_quic_qc_index));
 
-  qc->next_protocol_set()->advertiseProtocols(&npn, &npnsz);
-  if (SSL_select_next_proto((unsigned char **)out, outlen, npn, npnsz, in, inlen) == OPENSSL_NPN_NEGOTIATED)
{
-    return SSL_TLSEXT_ERR_OK;
+  if (qc) {
+    return qc->select_next_protocol(ssl, out, outlen, in, inlen);
   }
-
-  *out    = nullptr;
-  *outlen = 0;
   return SSL_TLSEXT_ERR_NOACK;
 }
 
diff --git a/iocore/net/QUICNetVConnection.cc b/iocore/net/QUICNetVConnection.cc
index 5bbd25b..36f55cc 100644
--- a/iocore/net/QUICNetVConnection.cc
+++ b/iocore/net/QUICNetVConnection.cc
@@ -503,6 +503,11 @@ QUICNetVConnection::free(EThread *t)
 
     super::clear();
   */
+  if (this->_npn) {
+    ats_free(this->_npn);
+    this->_npn   = nullptr;
+    this->_npnsz = 0;
+  }
   this->_packet_handler->close_connection(this);
 }
 
@@ -1018,6 +1023,27 @@ void
 QUICNetVConnection::registerNextProtocolSet(SSLNextProtocolSet *s)
 {
   this->_next_protocol_set = s;
+  this->_next_protocol_set->create_npn_advertisement(this->_protoenabled, &this->_npn,
&this->_npnsz);
+}
+
+// ALPN TLS extension callback. Given the client's set of offered
+// protocols, we have to select a protocol to use for this session.
+int
+QUICNetVConnection::select_next_protocol(SSL *ssl, const unsigned char **out, unsigned char
*outlen, const unsigned char *in,
+                                         unsigned inlen) const
+{
+  if (this->_npn && this->_npnsz) {
+    // SSL_select_next_proto chooses the first server-offered protocol that appears in the
clients protocol set, ie. the
+    // server selects the protocol. This is a n^2 search, so it's preferable to keep the
protocol set short.
+    if (SSL_select_next_proto((unsigned char **)out, outlen, this->_npn, this->_npnsz,
in, inlen) == OPENSSL_NPN_NEGOTIATED) {
+      Debug("ssl", "selected ALPN protocol %.*s", (int)(*outlen), *out);
+      return SSL_TLSEXT_ERR_OK;
+    }
+  }
+
+  *out    = nullptr;
+  *outlen = 0;
+  return SSL_TLSEXT_ERR_NOACK;
 }
 
 bool
@@ -1032,6 +1058,12 @@ QUICNetVConnection::next_protocol_set() const
   return this->_next_protocol_set;
 }
 
+const SessionProtocolSet &
+QUICNetVConnection::get_enabled_protocols() const
+{
+  return this->_protoenabled;
+}
+
 QUICPacketNumber
 QUICNetVConnection::_largest_acked_packet_number(QUICEncryptionLevel level) const
 {
diff --git a/iocore/net/QUICNextProtocolAccept.cc b/iocore/net/QUICNextProtocolAccept.cc
index 1f721fa..4662a09 100644
--- a/iocore/net/QUICNextProtocolAccept.cc
+++ b/iocore/net/QUICNextProtocolAccept.cc
@@ -54,6 +54,7 @@ QUICNextProtocolAccept::mainEvent(int event, void *edata)
   switch (event) {
   case NET_EVENT_ACCEPT:
     ink_release_assert(netvc != nullptr);
+    netvc->setEnabledProtocols(this->protoenabled);
     netvc->registerNextProtocolSet(&this->protoset);
     return EVENT_CONT;
   default:
@@ -75,10 +76,10 @@ QUICNextProtocolAccept::registerEndpoint(const char *protocol, Continuation
*han
   return this->protoset.registerEndpoint(protocol, handler);
 }
 
-bool
-QUICNextProtocolAccept::unregisterEndpoint(const char *protocol, Continuation *handler)
+void
+QUICNextProtocolAccept::enableProtocols(const SessionProtocolSet &protos)
 {
-  return this->protoset.unregisterEndpoint(protocol, handler);
+  this->protoenabled = protos;
 }
 
 QUICNextProtocolAccept::QUICNextProtocolAccept() : SessionAccept(nullptr)
@@ -92,10 +93,4 @@ QUICNextProtocolAccept::getProtoSet()
   return &this->protoset;
 }
 
-SSLNextProtocolSet *
-QUICNextProtocolAccept::cloneProtoSet()
-{
-  return this->protoset.clone();
-}
-
 QUICNextProtocolAccept::~QUICNextProtocolAccept() {}
diff --git a/iocore/net/quic/Mock.h b/iocore/net/quic/Mock.h
index 45f5e8f..cb107c9 100644
--- a/iocore/net/quic/Mock.h
+++ b/iocore/net/quic/Mock.h
@@ -220,6 +220,12 @@ public:
     return nullptr;
   }
 
+  const SessionProtocolSet &
+  get_enabled_protocols() const override
+  {
+    return _protocolsenabled;
+  }
+
   void
   close(QUICConnectionErrorUPtr error) override
   {
@@ -259,6 +265,13 @@ public:
     return negotiated_application_name_sv;
   }
 
+  int
+  select_next_protocol(SSL *ssl, const unsigned char **out, unsigned char *outlen, const
unsigned char *in,
+                       unsigned inlen) const override
+  {
+    return SSL_TLSEXT_ERR_OK;
+  }
+
   int _transmit_count   = 0;
   int _retransmit_count = 0;
   Ptr<ProxyMutex> _mutex;
@@ -268,6 +281,7 @@ public:
 
   QUICTransportParametersInEncryptedExtensions dummy_transport_parameters();
   NetVConnectionContext_t _direction;
+  SessionProtocolSet _protocolsenabled;
 };
 
 class MockQUICConnectionInfoProvider : public QUICConnectionInfoProvider
@@ -326,6 +340,18 @@ class MockQUICConnectionInfoProvider : public QUICConnectionInfoProvider
   {
     return nullptr;
   }
+  const SessionProtocolSet &
+  get_enabled_protocols() const override
+  {
+    return _protocolsenabled;
+  }
+
+  int
+  select_next_protocol(SSL *ssl, const unsigned char **out, unsigned char *outlen, const
unsigned char *in,
+                       unsigned inlen) const override
+  {
+    return SSL_TLSEXT_ERR_OK;
+  }
 
   bool
   is_closed() const override
@@ -338,6 +364,8 @@ class MockQUICConnectionInfoProvider : public QUICConnectionInfoProvider
   {
     return negotiated_application_name_sv;
   }
+
+  SessionProtocolSet _protocolsenabled;
 };
 
 class MockQUICCongestionController : public QUICCongestionController
diff --git a/iocore/net/quic/QUICConnection.h b/iocore/net/quic/QUICConnection.h
index 36cc5fb..c57b19f 100644
--- a/iocore/net/quic/QUICConnection.h
+++ b/iocore/net/quic/QUICConnection.h
@@ -31,6 +31,7 @@ class QUICApplication;
 class QUICStreamManager;
 class UDPPacket;
 class SSLNextProtocolSet;
+class SessionProtocolSet;
 
 class QUICConnectionInfoProvider
 {
@@ -42,11 +43,14 @@ public:
   virtual std::string_view cids() const                   = 0;
   virtual const QUICFiveTuple five_tuple() const          = 0;
 
-  virtual uint32_t pmtu() const                                = 0;
-  virtual NetVConnectionContext_t direction() const            = 0;
-  virtual SSLNextProtocolSet *next_protocol_set() const        = 0;
-  virtual bool is_closed() const                               = 0;
-  virtual std::string_view negotiated_application_name() const = 0;
+  virtual uint32_t pmtu() const                                   = 0;
+  virtual NetVConnectionContext_t direction() const               = 0;
+  virtual SSLNextProtocolSet *next_protocol_set() const           = 0;
+  virtual const SessionProtocolSet &get_enabled_protocols() const = 0;
+  virtual int select_next_protocol(SSL *ssl, const unsigned char **out, unsigned char *outlen,
const unsigned char *in,
+                                   unsigned inlen) const          = 0;
+  virtual bool is_closed() const                                  = 0;
+  virtual std::string_view negotiated_application_name() const    = 0;
 };
 
 class QUICConnection : public QUICFrameHandler, public QUICConnectionInfoProvider
diff --git a/proxy/http/HttpProxyServerMain.cc b/proxy/http/HttpProxyServerMain.cc
index 78f05a3..48ea161 100644
--- a/proxy/http/HttpProxyServerMain.cc
+++ b/proxy/http/HttpProxyServerMain.cc
@@ -235,15 +235,13 @@ MakeHttpProxyAcceptor(HttpProxyAcceptor &acceptor, HttpProxyPort
&port, unsigned
   } else if (port.isQUIC()) {
     QUICNextProtocolAccept *quic = new QUICNextProtocolAccept();
 
+    quic->enableProtocols(port.m_session_protocol_preference);
+
     // HTTP/3
-    if (port.m_session_protocol_preference.contains(TS_ALPN_PROTOCOL_INDEX_HTTP_3)) {
-      quic->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_3, new Http3SessionAccept(accept_opt));
-    }
+    quic->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_3, new Http3SessionAccept(accept_opt));
 
     // HTTP/0.9 over QUIC (for interop only, will be removed)
-    if (port.m_session_protocol_preference.contains(TS_ALPN_PROTOCOL_INDEX_HTTP_QUIC)) {
-      quic->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_QUIC, new Http3SessionAccept(accept_opt));
-    }
+    quic->registerEndpoint(TS_ALPN_PROTOCOL_HTTP_QUIC, new Http3SessionAccept(accept_opt));
 
     quic->proxyPort  = &port;
     acceptor._accept = quic;
diff --git a/src/traffic_server/InkAPI.cc b/src/traffic_server/InkAPI.cc
index 7b13540..d4c56b3 100644
--- a/src/traffic_server/InkAPI.cc
+++ b/src/traffic_server/InkAPI.cc
@@ -7160,7 +7160,6 @@ TSNetAccept(TSCont contp, int port, int domain, int accept_threads)
 
 /* From proxy/http/HttpProxyServerMain.c: */
 extern bool ssl_register_protocol(const char *, Continuation *);
-// extern bool ssl_unregister_protocol(const char *, Continuation *);
 
 TSReturnCode
 TSNetAcceptNamedProtocol(TSCont contp, const char *protocol)
diff --git a/src/traffic_server/traffic_server.cc b/src/traffic_server/traffic_server.cc
index 61fe2cc..2c82fd5 100644
--- a/src/traffic_server/traffic_server.cc
+++ b/src/traffic_server/traffic_server.cc
@@ -1958,9 +1958,6 @@ main(int /* argc ATS_UNUSED */, const char **argv)
         start_HttpProxyServer(); // PORTS_READY_HOOK called from in here
       }
     }
-#ifdef OLD
-    SNIConfig::cloneProtoSet();
-#endif
     // Plugins can register their own configuration names so now after they've done that
     // check for unexpected names. This is very late because remap plugins must be allowed
to
     // fire up as well.


Mime
View raw message