You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by bc...@apache.org on 2017/06/12 17:22:23 UTC

[trafficserver] branch YTSATS-1127 created (now 91b4888)

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

bcall pushed a change to branch YTSATS-1127
in repository https://gitbox.apache.org/repos/asf/trafficserver.git.


      at 91b4888  YTSATS-1127: update tls_proto to allow for override of port protoset

This branch includes the following new commits:

     new 91b4888  YTSATS-1127: update tls_proto to allow for override of port protoset

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


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

[trafficserver] 01/01: YTSATS-1127: update tls_proto to allow for override of port protoset

Posted by bc...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

bcall pushed a commit to branch YTSATS-1127
in repository https://gitbox.apache.org/repos/asf/trafficserver.git

commit 91b4888661ff8644359beed8a00e517423944b5b
Author: Persia Aziz <pe...@yahoo-inc.com>
AuthorDate: Wed Jan 25 16:54:52 2017 -0600

    YTSATS-1127: update tls_proto to allow for override of port protoset
    
    (cherry picked from commit 6c17449436426e1c1732189d2b09ee6f50283168)
---
 .../api/functions/TSAcceptor.en.rst                |  50 ++++++++
 .../api/functions/TSProtoSet.en.rst                |  46 ++++++++
 doc/developer-guide/api/functions/TSTypes.en.rst   |  23 ++++
 example/Makefile.am                                |   4 +-
 example/replace-protoset/replace-protoset.cc       | 126 +++++++++++++++++++++
 iocore/net/I_SessionAccept.h                       |   4 +-
 iocore/net/P_NetAccept.h                           |  10 +-
 iocore/net/P_SSLNetVConnection.h                   |   7 +-
 iocore/net/P_SSLNextProtocolAccept.h               |   2 +
 iocore/net/P_SSLNextProtocolSet.h                  |   2 +
 iocore/net/P_UnixNetVConnection.h                  |   2 +
 iocore/net/SSLNetVConnection.cc                    |   3 -
 iocore/net/SSLNextProtocolAccept.cc                |  13 ++-
 iocore/net/SSLNextProtocolSet.cc                   |  17 ++-
 iocore/net/UnixNetAccept.cc                        |  11 +-
 iocore/net/UnixNetProcessor.cc                     |  12 +-
 iocore/net/UnixNetVConnection.cc                   |   1 +
 lib/ts/apidefs.h.in                                |   2 +
 proxy/InkAPI.cc                                    |  60 ++++++++++
 proxy/api/ts/ts.h                                  |   8 +-
 proxy/http/HttpProxyServerMain.cc                  |   3 +-
 21 files changed, 385 insertions(+), 21 deletions(-)

