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

zwoop pushed a commit to branch 7.1.x
in repository https://gitbox.apache.org/repos/asf/trafficserver.git


The following commit(s) were added to refs/heads/7.1.x by this push:
     new 7f1c394  YTSATS-1127: update tls_proto to allow for override of port 
protoset
7f1c394 is described below

commit 7f1c3943222f811a79dcf19021562826bb6986f1
Author: Persia Aziz <[email protected]>
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                   |  21 ++--
 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, 392 insertions(+), 28 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 = "[email protected]";
+  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..14270cf 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 {
@@ -87,8 +88,8 @@ class SSLNetVConnection : public UnixNetVConnection
   typedef UnixNetVConnection super; ///< Parent type.
 
 public:
-  virtual int sslStartHandShake(int event, int &err);
-  virtual void free(EThread *t);
+  int sslStartHandShake(int event, int &err) override;
+  void free(EThread *t) override;
 
   virtual void
   enableRead()
@@ -97,8 +98,8 @@ public:
     write.enabled = 1;
   }
 
-  virtual bool
-  getSSLHandShakeComplete() const
+  bool
+  getSSLHandShakeComplete() const override
   {
     return sslHandShakeComplete;
   }
@@ -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        //
@@ -240,15 +241,15 @@ public:
     return ssl ? SSL_get_cipher_name(ssl) : nullptr;
   }
 
-  int populate_protocol(const char **results, int n) const;
-  const char *protocol_contains(const char *tag) const;
+  int populate_protocol(const char **results, int n) const override;
+  const char *protocol_contains(const char *tag) const override;
 
   /**
    * Populate the current object based on the socket information in in the
    * con parameter and the ssl object in the arg parameter
    * This is logic is invoked when the NetVC object is created in a new thread 
context
    */
-  virtual int populate(Connection &con, Continuation *c, void *arg);
+  virtual int populate(Connection &con, Continuation *c, void *arg) override;
 
   SSL *ssl;
   ink_hrtime sslHandshakeBeginTime;
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 4d071a9..bd9119c 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;
@@ -291,6 +292,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 204ee7b..757ebe6 100644
--- a/iocore/net/SSLNetVConnection.cc
+++ b/iocore/net/SSLNetVConnection.cc
@@ -1343,7 +1343,6 @@ SSLNetVConnection::sslClientHandShakeEvent(int &err)
 void
 SSLNetVConnection::registerNextProtocolSet(const SSLNextProtocolSet *s)
 {
-  ink_release_assert(this->npnSet == nullptr);
   this->npnSet = s;
 }
 
@@ -1356,7 +1355,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;
@@ -1376,7 +1374,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 8d4d8fa..aaf9398 100644
--- a/iocore/net/UnixNetAccept.cc
+++ b/iocore/net/UnixNetAccept.cc
@@ -32,6 +32,7 @@ using NetAcceptHandler      = int (NetAccept::*)(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 b51c42c..905d268 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 113410d..40f585f 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -928,6 +928,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 cb1a8af..438ad49 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
['"[email protected]" <[email protected]>'].

Reply via email to