TS-1090 Added the ability to set firwall marks on linux connections (bonus 
feature includes IP TOS/DSCP as well


Project: http://git-wip-us.apache.org/repos/asf/trafficserver/repo
Commit: http://git-wip-us.apache.org/repos/asf/trafficserver/commit/b7783899
Tree: http://git-wip-us.apache.org/repos/asf/trafficserver/tree/b7783899
Diff: http://git-wip-us.apache.org/repos/asf/trafficserver/diff/b7783899

Branch: refs/heads/master
Commit: b77838991531d6cb402618c3d690b83e95b92d63
Parents: 4fa8350
Author: Bart Wyatt <[email protected]>
Authored: Thu May 3 15:11:05 2012 -0500
Committer: Bart Wyatt <[email protected]>
Committed: Thu May 3 15:11:05 2012 -0500

----------------------------------------------------------------------
 configure.ac                         |   41 +++++++++++++
 iocore/cluster/ClusterHandlerBase.cc |    5 ++
 iocore/cluster/ClusterProcessor.cc   |    4 +
 iocore/net/Connection.cc             |    1 +
 iocore/net/I_NetProcessor.h          |    3 +
 iocore/net/I_NetVConnection.h        |    9 +++-
 iocore/net/P_Connection.h            |    3 +
 iocore/net/P_NetAccept.h             |    2 +
 iocore/net/P_UnixNetVConnection.h    |    9 +++-
 iocore/net/UnixConnection.cc         |   42 ++++++++++----
 iocore/net/UnixNetAccept.cc          |   20 ++++++-
 iocore/net/UnixNetProcessor.cc       |    4 +
 iocore/net/UnixNetVConnection.cc     |    6 ++
 lib/ts/ink_config.h.in               |    2 +
 mgmt/RecordsConfig.cc                |   12 ++++
 proxy/InkAPI.cc                      |   94 +++++++++++++++++++++++++++++
 proxy/InkAPITest.cc                  |    2 +
 proxy/PluginVC.cc                    |    6 ++
 proxy/PluginVC.h                     |    1 +
 proxy/UglyLogStubs.cc                |    2 +
 proxy/api/ts/ts.h.in                 |   51 ++++++++++++++-
 proxy/http/HttpConfig.cc             |    6 ++
 proxy/http/HttpConfig.h              |    3 +
 proxy/http/HttpProxyServerMain.cc    |    2 +
 proxy/http/HttpSM.cc                 |   21 ++++++-
 25 files changed, 332 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/configure.ac
----------------------------------------------------------------------
diff --git a/configure.ac b/configure.ac
index ea57666..75c9dcd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1305,6 +1305,47 @@ AS_IF([test "x$enable_tproxy" != "xno"], [
 AC_SUBST(use_tproxy)
 AC_SUBST(ip_transparent)
 
+AC_MSG_CHECKING([for SO_MARK])
+AC_LANG_PUSH(C)
+AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[
+       #include <sys/socket.h>
+       ]],[[
+       if( SO_MARK > 0) return 0;
+       else return 1;
+       ]]), [so_mark_found='yes'], [so_mark_found='no'])
+AC_LANG_POP()
+
+if test "x${so_mark_found}" = "xyes"; then
+  has_so_mark=1
+  AC_MSG_RESULT([found])
+else
+  has_so_mark=0
+  AC_MSG_RESULT([not found])
+fi
+AC_SUBST(has_so_mark)
+
+AC_MSG_CHECKING([for IP_TOS])
+AC_LANG_PUSH(C)
+AC_COMPILE_IFELSE(AC_LANG_PROGRAM([[
+       #include <sys/socket.h>
+       #include <netinet/in.h>
+       #include <netinet/ip.h>
+       ]],[[
+       if( IP_TOS > 0) return 0;
+       else return 1;
+       ]]), [ip_tos_found='yes'], [ip_tos_found='no'])
+AC_LANG_POP()
+
+if test "x${ip_tos_found}" = "xyes"; then
+  has_ip_tos=1
+  AC_MSG_RESULT([found])
+else
+  has_ip_tos=0
+  AC_MSG_RESULT([not found])
+fi
+AC_SUBST(has_ip_tos)
+
+
 TS_CHECK_LOOPBACK_IFACE
 TS_CHECK_GETHOSTBYNAME_R_STYLE
 TS_CHECK_MACRO_IN6_IS_ADDR_UNSPECIFIED

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/cluster/ClusterHandlerBase.cc
----------------------------------------------------------------------
diff --git a/iocore/cluster/ClusterHandlerBase.cc 
b/iocore/cluster/ClusterHandlerBase.cc
index b745d30..baa97af 100644
--- a/iocore/cluster/ClusterHandlerBase.cc
+++ b/iocore/cluster/ClusterHandlerBase.cc
@@ -31,6 +31,9 @@
 extern int cluster_receive_buffer_size;
 extern int cluster_send_buffer_size;
 extern uint32_t cluster_sockopt_flags;