diff --git a/doc/developer-guide/api/functions/TSAcceptor.en.rst b/doc/developer-guide/api/functions/TSAcceptor.en.rst
new file mode 100644
index 0000000..35bc21e
--- /dev/null
+++ b/doc/developer-guide/api/functions/TSAcceptor.en.rst
@@ -0,0 +1,50 @@
+.. Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed
+   with this work for additional information regarding copyright
+   ownership.  The ASF licenses this file to you under the Apache
+   License, Version 2.0 (the "License"); you may not use this file
+   except in compliance with the License.  You may obtain a copy of
+   the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied.  See the License for the specific language governing
+   permissions and limitations under the License.
+
+.. include:: ../../../common.defs
+
+.. default-domain:: c
+
+TSAcceptor
+**********
+
+Traffic Server API's related to Accept objects
+
+Synopsis
+========
+
+`#include <ts/ts.h>`
+
+.. function:: TSAcceptor TSAcceptorGet(TSVConn sslp)
+.. function:: TSAcceptor TSAcceptorGetbyID(int id)
+.. function:: int TSAcceptorIDGet(TSAcceptor acceptor)
+.. function:: int TSAcceptorCount()
+
+
+Description
+===========
+
+Traffic Server allows plugins to get information from an accept object that created a certain TSVConn object using the above mentioned APIs.
+An acceptor thread listens for incoming connections and creates the virtual connection (:type:`TSVConn`) for each accepted connection.
+
+:func:`TSAcceptorGet` returns :type:`TSAcceptor` object that created :arg:`sslp`.
+
+:func:`TSAcceptorGetbyID` returns the :type:`TSAcceptor` object identified by :arg:`id`. :type:`TSAcceptor` represents the acceptor object created by the core
+traffic server.
+
+:func:`TSAcceptorIDGet` returns the Integer number that identifies :arg:`acceptor`. All the cloned :type:`TSAcceptor` objects will have the same identifying number.
+
+:func:`TSAcceptorCount` returns the number of :type:`TSAcceptor` objects created by the server.
diff --git a/doc/developer-guide/api/functions/TSProtoSet.en.rst b/doc/developer-guide/api/functions/TSProtoSet.en.rst
new file mode 100644
index 0000000..8b57209
--- /dev/null
+++ b/doc/developer-guide/api/functions/TSProtoSet.en.rst
@@ -0,0 +1,46 @@
+.. Licensed to the Apache Software Foundation (ASF) under one or more
+   contributor license agreements.  See the NOTICE file distributed
+   with this work for additional information regarding copyright
+   ownership.  The ASF licenses this file to you under the Apache
+   License, Version 2.0 (the "License"); you may not use this file
+   except in compliance with the License.  You may obtain a copy of
+   the License at
+
+   http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied.  See the License for the specific language governing
+   permissions and limitations under the License.
+
+.. include:: ../../../common.defs
+
+.. default-domain:: c
+
+TSProtoSet
+******************
+
+Synopsis
+========
+
+`#include <ts/ts.h>`
+
+.. function:: TSNextProtocolSet TSGetcloneProtoSet(TSAcceptor tna)
+.. function:: TSNextProtocolSet TSUnregisterProtocol(TSNextProtocolSet protoset, const char* protocol)
+.. function:: void TSRegisterProtocolSet(TSVConn sslp, TSNextProtocolSet ps)
+
+Description
+===========
+
+:func:`TSGetcloneProtoSet` makes a copy of the ProtocolSet to be advertised by the ssl connection associated with :arg:`tna`. This function
+returns :type:`TSNextProtocolSet` object which points to a clone of the protocolset owned by :arg:`tna`. This type represents the protocolset
+containing the protocols which are advertised by an ssl connection during ssl handshake. Each :type:`TSAcceptor` object is associated with a protocolset.
+
+
+:func:`TSUnregisterProtocol` unregisters :arg:`protocol` from :arg:`protoset` and returns the protocol set.
+The returned protocol set needs to be registered with the :type:`TSVConn` using :func:`TSRegisterProtocolSet` that will advertise the protocols.
+
+
+:func:`TSRegisterProtocolSet` registers :arg:`ps` with :arg:`sslp`. This function clears the protocolset string created by the already registered
+protocolset before registering the new protocolset. On Success, the ssl object associated with :arg:`sslp` will then advertise the protocols contained in :arg:`ps`.
diff --git a/doc/developer-guide/api/functions/TSTypes.en.rst b/doc/developer-guide/api/functions/TSTypes.en.rst
index c837de6..ba92545 100644
--- a/doc/developer-guide/api/functions/TSTypes.en.rst
+++ b/doc/developer-guide/api/functions/TSTypes.en.rst
@@ -154,4 +154,27 @@ more widely. Those are described on this page.
 
 .. type:: TSVConn
 
+    A virtual connection. This is the basic mechanism for abstracting I/O operations in |TS|.
+
+.. type:: TSNetVConnection
+
+    A subtype of :type:`TSVConn` that provides additional IP network information and operations.
+
 .. type:: TSVIO
+
+.. type:: ModuleVersion
+
+    A module version.
+
+.. cpp:type:: ModuleVersion
+
+    A module version.
+
+.. cpp:class:: template<typename T> DLL
+
+    An anchor for a double linked instrusive list of instance of :arg:`T`.
+
+.. type:: TSAcceptor
+
+.. type:: TSNextProtocolSet
+
diff --git a/example/Makefile.am b/example/Makefile.am
index ec414b0..acbc156 100644
--- a/example/Makefile.am
+++ b/example/Makefile.am
@@ -54,7 +54,8 @@ example_Plugins = \
 	statistic.la \
 	thread-1.la \
 	txn-data-sink.la \
-	version.la
+	version.la \
+	replace-protoset.la
 
 example_Plugins += \
 	cppapi/AsyncHttpFetch.la \
@@ -115,6 +116,7 @@ server_transform_la_SOURCES = server-transform/server-transform.c
 ssl_preaccept_la_SOURCES = ssl-preaccept/ssl-preaccept.cc
 ssl_sni_la_SOURCES = ssl-sni/ssl-sni.cc
 ssl_sni_whitelist_la_SOURCES = ssl-sni-whitelist/ssl-sni-whitelist.cc
