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;