+extern uint32_t cluster_packet_mark;
+extern uint32_t cluster_packet_tos;
+
 
 ///////////////////////////////////////////////////////////////
 // Incoming message continuation for periodic callout threads
@@ -841,6 +844,8 @@ ClusterHandler::connectClusterEvent(int event, Event * e)
     opt.socket_send_bufsize = cluster_send_buffer_size;
     opt.socket_recv_bufsize = cluster_receive_buffer_size;
     opt.sockopt_flags = cluster_sockopt_flags;
+    opt.packet_mark = cluster_packet_mark;
+    opt.packet_tos = cluster_packet_tos;
     opt.etype = ET_CLUSTER;
     opt.addr_binding = NetVCOptions::INTF_ADDR;
     opt.local_ip = this_cluster_machine()->ip;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/cluster/ClusterProcessor.cc
----------------------------------------------------------------------
diff --git a/iocore/cluster/ClusterProcessor.cc 
b/iocore/cluster/ClusterProcessor.cc
index c603740..6f20f5e 100644
--- a/iocore/cluster/ClusterProcessor.cc
+++ b/iocore/cluster/ClusterProcessor.cc
@@ -383,6 +383,8 @@ int CacheClusterMonitorIntervalSecs = 1;
 int cluster_send_buffer_size = 0;
 int cluster_receive_buffer_size = 0;
 unsigned long cluster_sockopt_flags = 0;
+unsigned long cluster_packet_mark = 0;
+unsigned long cluster_packet_tos = 0;
 
 int RPC_only_CacheCluster = 0;
 #endif
@@ -680,6 +682,8 @@ ClusterProcessor::init()
   IOCORE_ReadConfigInteger(cluster_receive_buffer_size, 
"proxy.config.cluster.receive_buffer_size");
   IOCORE_ReadConfigInteger(cluster_send_buffer_size, 
"proxy.config.cluster.send_buffer_size");
   IOCORE_ReadConfigInteger(cluster_sockopt_flags, 
"proxy.config.cluster.sock_option_flag");
+  IOCORE_ReadConfigInteger(cluster_packet_mark, 
"proxy.config.cluster.sock_packet_mark");
+  IOCORE_ReadConfigInteger(cluster_packet_tos, 
"proxy.config.cluster.sock_packet_tos");
   IOCORE_EstablishStaticConfigInt32(RPC_only_CacheCluster, 
"proxy.config.cluster.rpc_cache_cluster");
 
   int cluster_type = 0;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/Connection.cc
----------------------------------------------------------------------
diff --git a/iocore/net/Connection.cc b/iocore/net/Connection.cc
index d3bf2ca..47e0728 100644
--- a/iocore/net/Connection.cc
+++ b/iocore/net/Connection.cc
@@ -68,6 +68,7 @@ Connection::Connection()
   : fd(NO_FD)
   , is_bound(false)
   , is_connected(false)