+replace_protoset_la_SOURCES = replace-protoset/replace-protoset.cc
 statistic_la_SOURCES = statistic/statistic.cc
 thread_1_la_SOURCES = thread-1/thread-1.c
 txn_data_sink_la_SOURCES = txn-data-sink/txn-data-sink.c
diff --git a/example/replace-protoset/replace-protoset.cc b/example/replace-protoset/replace-protoset.cc
new file mode 100644
index 0000000..bfd4dbc
--- /dev/null
+++ b/example/replace-protoset/replace-protoset.cc
@@ -0,0 +1,126 @@
+/** @file
+
+  A brief file description
+
+  @section license License
+
+  Licensed to the Apache Software Foundation (ASF) under one
+  or more contributor license agreements.  See the NOTICE file
+  distributed with this work for additional information
+  regarding copyright ownership.  The ASF licenses this file
+  to you under the Apache License, Version 2.0 (the
+  "License"); you may not use this file except in compliance
+  with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+  Unless required by applicable law or agreed to in writing, software
+  distributed under the License is distributed on an "AS IS" BASIS,
+  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  See the License for the specific language governing permissions and
+  limitations under the License.
+ */
+
+/*
+ *   replace-protoset.c:
+ *	an example plugin...
+ * Clones protoset attached with all the accept objects
+ * Unregisters H2 from the clone
+ * Replaces the protoset attached with all the incoming VCs with a clone
+ */
+#include <atscppapi/GlobalPlugin.h>
+#include <atscppapi/PluginInit.h>
+#include <ts/ts.h>
+#include <ts/TsBuffer.h>
+
+#include <unordered_map>
+#include <unordered_set>
+#include <iostream>
+#include <algorithm>
+#include <inttypes.h>
+#include <openssl/ssl.h>
+#include <fcntl.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#define PLNAME "TLS Protocol Adjuster"
+#define PLTAG "replace_protoset"
+
+typedef std::unordered_map<int, TSNextProtocolSet> protoTable; // stores protocolset keyed by NetAccept ID
+protoTable ProtoSetTable;
+typedef std::unordered_set<std::string> Table;
+// Map of domains to tweak.
+Table _table;
+
+int
+CB_SNI(TSCont contp, TSEvent, void *cb_data)
+{
+  TSVConn vc               = (static_cast<TSVConn>(cb_data));
+  TSSslConnection ssl_conn = TSVConnSSLConnectionGet(vc);
+  auto *ssl                = reinterpret_cast<SSL *>(ssl_conn);
+  char const *sni          = SSL_get_servername(ssl, TLSEXT_NAMETYPE_host_name);
+  if (sni) {
+    if (_table.find(sni) != _table.end()) {
+      TSAcceptor na        = TSAcceptorGet(vc);
+      int nid              = TSAcceptorIDGet(na);
+      TSNextProtocolSet ps = ProtoSetTable[nid];
+      TSRegisterProtocolSet(vc, ps);
+    }
+  }
+
+  TSVConnReenable(vc);
+  return TS_SUCCESS;
+}
+
+int
+CB_NetAcceptReady(TSCont contp, TSEvent event, void *cb_data)
+{
+  switch (event) {
+  case TS_EVENT_LIFECYCLE_PORTS_READY:
+    for (int i = 0, totalNA = TSAcceptorCount(); i < totalNA; ++i) {
+      TSAcceptor netaccept = TSAcceptorGetbyID(i);
+      // get a clone of the protoset associated with the netaccept
+      TSNextProtocolSet nps = TSGetcloneProtoSet(netaccept);
+      TSUnregisterProtocol(nps, TS_ALPN_PROTOCOL_HTTP_2_0);
+      ProtoSetTable[i] = nps;
+    }
+    break;
+  default:
+    break;
+  }
+  return 0;
+}
+
+void
+TSPluginInit(int argc, char const *argv[])
+{
+  int ret = -999, i;
+  TSPluginRegistrationInfo info;
+  info.plugin_name   = PLNAME;
+  info.vendor_name   = "Yahoo!";
+  info.support_email = "persia@yahoo-inc.com";
+  ret                = TSPluginRegister(&info);
+
+  if (ret != TS_SUCCESS) {
+    TSError("Plugin registration failed.");
+    return;
+  } else {
+    if (argc < 2) {
+      TSError("[%s] Usage %s servername1 servername2 .... ", PLTAG, PLTAG);
+      return;
+    }
+    TSDebug(PLTAG, "Plugin registration succeeded.");
+  }
+
+  for (i = 1; i < argc; i++) {
+    TSDebug(PLTAG, "%s added to the No-H2 list", argv[i]);
+    _table.emplace(std::string(argv[i], strlen(argv[i])));
+  }
+  // This should not modify any state so no lock is needed.
+  TSCont cb_sni    = TSContCreate(&CB_SNI, NULL);
+  TSCont cb_netacc = TSContCreate(&CB_NetAcceptReady, NULL);
+
+  TSHttpHookAdd(TS_SSL_SERVERNAME_HOOK, cb_sni);
+  TSLifecycleHookAdd(TS_LIFECYCLE_PORTS_READY_HOOK, cb_netacc);
+}
diff --git a/iocore/net/I_SessionAccept.h b/iocore/net/I_SessionAccept.h
index 4c677c3..3527f3d 100644
--- a/iocore/net/I_SessionAccept.h
+++ b/iocore/net/I_SessionAccept.h
@@ -28,7 +28,7 @@
 #include "I_VConnection.h"
 
 struct AclRecord;