+  , sock_type(0)
 {
   memset(&addr, 0, sizeof(addr));
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/I_NetProcessor.h
----------------------------------------------------------------------
diff --git a/iocore/net/I_NetProcessor.h b/iocore/net/I_NetProcessor.h
index bea906a..cdccf4e 100644
--- a/iocore/net/I_NetProcessor.h
+++ b/iocore/net/I_NetProcessor.h
@@ -82,6 +82,9 @@ public:
     /// Socket options for @c sockopt.
     /// 0 => do not set options.
     uint32_t sockopt_flags;
+    uint32_t packet_mark;
+    uint32_t packet_tos;
+
     /** Transparency on client (user agent) connection.
        @internal This is irrelevant at a socket level (since inbound
        transparency must be set up when the listen socket is created)

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/I_NetVConnection.h
----------------------------------------------------------------------
diff --git a/iocore/net/I_NetVConnection.h b/iocore/net/I_NetVConnection.h
index 0c55580..97f8de3 100644
--- a/iocore/net/I_NetVConnection.h
+++ b/iocore/net/I_NetVConnection.h
@@ -158,12 +158,16 @@ struct NetVCOptions {
   /// Value for keep alive for @c sockopt_flags.
   static uint32_t const SOCK_OPT_KEEP_ALIVE = 2;
 
+  uint32_t packet_mark;
+  uint32_t packet_tos;
+
   EventType etype;
 
   /// Reset all values to defaults.
   void reset();
 
-  void set_sock_param(int _recv_bufsize, int _send_bufsize, unsigned long 
_opt_flags);
+  void set_sock_param(int _recv_bufsize, int _send_bufsize, unsigned long 
_opt_flags,
+                      unsigned long _packet_mark = 0, unsigned long 
_packet_tos = 0);
 
   NetVCOptions() {
     reset();
@@ -423,6 +427,9 @@ public:
   /** Structure holding user options. */
   NetVCOptions options;
 
+  /** Attempt to push any changed options down */
+  virtual void apply_options() = 0;
+
   //
   // Private
   //

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/P_Connection.h
----------------------------------------------------------------------
diff --git a/iocore/net/P_Connection.h b/iocore/net/P_Connection.h
index 1630ee3..5396226 100644
--- a/iocore/net/P_Connection.h
+++ b/iocore/net/P_Connection.h
@@ -84,6 +84,7 @@ struct Connection
   IpEndpoint addr; ///< Associated address.
   bool is_bound; ///< Flag for already bound to a local address.
   bool is_connected; ///< Flag for already connected.
+  int sock_type;
 
   /** Create and initialize the socket for this connection.
 
@@ -181,6 +182,8 @@ struct Connection
 
   int close();                  // 0 on success, -errno on failure
 
+  void apply_options(NetVCOptions const& opt);
+
   virtual ~ Connection();
   Connection();
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/P_NetAccept.h
----------------------------------------------------------------------
diff --git a/iocore/net/P_NetAccept.h b/iocore/net/P_NetAccept.h
index 4771e3a..046faa4 100644
--- a/iocore/net/P_NetAccept.h
+++ b/iocore/net/P_NetAccept.h
@@ -94,6 +94,8 @@ struct NetAccept:public Continuation
   int recv_bufsize;
   int send_bufsize;
   uint32_t sockopt_flags;
+  uint32_t packet_mark;
+  uint32_t packet_tos;
   EventType etype;
   UnixNetVConnection *epoll_vc; // only storage for epoll events
   EventIO ep;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/P_UnixNetVConnection.h
----------------------------------------------------------------------
diff --git a/iocore/net/P_UnixNetVConnection.h 
b/iocore/net/P_UnixNetVConnection.h
index 9a9d07b..08d9e69 100644
--- a/iocore/net/P_UnixNetVConnection.h
+++ b/iocore/net/P_UnixNetVConnection.h
@@ -61,15 +61,21 @@ NetVCOptions::reset()
 #endif
   socket_send_bufsize = 0;
   sockopt_flags = 0;
+  packet_mark = 0;
+  packet_tos = 0;
+
   etype = ET_NET;
 }
 
 TS_INLINE void
-NetVCOptions::set_sock_param(int _recv_bufsize, int _send_bufsize, unsigned 
long _opt_flags)
+NetVCOptions::set_sock_param(int _recv_bufsize, int _send_bufsize, unsigned 
long _opt_flags,
+                             unsigned long _packet_mark, unsigned long 
_packet_tos)
 {
   socket_recv_bufsize = _recv_bufsize;
   socket_send_bufsize = _send_bufsize;
   sockopt_flags = _opt_flags;
+  packet_mark = _packet_mark;
+  packet_tos = _packet_tos;
 }
 
 struct OOB_callback:public Continuation
@@ -240,6 +246,7 @@ public:
   virtual void set_local_addr();
   virtual void set_remote_addr();
   virtual int set_tcp_init_cwnd(int init_cwnd);
+  virtual void apply_options();
 };
 
 extern ClassAllocator<UnixNetVConnection> netVCAllocator;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/UnixConnection.cc
----------------------------------------------------------------------
diff --git a/iocore/net/UnixConnection.cc b/iocore/net/UnixConnection.cc
index 3be09f5..e0df92d 100644
--- a/iocore/net/UnixConnection.cc
+++ b/iocore/net/UnixConnection.cc
@@ -214,7 +214,7 @@ Connection::open(NetVCOptions const& opt)
   int enable_reuseaddr = 1; // used for sockopt setting
   int res = 0; // temp result
   IpEndpoint local_addr;
-  int sock_type = NetVCOptions::USE_UDP == opt.ip_proto
+  sock_type = NetVCOptions::USE_UDP == opt.ip_proto
     ? SOCK_DGRAM
     : SOCK_STREAM;
   int family;
@@ -294,16 +294,8 @@ Connection::open(NetVCOptions const& opt)
     }
   }
 
-  if (SOCK_STREAM == sock_type) {
-    if (opt.sockopt_flags & NetVCOptions::SOCK_OPT_NO_DELAY) {
-      safe_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, SOCKOPT_ON, sizeof(int));
-      Debug("socket", "::open: setsockopt() TCP_NODELAY on socket");
-    }
-    if (opt.sockopt_flags & NetVCOptions::SOCK_OPT_KEEP_ALIVE) {
-      safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, SOCKOPT_ON, sizeof(int));
-      Debug("socket", "::open: setsockopt() SO_KEEPALIVE on socket");
-    }
-  }
+  // apply dynamic options
+  apply_options(opt);
 
   if (-1 == socketManager.ink_bind(fd, &local_addr.sa, 
ats_ip_size(&local_addr.sa)))
     return -errno;
@@ -352,3 +344,31 @@ Connection::_cleanup()
 {
   this->close();
 }
+
+void
+Connection::apply_options(NetVCOptions const& opt)
+{
+  // Set options which can be changed after a connection is established
+  // ignore other changes
+  if (SOCK_STREAM == sock_type) {
+    if (opt.sockopt_flags & NetVCOptions::SOCK_OPT_NO_DELAY) {
+      safe_setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, SOCKOPT_ON, sizeof(int));
+      Debug("socket", "::open: setsockopt() TCP_NODELAY on socket");
+    }
+    if (opt.sockopt_flags & NetVCOptions::SOCK_OPT_KEEP_ALIVE) {
+      safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, SOCKOPT_ON, sizeof(int));
+      Debug("socket", "::open: setsockopt() SO_KEEPALIVE on socket");
+    }
+  }
+
+#if TS_HAS_SO_MARK
+  uint32_t mark = opt.packet_mark;
+  safe_setsockopt(fd, SOL_SOCKET, SO_MARK, reinterpret_cast<char *>(&mark), 
sizeof(uint32_t));
+#endif
+
+#if TS_HAS_IP_TOS
+  uint32_t tos = opt.packet_tos;
+  safe_setsockopt(fd, IPPROTO_IP, IP_TOS, reinterpret_cast<char *>(&tos), 
sizeof(uint32_t));
+#endif
+
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/UnixNetAccept.cc
----------------------------------------------------------------------
diff --git a/iocore/net/UnixNetAccept.cc b/iocore/net/UnixNetAccept.cc
index 1e11eac..1ff6511 100644
--- a/iocore/net/UnixNetAccept.cc
+++ b/iocore/net/UnixNetAccept.cc
@@ -423,6 +423,17 @@ NetAccept::acceptFastEvent(int event, void *ep)
         safe_setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, SOCKOPT_ON, sizeof(int));
         Debug("socket", "::acceptFastEvent: setsockopt() SO_KEEPALIVE on 
socket");
       }
+#if TS_HAS_SO_MARK
+      if (packet_mark != 0) {
+        safe_setsockopt(fd, SOL_SOCKET, SO_MARK, reinterpret_cast<char 
*>(&packet_mark), sizeof(uint32_t));
+      }
+#endif
+
+#if TS_HAS_IP_TOS
+      if (packet_tos != 0) {
+        safe_setsockopt(fd, IPPROTO_IP, IP_TOS, reinterpret_cast<char 
*>(&packet_tos), sizeof(uint32_t));
+      }
+#endif
       do {
         res = safe_nonblocking(fd);
       } while (res < 0 && (errno == EAGAIN || errno == EINTR));
@@ -524,7 +535,14 @@ NetAccept::NetAccept()
   : Continuation(NULL),
     period(0),
     alloc_cache(0),
-    ifd(-1), callback_on_open(false), recv_bufsize(0), send_bufsize(0), 
sockopt_flags(0), etype(0)
+    ifd(-1),
+    callback_on_open(false),
+    recv_bufsize(0),
+    send_bufsize(0),
+    sockopt_flags(0),
+    packet_mark(0),
+    packet_tos(0),
+    etype(0)
 { }
 
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/UnixNetProcessor.cc
----------------------------------------------------------------------
diff --git a/iocore/net/UnixNetProcessor.cc b/iocore/net/UnixNetProcessor.cc
index 512a68a..c3cdea6 100644
--- a/iocore/net/UnixNetProcessor.cc
+++ b/iocore/net/UnixNetProcessor.cc
@@ -44,6 +44,8 @@ NetProcessor::AcceptOptions::reset()
   recv_bufsize = 0;
   send_bufsize = 0;
   sockopt_flags = 0;
+  packet_mark = 0;
+  packet_tos = 0;
   f_inbound_transparent = false;
   return *this;
 }
@@ -141,6 +143,8 @@ UnixNetProcessor::accept_internal(
   na->recv_bufsize = opt.recv_bufsize;
   na->send_bufsize = opt.send_bufsize;
   na->sockopt_flags = opt.sockopt_flags;
+  na->packet_mark = opt.packet_mark;
+  na->packet_tos = opt.packet_tos;
   na->etype = opt.etype;
   if (na->callback_on_open)
     na->mutex = cont->mutex;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/iocore/net/UnixNetVConnection.cc
----------------------------------------------------------------------
diff --git a/iocore/net/UnixNetVConnection.cc b/iocore/net/UnixNetVConnection.cc
index b74defa..f70d8a8 100644
--- a/iocore/net/UnixNetVConnection.cc
+++ b/iocore/net/UnixNetVConnection.cc
@@ -1155,3 +1155,9 @@ UnixNetVConnection::free(EThread *t)
     THREAD_FREE(this, netVCAllocator, t);
   }
 }
+
+void
+UnixNetVConnection::apply_options()
+{
+  con.apply_options(options);
+}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/lib/ts/ink_config.h.in
----------------------------------------------------------------------
diff --git a/lib/ts/ink_config.h.in b/lib/ts/ink_config.h.in
index e6b6920..dd6a007 100644
--- a/lib/ts/ink_config.h.in
+++ b/lib/ts/ink_config.h.in
@@ -110,6 +110,8 @@
 #define TS_USE_PORT                    @use_port@
 #define TS_USE_POSIX_CAP               @use_posix_cap@
 #define TS_USE_TPROXY                  @use_tproxy@
+#define TS_HAS_SO_MARK                 @has_so_mark@
+#define TS_HAS_IP_TOS                  @has_ip_tos@
 #define TS_USE_HWLOC                   @use_hwloc@
 #define TS_USE_FREELIST                @use_freelist@
 #define TS_USE_TLS_NPN                 @use_tls_npn@

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/mgmt/RecordsConfig.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index b74f51a..e7b2052 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -832,12 +832,20 @@ RecordElement RecordsConfig[] = {
   ,
   {RECT_CONFIG, "proxy.config.net.sock_option_flag_in", RECD_INT, "0x0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
+  {RECT_CONFIG, "proxy.config.net.sock_packet_mark_in", RECD_INT, "0x0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
+  ,
+  {RECT_CONFIG, "proxy.config.net.sock_packet_tos_in", RECD_INT, "0x0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
+  ,
   {RECT_CONFIG, "proxy.config.net.sock_recv_buffer_size_out", RECD_INT, "0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
   {RECT_CONFIG, "proxy.config.net.sock_send_buffer_size_out", RECD_INT, "0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
   {RECT_CONFIG, "proxy.config.net.sock_option_flag_out", RECD_INT, "0x0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
+  {RECT_CONFIG, "proxy.config.net.sock_packet_mark_out", RECD_INT, "0x0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
+  ,
+  {RECT_CONFIG, "proxy.config.net.sock_packet_tos_out", RECD_INT, "0x0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
+  ,
   {RECT_CONFIG, "proxy.config.net.sock_mss_in", RECD_INT, "0", RECU_NULL, 
RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
 
@@ -864,6 +872,10 @@ RecordElement RecordsConfig[] = {
   ,
   {RECT_CONFIG, "proxy.config.cluster.sock_option_flag", RECD_INT, "0x0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
+  {RECT_CONFIG, "proxy.config.cluster.sock_packet_mark", RECD_INT, "0x0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
+  ,
+  {RECT_CONFIG, "proxy.config.cluster.sock_packet_tos", RECD_INT, "0x0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
+  ,
   {RECT_CONFIG, "proxy.config.cluster.rpc_cache_cluster", RECD_INT, "0", 
RECU_NULL, RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/InkAPI.cc
----------------------------------------------------------------------
diff --git a/proxy/InkAPI.cc b/proxy/InkAPI.cc
index 03f6cbe..1027288 100644
--- a/proxy/InkAPI.cc
+++ b/proxy/InkAPI.cc
@@ -38,6 +38,7 @@
 #include "MIME.h"
 #include "HTTP.h"
 #include "HttpClientSession.h"
+#include "HttpServerSession.h"
 #include "HttpSM.h"
 #include "HttpConfig.h"
 #include "P_Net.h"
@@ -5357,6 +5358,89 @@ TSHttpTxnOutgoingTransparencySet(TSHttpTxn txnp, int 
flag)
   return TS_SUCCESS;
 }
 
+TSReturnCode
+TSHttpTxnClientPacketMarkSet(TSHttpTxn txnp, int mark)
+{
+  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
+  HttpSM *sm = (HttpSM *) txnp;
+  if (NULL == sm->ua_session) {
+    return TS_ERROR;
+  }
+
+  NetVConnection *vc = sm->ua_session->get_netvc();
+  if (NULL == vc) {
+    return TS_ERROR;
+  }
+
+  vc->options.packet_mark = (uint32_t)mark;
+  vc->apply_options();
+  return TS_SUCCESS;
+}
+
+TSReturnCode
+TSHttpTxnServerPacketMarkSet(TSHttpTxn txnp, int mark)
+{
+  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
+  HttpSM *sm = (HttpSM *) txnp;
+
+  // change the mark on an active server session
+  if (NULL != sm->ua_session) {
+    HttpServerSession *ssn = sm->ua_session->get_server_session();
+    if (NULL != ssn) {
+      NetVConnection *vc = ssn->get_netvc();
+      if (vc != NULL) {
+        vc->options.packet_mark = (uint32_t)mark;
+        vc->apply_options();
+      }
+    }
+  }
+
+  // update the transactions mark config for future connections
+  TSHttpTxnConfigIntSet(txnp, TS_CONFIG_NET_SOCK_PACKET_MARK_OUT, mark);
+  return TS_SUCCESS;
+}
+
+TSReturnCode
+TSHttpTxnClientPacketTosSet(TSHttpTxn txnp, int tos)
+{
+  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
+  HttpSM *sm = (HttpSM *) txnp;
+  if (NULL == sm->ua_session) {
+    return TS_ERROR;
+  }
+
+  NetVConnection *vc = sm->ua_session->get_netvc();
+  if (NULL == vc) {
+    return TS_ERROR;
+  }
+
+  vc->options.packet_tos = (uint32_t)tos;
+  vc->apply_options();
+  return TS_SUCCESS;
+}
+
+TSReturnCode
+TSHttpTxnServerPacketTosSet(TSHttpTxn txnp, int tos)
+{
+  sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
+  HttpSM *sm = (HttpSM *) txnp;
+
+  // change the tos on an active server session
+  if (NULL != sm->ua_session) {
+    HttpServerSession *ssn = sm->ua_session->get_server_session();
+    if (NULL != ssn) {
+      NetVConnection *vc = ssn->get_netvc();
+      if (vc != NULL) {
+        vc->options.packet_tos = (uint32_t)tos;
+        vc->apply_options();
+      }
+    }
+  }
+
+  // update the transactions mark config for future connections
+  TSHttpTxnConfigIntSet(txnp, TS_CONFIG_NET_SOCK_PACKET_TOS_OUT, tos);
+  return TS_SUCCESS;
+}
 
 void
 TSHttpTxnErrorBodySet(TSHttpTxn txnp, char *buf, int buflength, char *mimetype)
@@ -7430,6 +7514,12 @@ _conf_to_memberp(TSOverridableConfigKey conf, HttpSM* 
sm, OverridableDataType *t
   case TS_CONFIG_NET_SOCK_OPTION_FLAG_OUT:
     ret = &sm->t_state.txn_conf->sock_option_flag_out;
     break;
+  case TS_CONFIG_NET_SOCK_PACKET_MARK_OUT:
+    ret = &sm->t_state.txn_conf->sock_packet_mark_out;
+    break;
+  case TS_CONFIG_NET_SOCK_PACKET_TOS_OUT:
+      ret = &sm->t_state.txn_conf->sock_packet_tos_out;
+      break;
   case TS_CONFIG_HTTP_FORWARD_PROXY_AUTH_TO_PARENT:
     ret = &sm->t_state.txn_conf->fwd_proxy_auth_to_parent;
     break;
@@ -7774,6 +7864,10 @@ TSHttpTxnConfigFind(const char* name, int length, 
TSOverridableConfigKey *conf,
         cnf = TS_CONFIG_HTTP_KEEP_ALIVE_POST_OUT;
       else if (!strncmp(name, "proxy.config.net.sock_option_flag_out", length))
         cnf = TS_CONFIG_NET_SOCK_OPTION_FLAG_OUT;
+      else if (!strncmp(name, "proxy.config.net.sock_packet_mark_out", length))
+        cnf = TS_CONFIG_NET_SOCK_PACKET_MARK_OUT;
+      else if (!strncmp(name, "proxy.config.net.sock_packet_tos_out", length))
+        cnf = TS_CONFIG_NET_SOCK_PACKET_TOS_OUT;
       break;
     }
     break;

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/InkAPITest.cc
----------------------------------------------------------------------
diff --git a/proxy/InkAPITest.cc b/proxy/InkAPITest.cc
index bac3d86..2c356f4 100644
--- a/proxy/InkAPITest.cc
+++ b/proxy/InkAPITest.cc
@@ -7533,6 +7533,8 @@ const char *SDK_Overridable_Configs[] = {
   "proxy.config.net.sock_recv_buffer_size_out",
   "proxy.config.net.sock_send_buffer_size_out",
   "proxy.config.net.sock_option_flag_out",
+  "proxy.config.net.sock_packet_mark_out",
+  "proxy.config.net.sock_packet_tos_out",
   "proxy.config.http.forward.proxy_auth_to_parent",
   "proxy.config.http.anonymize_remove_from",
   "proxy.config.http.anonymize_remove_referer",

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/PluginVC.cc
----------------------------------------------------------------------
diff --git a/proxy/PluginVC.cc b/proxy/PluginVC.cc
index 1346c66..5ce1bcb 100644
--- a/proxy/PluginVC.cc
+++ b/proxy/PluginVC.cc
@@ -903,6 +903,12 @@ PluginVC::set_tcp_init_cwnd(int init_cwnd)
   return -1;
 }
 
+void
+PluginVC::apply_options()
+{
+  // do nothing
+}
+
 bool
 PluginVC::get_data(int id, void *data)
 {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/PluginVC.h
----------------------------------------------------------------------
diff --git a/proxy/PluginVC.h b/proxy/PluginVC.h
index 7a6245e..d953741 100644
--- a/proxy/PluginVC.h
+++ b/proxy/PluginVC.h
@@ -112,6 +112,7 @@ public:
   virtual void set_local_addr();
   virtual void set_remote_addr();
   virtual int set_tcp_init_cwnd(int init_cwnd);
+  virtual void apply_options();
 
   virtual bool get_data(int id, void *data);
   virtual bool set_data(int id, void *data);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/UglyLogStubs.cc
----------------------------------------------------------------------
diff --git a/proxy/UglyLogStubs.cc b/proxy/UglyLogStubs.cc
index 223d453..0d8e219 100644
--- a/proxy/UglyLogStubs.cc
+++ b/proxy/UglyLogStubs.cc
@@ -139,6 +139,8 @@ NetProcessor::AcceptOptions::reset()
   recv_bufsize = 0;
   send_bufsize = 0;
   sockopt_flags = 0;
+  packet_mark = 0;
+  packet_tos = 0;
   f_inbound_transparent = false;
   return *this;
 }

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/api/ts/ts.h.in
----------------------------------------------------------------------
diff --git a/proxy/api/ts/ts.h.in b/proxy/api/ts/ts.h.in
index f3260ae..66f30a0 100644
--- a/proxy/api/ts/ts.h.in
+++ b/proxy/api/ts/ts.h.in
@@ -539,8 +539,6 @@ extern "C"
   typedef enum
   {
     TS_CONFIG_NULL = -1,
-    /* The order of these enum's must match the order of
-       struct OverridableHttpConfigParams in HttpConfig.h. */
     TS_CONFIG_URL_REMAP_PRISTINE_HOST_HDR,
     TS_CONFIG_HTTP_CHUNKING_ENABLED,
     TS_CONFIG_HTTP_NEGATIVE_CACHING_ENABLED,
@@ -596,11 +594,11 @@ extern "C"
     TS_CONFIG_HTTP_CACHE_FUZZ_TIME,
     TS_CONFIG_HTTP_CACHE_FUZZ_MIN_TIME,
     TS_CONFIG_HTTP_DOC_IN_CACHE_SKIP_DNS,
-
-    /* Strings and floats must come after all the integer configs */
     TS_CONFIG_HTTP_RESPONSE_SERVER_STR,
     TS_CONFIG_HTTP_CACHE_HEURISTIC_LM_FACTOR,
     TS_CONFIG_HTTP_CACHE_FUZZ_PROBABILITY,
+    TS_CONFIG_NET_SOCK_PACKET_MARK_OUT,
+    TS_CONFIG_NET_SOCK_PACKET_TOS_OUT,
     TS_CONFIG_LAST_ENTRY
   } TSOverridableConfigKey;
 
@@ -2267,6 +2265,51 @@ extern "C"
   tsapi TSReturnCode TSHttpSsnClientFdGet(TSHttpSsn ssnp, int* fdp);
   /* TS-1008 END */
 
+  /** Change packet firewall mark for the client side connection
+   *
+      @note The change takes effect immediately
+      
+      @return TS_SUCCESS if the client connection was modified
+  */
+  tsapi TSReturnCode TSHttpTxnClientPacketMarkSet(TSHttpTxn txnp, int mark);
+  
+  /** Change packet firewall mark for the server side connection
+   *
+      @note The change takes effect immediately, if no OS connection has been
+      made, then this sets the mark that will be used IF an OS connection
+      is established
+      
+      @return TS_SUCCESS if the (future?) server connection was modified
+  */
+  tsapi TSReturnCode TSHttpTxnServerPacketMarkSet(TSHttpTxn txnp, int mark);
+  
+  /** Change packet TOS for the client side connection
+   *
+      @note The change takes effect immediately
+      
+      @note TOS is deprecated and replaced by DSCP, this is still used to
+      set DSCP however the first 2 bits of this value will be ignored as
+      they now belong to the ECN field.
+      
+      @return TS_SUCCESS if the client connection was modified
+  */
+  tsapi TSReturnCode TSHttpTxnClientPacketTosSet(TSHttpTxn txnp, int tos);
+  
+  /** Change packet TOS for the server side connection
+   *
+      @note The change takes effect immediately, if no OS connection has been
+      made, then this sets the mark that will be used IF an OS connection
+      is established
+      
+      @note TOS is deprecated and replaced by DSCP, this is still used to
+      set DSCP however the first 2 bits of this value will be ignored as
+      they now belong to the ECN field.
+      
+      @return TS_SUCCESS if the (future?) server connection was modified
+  */
+  tsapi TSReturnCode TSHttpTxnServerPacketTosSet(TSHttpTxn txnp, int tos);
+
+
   tsapi void TSHttpTxnErrorBodySet(TSHttpTxn txnp, char* buf, int buflength, 
char* mimetype);
 
   /**

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/http/HttpConfig.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpConfig.cc b/proxy/http/HttpConfig.cc
index 52aaf01..ecf36ec 100644
--- a/proxy/http/HttpConfig.cc
+++ b/proxy/http/HttpConfig.cc
@@ -1211,6 +1211,9 @@ HttpConfig::startup()
   HttpEstablishStaticConfigLongLong(c.oride.sock_recv_buffer_size_out, 
"proxy.config.net.sock_recv_buffer_size_out");
   HttpEstablishStaticConfigLongLong(c.oride.sock_send_buffer_size_out, 
"proxy.config.net.sock_send_buffer_size_out");
   HttpEstablishStaticConfigLongLong(c.oride.sock_option_flag_out, 
"proxy.config.net.sock_option_flag_out");
+  HttpEstablishStaticConfigLongLong(c.oride.sock_packet_mark_out, 
"proxy.config.net.sock_packet_mark_out");
+  HttpEstablishStaticConfigLongLong(c.oride.sock_packet_tos_out, 
"proxy.config.net.sock_packet_tos_out");
+
 
   HttpEstablishStaticConfigByte(c.oride.fwd_proxy_auth_to_parent, 
"proxy.config.http.forward.proxy_auth_to_parent");
 
@@ -1479,6 +1482,9 @@ HttpConfig::reconfigure()
   params->oride.sock_recv_buffer_size_out = 
m_master.oride.sock_recv_buffer_size_out;
   params->oride.sock_send_buffer_size_out = 
m_master.oride.sock_send_buffer_size_out;
   params->oride.sock_option_flag_out = m_master.oride.sock_option_flag_out;
+  params->oride.sock_packet_mark_out = m_master.oride.sock_packet_mark_out;
+  params->oride.sock_packet_tos_out = m_master.oride.sock_packet_tos_out;
+
 
   params->oride.fwd_proxy_auth_to_parent = 
INT_TO_BOOL(m_master.oride.fwd_proxy_auth_to_parent);
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/http/HttpConfig.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpConfig.h b/proxy/http/HttpConfig.h
index 5757ab4..fee7c61 100644
--- a/proxy/http/HttpConfig.h
+++ b/proxy/http/HttpConfig.h
@@ -405,6 +405,7 @@ struct OverridableHttpConfigParams {
        keep_alive_enabled_in(0), keep_alive_enabled_out(0), 
keep_alive_post_out(0),
        server_tcp_init_cwnd(0), share_server_sessions(0),
        sock_recv_buffer_size_out(0), sock_send_buffer_size_out(0), 
sock_option_flag_out(0),
+       sock_packet_mark_out(0), sock_packet_tos_out(0),
        fwd_proxy_auth_to_parent(0), 
        anonymize_remove_from(0), anonymize_remove_referer(0), 
anonymize_remove_user_agent(0),
        anonymize_remove_cookie(0), anonymize_remove_client_ip(0), 
anonymize_insert_client_ip(1),
@@ -463,6 +464,8 @@ struct OverridableHttpConfigParams {
   MgmtInt sock_recv_buffer_size_out;
   MgmtInt sock_send_buffer_size_out;
   MgmtInt sock_option_flag_out;
+  MgmtInt sock_packet_mark_out;
+  MgmtInt sock_packet_tos_out;
 
   MgmtByte fwd_proxy_auth_to_parent;
 

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/http/HttpProxyServerMain.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpProxyServerMain.cc 
b/proxy/http/HttpProxyServerMain.cc
index 9df86a3..555cea0 100644
--- a/proxy/http/HttpProxyServerMain.cc
+++ b/proxy/http/HttpProxyServerMain.cc
@@ -176,6 +176,8 @@ start_HttpProxyServer(int accept_threads)
   opt.accept_threads = accept_threads;
   REC_ReadConfigInteger(opt.recv_bufsize, 
"proxy.config.net.sock_recv_buffer_size_in");
   REC_ReadConfigInteger(opt.send_bufsize, 
"proxy.config.net.sock_send_buffer_size_in");
+  REC_ReadConfigInteger(opt.packet_mark, 
"proxy.config.net.sock_packet_mark_in");
+  REC_ReadConfigInteger(opt.packet_tos, "proxy.config.net.sock_packet_tos_in");
   SslConfigParams *sslParam = sslTerminationConfig.acquire();
   
   for ( int i = 0 , n = HttpProxyPort::global().length() ; i < n ; ++i ) {

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/b7783899/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 4542244..ebc9c4f 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -4224,7 +4224,9 @@ HttpSM::do_http_server_open(bool raw)
   opt.f_blocking_connect = false;
   opt.set_sock_param(t_state.txn_conf->sock_recv_buffer_size_out,
                      t_state.txn_conf->sock_send_buffer_size_out,
-                     t_state.txn_conf->sock_option_flag_out);
+                     t_state.txn_conf->sock_option_flag_out,
+                     t_state.txn_conf->sock_packet_mark_out,
+                     t_state.txn_conf->sock_packet_tos_out);
 
   opt.ip_family = ip_family;
 
@@ -4596,6 +4598,23 @@ HttpSM::handle_post_failure()
 void
 HttpSM::handle_http_server_open()
 {
+  // [bwyatt] applying per-transaction OS netVC options here
+  //          IFF they differ from the netVC's current options.
+  //          This should keep this from being redundant on a
+  //          server session's first transaction.
+  if (NULL != server_session) {
+    NetVConnection *vc = server_session->get_netvc();
+    if (vc != NULL &&
+        (vc->options.sockopt_flags != t_state.txn_conf->sock_option_flag_out ||
+         vc->options.packet_mark != t_state.txn_conf->sock_packet_mark_out ||
+         vc->options.packet_tos != t_state.txn_conf->sock_packet_tos_out )) {
+      vc->options.sockopt_flags = t_state.txn_conf->sock_option_flag_out;
+      vc->options.packet_mark = t_state.txn_conf->sock_packet_mark_out;
+      vc->options.packet_tos = t_state.txn_conf->sock_packet_tos_out;
+      vc->apply_options();
+    }
+  }
+
   if (t_state.pCongestionEntry != NULL) {
     if (t_state.congestion_connection_opened == 0) {
       t_state.congestion_connection_opened = 1;

Reply via email to