-
+struct HttpProxyPort;
 /**
    The base class SessionAccept can not be used directly. The inherited class of
    SessionAccept (ex. HttpSessionAccept) is designed to:
@@ -71,7 +71,7 @@ public:
 
    */
   virtual bool accept(NetVConnection *, MIOBuffer *, IOBufferReader *) = 0;
-
+  HttpProxyPort *proxyPort;
   /* Returns nullptr if the specified client_ip is not allowed by ip_allow
    * Returns a pointer to the relevant IP policy for later processing otherwise */
   static const AclRecord *testIpAllowPolicy(sockaddr const *client_ip);
diff --git a/iocore/net/P_NetAccept.h b/iocore/net/P_NetAccept.h
index 3c14b87..73e070a 100644
--- a/iocore/net/P_NetAccept.h
+++ b/iocore/net/P_NetAccept.h
@@ -44,6 +44,7 @@
 
 struct NetAccept;
 class Event;
+class SSLNextProtocolAccept;
 //
 // Default accept function
 //   Accepts as many connections as possible, returning the number accepted
@@ -80,13 +81,16 @@ struct NetAcceptAction : public Action, public RefCountObj {
 // Handles accepting connections.
 //
 struct NetAccept : public Continuation {
-  ink_hrtime period;
+  ink_hrtime period = 0;
   Server server;
-  AcceptFunctionPtr accept_fn;
-  int ifd;
+  AcceptFunctionPtr accept_fn = nullptr;
+  int ifd                     = NO_FD;
+  int id                      = -1;
   Ptr<NetAcceptAction> action_;
+  SSLNextProtocolAccept *snpa = nullptr;
   EventIO ep;
 
+  HttpProxyPort *proxyPort = nullptr;
   NetProcessor::AcceptOptions opt;
 
   virtual NetProcessor *getNetProcessor() const;
diff --git a/iocore/net/P_SSLNetVConnection.h b/iocore/net/P_SSLNetVConnection.h
index ae09bd8..e636016 100644
--- a/iocore/net/P_SSLNetVConnection.h
+++ b/iocore/net/P_SSLNetVConnection.h
@@ -66,6 +66,7 @@
 #define SSL_DEF_TLS_RECORD_MSEC_THRESHOLD 1000
 
 class SSLNextProtocolSet;
+class SSLNextProtocolAccept;
 struct SSLCertLookup;
 
 typedef enum {
@@ -123,10 +124,10 @@ public:
 
   int sslServerHandShakeEvent(int &err);
   int sslClientHandShakeEvent(int &err);
-  virtual void net_read_io(NetHandler *nh, EThread *lthread);
-  virtual int64_t load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs);
+  void net_read_io(NetHandler *nh, EThread *lthread) override;
+  int64_t load_buffer_and_write(int64_t towrite, MIOBufferAccessor &buf, int64_t &total_written, int &needs) override;
   void registerNextProtocolSet(const SSLNextProtocolSet *);
-  virtual void do_io_close(int lerrno = -1);
+  void do_io_close(int lerrno = -1) override;
 
   ////////////////////////////////////////////////////////////
   // Instances of NetVConnection should be allocated        //
diff --git a/iocore/net/P_SSLNextProtocolAccept.h b/iocore/net/P_SSLNextProtocolAccept.h
index 94b2553..61364e3 100644
--- a/iocore/net/P_SSLNextProtocolAccept.h
+++ b/iocore/net/P_SSLNextProtocolAccept.h
@@ -49,6 +49,8 @@ public:
   bool unregisterEndpoint(const char *protocol, Continuation *handler);
 
   SLINK(SSLNextProtocolAccept, link);
+  SSLNextProtocolSet *getProtoSet();
+  SSLNextProtocolSet *cloneProtoSet();
 
 private:
   int mainEvent(int event, void *netvc);
diff --git a/iocore/net/P_SSLNextProtocolSet.h b/iocore/net/P_SSLNextProtocolSet.h
index 9a04370..8797961 100644
--- a/iocore/net/P_SSLNextProtocolSet.h
+++ b/iocore/net/P_SSLNextProtocolSet.h
@@ -37,7 +37,9 @@ public:
 
   bool registerEndpoint(const char *, Continuation *);
   bool unregisterEndpoint(const char *, Continuation *);
+  bool unregisterEndpoint(const char *proto);
   bool advertiseProtocols(const unsigned char **out, unsigned *len) const;
+  SSLNextProtocolSet *clone() const;
 
   Continuation *findEndpoint(const unsigned char *, unsigned) const;
 
diff --git a/iocore/net/P_UnixNetVConnection.h b/iocore/net/P_UnixNetVConnection.h
index e5b5d25..a471d76 100644
--- a/iocore/net/P_UnixNetVConnection.h
+++ b/iocore/net/P_UnixNetVConnection.h
@@ -36,6 +36,7 @@
 #include "I_NetVConnection.h"
 #include "P_UnixNetState.h"
 #include "P_Connection.h"
+#include "P_NetAccept.h"
 
 class UnixNetVConnection;
 class NetHandler;
@@ -292,6 +293,7 @@ public:
   ink_hrtime submit_time;
   OOB_callback *oob_ptr;
   bool from_accept_thread;
+  NetAccept *accept_object;
 
   // es - origin_trace associated connections
   bool origin_trace;
diff --git a/iocore/net/SSLNetVConnection.cc b/iocore/net/SSLNetVConnection.cc
index 197b5df..f2a0852 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -1340,7 +1340,6 @@ SSLNetVConnection::sslClientHandShakeEvent(int &err)
 void
 SSLNetVConnection::registerNextProtocolSet(const SSLNextProtocolSet *s)
 {
-  ink_release_assert(this->npnSet == nullptr);
   this->npnSet = s;
 }
 
@@ -1353,7 +1352,6 @@ SSLNetVConnection::advertise_next_protocol(SSL *ssl, const unsigned char **out,
   SSLNetVConnection *netvc = SSLNetVCAccess(ssl);
 
   ink_release_assert(netvc != nullptr);
-
   if (netvc->npnSet && netvc->npnSet->advertiseProtocols(out, outlen)) {
     // Successful return tells OpenSSL to advertise.
     return SSL_TLSEXT_ERR_OK;
@@ -1373,7 +1371,6 @@ SSLNetVConnection::select_next_protocol(SSL *ssl, const unsigned char **out, uns
   unsigned npnsz           = 0;
 
   ink_release_assert(netvc != nullptr);
-
   if (netvc->npnSet && netvc->npnSet->advertiseProtocols(&npn, &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.
diff --git a/iocore/net/SSLNextProtocolAccept.cc b/iocore/net/SSLNextProtocolAccept.cc
index 47068c3..5ec4d72 100644
--- a/iocore/net/SSLNextProtocolAccept.cc
+++ b/iocore/net/SSLNextProtocolAccept.cc
@@ -125,7 +125,6 @@ SSLNextProtocolAccept::mainEvent(int event, void *edata)
   SSLNetVConnection *netvc = ssl_netvc_cast(event, edata);
 
   Debug("ssl", "[SSLNextProtocolAccept:mainEvent] event %d netvc %p", event, netvc);
-
   switch (event) {
   case NET_EVENT_ACCEPT:
     ink_release_assert(netvc != nullptr);
@@ -170,6 +169,18 @@ SSLNextProtocolAccept::SSLNextProtocolAccept(Continuation *ep, bool transparent_
   SET_HANDLER(&SSLNextProtocolAccept::mainEvent);
 }
 
+SSLNextProtocolSet *
+SSLNextProtocolAccept::getProtoSet()
+{
+  return &this->protoset;
+}
+
+SSLNextProtocolSet *
+SSLNextProtocolAccept::cloneProtoSet()
+{
+  return this->protoset.clone();
+}
+
 SSLNextProtocolAccept::~SSLNextProtocolAccept()
 {
   free_MIOBuffer(this->buffer);
diff --git a/iocore/net/SSLNextProtocolSet.cc b/iocore/net/SSLNextProtocolSet.cc
index 6866349..38267a0 100644
--- a/iocore/net/SSLNextProtocolSet.cc
+++ b/iocore/net/SSLNextProtocolSet.cc
@@ -62,7 +62,7 @@ create_npn_advertisement(const SSLNextProtocolSet::NextProtocolEndpoint::list_ty
   }
 
   for (ep = endpoints.head; ep != nullptr; ep = endpoints.next(ep)) {
-    Debug("ssl", "advertising protocol %s", ep->protocol);
+    Debug("ssl", "advertising protocol %s, %p", ep->protocol, ep->endpoint);
     advertised = append_protocol(ep->protocol, advertised);
   }
 
@@ -75,6 +75,19 @@ fail:
   return false;
 }
 
+// copies th eprotocols but not the endpoints
+
+SSLNextProtocolSet *
+SSLNextProtocolSet::clone() const
+{
+  const SSLNextProtocolSet::NextProtocolEndpoint *ep;
+  SSLNextProtocolSet *newProtoSet = new SSLNextProtocolSet();
+  for (ep = this->endpoints.head; ep != nullptr; ep = this->endpoints.next(ep)) {
+    newProtoSet->registerEndpoint(ep->protocol, ep->endpoint);
+  }
+  return newProtoSet;
+}
+
 bool
 SSLNextProtocolSet::advertiseProtocols(const unsigned char **out, unsigned *len) const
 {
@@ -118,7 +131,7 @@ bool
 SSLNextProtocolSet::unregisterEndpoint(const char *proto, Continuation *ep)
 {
   for (NextProtocolEndpoint *e = this->endpoints.head; e; e = this->endpoints.next(e)) {
-    if (strcmp(proto, e->protocol) == 0 && e->endpoint == ep) {
+    if (strcmp(proto, e->protocol) == 0 && (ep == nullptr || e->endpoint == ep)) {
       // Protocol must be registered only once; no need to remove
       // any more entries.
       this->endpoints.remove(e);
diff --git a/iocore/net/UnixNetAccept.cc b/iocore/net/UnixNetAccept.cc
index d30ebe5..cd0161f 100644
--- a/iocore/net/UnixNetAccept.cc
+++ b/iocore/net/UnixNetAccept.cc
@@ -32,6 +32,7 @@ typedef int (NetAccept::*NetAcceptHandler)(int, void *);
 volatile int dummy_volatile = 0;
 int accept_till_done        = 1;
 
+std::vector<NetAccept *> naVec;
 static void
 safe_delay(int msec)
 {
@@ -102,6 +103,12 @@ Ldone:
   return count;
 }
 
+NetAccept *
+getNetAccept(int ID)
+{
+  return naVec.at(ID);
+}
+
 //
 // Initialize the NetAccept for execution in its own thread.
 // This should be done for low latency, high connection rate sockets.
@@ -272,6 +279,7 @@ NetAccept::do_blocking_accept(EThread *t)
     vc->options.packet_tos  = opt.packet_tos;
     vc->apply_options();
     vc->set_context(NET_VCONNECTION_IN);
+    vc->accept_object = this;
     SET_CONTINUATION_HANDLER(vc, (NetVConnHandler)&UnixNetVConnection::acceptEvent);
     // eventProcessor.schedule_imm(vc, getEtype());
     eventProcessor.schedule_imm_signal(vc, opt.etype);
@@ -481,8 +489,7 @@ NetAccept::acceptLoopEvent(int event, Event *e)
 //
 //
 
-NetAccept::NetAccept(const NetProcessor::AcceptOptions &_opt)
-  : Continuation(nullptr), period(0), accept_fn(nullptr), ifd(NO_FD), opt(_opt)
+NetAccept::NetAccept(const NetProcessor::AcceptOptions &_opt) : Continuation(nullptr), opt(_opt)
 {
 }
 
diff --git a/iocore/net/UnixNetProcessor.cc b/iocore/net/UnixNetProcessor.cc
index e94652f..2485a54 100644
--- a/iocore/net/UnixNetProcessor.cc
+++ b/iocore/net/UnixNetProcessor.cc
@@ -24,10 +24,13 @@
 #include "P_Net.h"
 #include "ts/InkErrno.h"
 #include "ts/ink_sock.h"
+#include "P_SSLNextProtocolAccept.h"
 
 // For Stat Pages
 #include "StatPages.h"
 
+volatile int net_accept_number = 0;
+extern std::vector<NetAccept *> naVec;
 NetProcessor::AcceptOptions const NetProcessor::DEFAULT_ACCEPT_OPTIONS;
 
 NetProcessor::AcceptOptions &
@@ -91,6 +94,8 @@ UnixNetProcessor::accept_internal(Continuation *cont, int fd, AcceptOptions cons
   char thr_name[MAX_THREAD_NAME_LENGTH];
 
   NetAccept *na = createNetAccept(opt);
+  na->id        = ink_atomic_increment(&net_accept_number, 1);
+  Debug("iocore_net_accept", "creating new net accept number %d", na->id);
 
   // Fill in accept thread from configuration if necessary.
   if (opt.accept_threads < 0) {
@@ -125,6 +130,10 @@ UnixNetProcessor::accept_internal(Continuation *cont, int fd, AcceptOptions cons
   if (should_filter_int > 0 && opt.etype == ET_NET)
     na->server.http_accept_filter = true;
 
+  SessionAccept *sa = dynamic_cast<SessionAccept *>(cont);
+  na->proxyPort     = sa ? sa->proxyPort : nullptr;
+  na->snpa          = dynamic_cast<SSLNextProtocolAccept *>(cont);
+
   na->action_         = new NetAcceptAction();
   *na->action_        = cont;
   na->action_->server = &na->server;
@@ -138,7 +147,6 @@ UnixNetProcessor::accept_internal(Continuation *cont, int fd, AcceptOptions cons
       if (0 == na->do_listen(BLOCKING)) {
         for (int i = 1; i < accept_threads; ++i) {
           NetAccept *a = na->clone();
-
           snprintf(thr_name, MAX_THREAD_NAME_LENGTH, "[ACCEPT %d:%d]", i - 1, ats_ip_port_host_order(&accept_ip));
           a->init_accept_loop(thr_name);
           Debug("iocore_net_accept", "Created accept thread #%d for port %d", i, ats_ip_port_host_order(&accept_ip));
@@ -164,7 +172,7 @@ UnixNetProcessor::accept_internal(Continuation *cont, int fd, AcceptOptions cons
   } else {
     na->init_accept(nullptr);
   }
-
+  naVec.push_back(na);
 #ifdef TCP_DEFER_ACCEPT
   // set tcp defer accept timeout if it is configured, this will not trigger an accept until there is
   // data on the socket ready to be read
diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index f9c172c..a9237a2 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -971,6 +971,7 @@ UnixNetVConnection::UnixNetVConnection()
     submit_time(0),
     oob_ptr(nullptr),
     from_accept_thread(false),
+    accept_object(nullptr),
     origin_trace(false),
     origin_trace_addr(nullptr),
     origin_trace_port(0)
diff --git a/lib/ts/apidefs.h.in b/lib/ts/apidefs.h.in
index 3807220..14d3053 100644
--- a/lib/ts/apidefs.h.in
+++ b/lib/ts/apidefs.h.in
@@ -842,6 +842,8 @@ typedef struct tsapi_bufferblock *TSIOBufferBlock;
 typedef struct tsapi_bufferreader *TSIOBufferReader;
 typedef struct tsapi_hostlookupresult *TSHostLookupResult;
 typedef struct tsapi_aiocallback *TSAIOCallback;
+typedef struct tsapi_net_accept *TSAcceptor;
+typedef struct tsapi_protocol_set *TSNextProtocolSet;
 
 typedef void *(*TSThreadFunc)(void *data);
 typedef int (*TSEventFunc)(TSCont contp, TSEvent event, void *edata);
diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
index 2f05027..570b046 100644
--- a/proxy/InkAPI.cc
+++ b/proxy/InkAPI.cc
@@ -39,6 +39,7 @@
 #include "HttpSM.h"
 #include "HttpConfig.h"
 #include "P_Net.h"
+#include "P_SSLNextProtocolAccept.h"
 #include "P_UDPNet.h"
 #include "P_HostDB.h"
 #include "P_Cache.h"
@@ -9185,6 +9186,65 @@ TSSslContextDestroy(TSSslContext ctx)
   SSLReleaseContext(reinterpret_cast<SSL_CTX *>(ctx));
 }
 
+void
+TSRegisterProtocolSet(TSVConn sslp, TSNextProtocolSet ps)
+{
+  NetVConnection *vc        = reinterpret_cast<NetVConnection *>(sslp);
+  SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(vc);
+  if (ssl_vc) {
+    ssl_vc->registerNextProtocolSet(reinterpret_cast<SSLNextProtocolSet *>(ps));
+  }
+}
+
+TSNextProtocolSet
+TSUnregisterProtocol(TSNextProtocolSet protoset, const char *protocol)
+{
+  SSLNextProtocolSet *snps = reinterpret_cast<SSLNextProtocolSet *>(protoset);
+  if (snps) {
+    snps->unregisterEndpoint(protocol, nullptr);
+    return reinterpret_cast<TSNextProtocolSet>(snps);
+  }
+  return nullptr;
+}
+
+TSAcceptor
+TSAcceptorGet(TSVConn sslp)
+{
+  NetVConnection *vc        = reinterpret_cast<NetVConnection *>(sslp);
+  SSLNetVConnection *ssl_vc = dynamic_cast<SSLNetVConnection *>(vc);
+  return ssl_vc ? reinterpret_cast<TSAcceptor>(ssl_vc->accept_object) : nullptr;
+}
+
+extern std::vector<NetAccept *> naVec;
+TSAcceptor
+TSAcceptorGetbyID(int ID)
+{
+  Debug("ssl", "getNetAccept in INK API.cc %p", naVec.at(ID));
+  return reinterpret_cast<TSAcceptor>(naVec.at(ID));
+}
+
+int
+TSAcceptorIDGet(TSAcceptor acceptor)
+{
+  NetAccept *na = reinterpret_cast<NetAccept *>(acceptor);
+  return na ? na->id : -1;
+}
+
+int
+TSAcceptorCount()
+{
+  return naVec.size();
+}
+
+// clones the protoset associated with netAccept
+TSNextProtocolSet
+TSGetcloneProtoSet(TSAcceptor tna)
+{
+  NetAccept *na = reinterpret_cast<NetAccept *>(tna);
+  // clone protoset
+  return (na && na->snpa) ? reinterpret_cast<TSNextProtocolSet>(na->snpa->cloneProtoSet()) : nullptr;
+}
+
 tsapi int
 TSVConnIsSsl(TSVConn sslp)
 {
diff --git a/proxy/api/ts/ts.h b/proxy/api/ts/ts.h
index 4a73063..96f47a5 100644
--- a/proxy/api/ts/ts.h
+++ b/proxy/api/ts/ts.h
@@ -1235,6 +1235,13 @@ tsapi TSSslContext TSSslContextFindByAddr(struct sockaddr const *);
 // Create a new SSL context based on the settings in records.config
 tsapi TSSslContext TSSslServerContextCreate(void);
 tsapi void TSSslContextDestroy(TSSslContext ctx);
+tsapi TSNextProtocolSet TSUnregisterProtocol(TSNextProtocolSet protoset, const char *protocol);
+TSAcceptor TSAcceptorGet(TSVConn sslp);
+TSNextProtocolSet TSGetcloneProtoSet(TSAcceptor tna);
+TSAcceptor TSAcceptorGetbyID(int ID);
+void TSRegisterProtocolSet(TSVConn sslp, TSNextProtocolSet ps);
+int TSAcceptorCount();
+int TSAcceptorIDGet(TSAcceptor acceptor);
 
 // Returns 1 if the sslp argument refers to a SSL connection
 tsapi int TSVConnIsSsl(TSVConn sslp);
@@ -1711,7 +1718,6 @@ tsapi TSVConn TSTransformOutputVConnGet(TSVConn connp);
 
 /* --------------------------------------------------------------------------
    Net VConnections */
-
 tsapi struct sockaddr const *TSNetVConnRemoteAddrGet(TSVConn vc);
 
 /**
diff --git a/proxy/http/HttpProxyServerMain.cc b/proxy/http/HttpProxyServerMain.cc
index a0ef4e4..99b0e2c 100644
--- a/proxy/http/HttpProxyServerMain.cc
+++ b/proxy/http/HttpProxyServerMain.cc
@@ -176,6 +176,7 @@ MakeHttpProxyAcceptor(HttpProxyAcceptor &acceptor, HttpProxyPort &port, unsigned
 
   ProtocolProbeSessionAccept *probe = new ProtocolProbeSessionAccept();
   HttpSessionAccept *http           = nullptr; // don't allocate this unless it will be used.
+  probe->proxyPort                  = &port;
 
   if (port.m_session_protocol_preference.intersects(HTTP_PROTOCOL_SET)) {
     http = new HttpSessionAccept(accept_opt);
@@ -214,7 +215,7 @@ MakeHttpProxyAcceptor(HttpProxyAcceptor &acceptor, HttpProxyPort &port, unsigned
 
     SCOPED_MUTEX_LOCK(lock, ssl_plugin_mutex, this_ethread());
     ssl_plugin_acceptors.push(ssl);
-
+    ssl->proxyPort   = &port;
     acceptor._accept = ssl;
   } else {
     acceptor._accept = probe;

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