You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@trafficserver.apache.org by wa...@apache.org on 2012/05/11 21:18:54 UTC

git commit: TS-1075 added optional explicit port binding for traffic_cop test ports and an option to use the client's source port as the proxy's source port when connecting through to OS when transparent

Updated Branches:
  refs/heads/master 53ebc2f72 -> 9f831282f


TS-1075 added optional explicit port binding for traffic_cop test ports and an option to use the client's source port as the proxy's source port when connecting through to OS when transparent


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

Branch: refs/heads/master
Commit: 9f831282f05cb12bc3332522bfd46c47a4e97c52
Parents: 53ebc2f
Author: Bart Wyatt <wa...@apache.org>
Authored: Fri May 11 14:14:40 2012 -0500
Committer: Bart Wyatt <wa...@apache.org>
Committed: Fri May 11 14:14:40 2012 -0500

----------------------------------------------------------------------
 CHANGES                  |    2 +
 cop/TrafficCop.cc        |   46 ++++++++++++++++++++++++++++++++++++----
 mgmt/RecordsConfig.cc    |    2 +
 proxy/http/HttpConfig.cc |    2 +
 proxy/http/HttpConfig.h  |    2 +
 proxy/http/HttpSM.cc     |   11 +++++++++
 6 files changed, 60 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9f831282/CHANGES
----------------------------------------------------------------------
diff --git a/CHANGES b/CHANGES
index 11a2315..730fb24 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,5 +1,7 @@
                                                          -*- coding: utf-8 -*-
 Changes with Apache Traffic Server 3.1.4
+  *) [TS-1075] workarounds for linux auto-port issues in transparent deployments.
+
   *) [TS-672] cleanup Win32 references.
 
   *) [TS-1181] Make the overridable configs work with "byte" configs.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9f831282/cop/TrafficCop.cc
----------------------------------------------------------------------
diff --git a/cop/TrafficCop.cc b/cop/TrafficCop.cc
index 9ff96d8..9921209 100644
--- a/cop/TrafficCop.cc
+++ b/cop/TrafficCop.cc
@@ -91,6 +91,11 @@ static int rs_port = 8088;
 static MgmtClusterType cluster_type = NO_CLUSTER;
 static int http_backdoor_port = 8084;
 
+#if defined(linux)
+// TS-1075 : auto-port ::connect DoS on high traffic linux systems
+static int source_port = 0;
+#endif
+
 static int manager_failures = 0;
 static int server_failures = 0;
 static int server_not_found = 0;
@@ -124,6 +129,7 @@ static int sem_id = 11452;
 AppVersionInfo appVersionInfo;
 static InkHashTable *configTable = NULL;
 
+static char const localhost[] = "127.0.0.1";
 
 static void
 cop_log(int priority, const char *format, ...)
@@ -688,6 +694,11 @@ read_config()
   read_config_int("proxy.config.cluster.rsport", &rs_port, true);
   read_config_int("proxy.config.lm.sem_id", &sem_id, true);
 
+#if defined(linux)
+  // TS-1075 : auto-port ::connect DoS on high traffic linux systems
+  read_config_int("proxy.config.cop.source_port", &source_port, true);
+#endif
+
   read_config_int("proxy.local.cluster.type", &tmp_int);
   cluster_type = static_cast<MgmtClusterType>(tmp_int);
 
@@ -851,7 +862,7 @@ poll_write(int fd, int timeout)
 }
 
 static int
-open_socket(int port, const char *ip = NULL, char *ip_to_bind = NULL)
+open_socket(int port, const char *ip = NULL, char const *ip_to_bind = NULL)
 {
 
   int sock = 0;
@@ -865,8 +876,16 @@ open_socket(int port, const char *ip = NULL, char *ip_to_bind = NULL)
   cop_log(COP_DEBUG, "Entering open_socket(%d, %s, %s)\n", port, ip, ip_to_bind);
 #endif
   if (!ip) {
-    ip = "127.0.0.1";
+    ip = localhost;
+  }
+
+#if defined(linux)
+  // TS-1075 : auto-port ::connect DoS on high traffic linux systems
+  // unbound connections are "unsafe" in high connection count environments
+  if (!ip_to_bind) {
+    ip = localhost;
   }
+#endif
 
   snprintf(port_str, sizeof(port_str), "%d", port);
   memset(&hints, 0, sizeof(hints));
@@ -901,6 +920,24 @@ open_socket(int port, const char *ip = NULL, char *ip_to_bind = NULL)
       goto error;
     }
 
+#if defined(linux)
+    // TS-1075 : auto-port ::connect DoS on high traffic linux systems
+    // Bash the port on ::bind so that we always use the same port
+    if (0 != source_port) {
+      if (result_to_bind->ai_addr->sa_family == AF_INET) {
+        ((sockaddr_in *)result_to_bind->ai_addr)->sin_port = htons(source_port);
+      } else {
+        ((sockaddr_in6 *)result_to_bind->ai_addr)->sin6_port = htons(source_port);
+      }
+
+      // also set REUSEADDR so that previous cop connections in the TIME_WAIT state
+      // do not interfere
+      if (safe_setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, SOCKOPT_ON, sizeof(int)) < 0) {
+        cop_log (COP_WARNING, "(test) unable to set REUSEADDR socket option [%d '%s']\n", errno, strerror (errno));
+      }
+    }
+#endif
+
     if (safe_bind(sock, result_to_bind->ai_addr, result_to_bind->ai_addrlen) < 0) {
       cop_log (COP_WARNING, "(test) unable to bind socket [%d '%s']\n", errno, strerror (errno));
     }
@@ -947,7 +984,7 @@ getaddrinfo_error:
 
 static int
 test_port(int port, const char *request, char *buffer, int bufsize,
-          int64_t test_timeout, char *ip = NULL, char *ip_to_bind = NULL)
+          int64_t test_timeout, char const *ip = NULL, char const *ip_to_bind = NULL)
 {
   int64_t start_time, timeout;
   int sock;
@@ -1200,7 +1237,7 @@ test_mgmt_cli_port()
 
 
 static int
-test_http_port(int port, char *request, int timeout, char *ip = NULL, char *ip_to_bind = NULL)
+test_http_port(int port, char *request, int timeout, char const *ip = NULL, char const *ip_to_bind = NULL)
 {
   char buffer[4096];
   char *p;
@@ -1261,7 +1298,6 @@ static int
 test_server_http_port()
 {
   char request[1024] = {'\0'};
-  static char localhost[] = "127.0.0.1";
 
   // Generate a request for a the 'synthetic.txt' document the manager
   // servers up on the autoconf port.

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9f831282/mgmt/RecordsConfig.cc
----------------------------------------------------------------------
diff --git a/mgmt/RecordsConfig.cc b/mgmt/RecordsConfig.cc
index e1cba3a..d86d57c 100644
--- a/mgmt/RecordsConfig.cc
+++ b/mgmt/RecordsConfig.cc
@@ -439,6 +439,8 @@ RecordElement RecordsConfig[] = {
   ,
   {RECT_CONFIG, "proxy.config.http.use_client_target_addr", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-1]", RECA_NULL}
   ,
+  {RECT_CONFIG, "proxy.config.http.use_client_source_port", RECD_INT, "0", RECU_DYNAMIC, RR_NULL, RECC_INT, "[0-1]", RECA_NULL}
+  ,
   {RECT_CONFIG, "proxy.config.http.keep_alive_enabled_in", RECD_INT, "1", RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL}
   ,
   {RECT_CONFIG, "proxy.config.http.keep_alive_enabled_out", RECD_INT, "1", RECU_DYNAMIC, RR_NULL, RECC_NULL, NULL, RECA_NULL}

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9f831282/proxy/http/HttpConfig.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpConfig.cc b/proxy/http/HttpConfig.cc
index 63115c2..3f5c1f2 100644
--- a/proxy/http/HttpConfig.cc
+++ b/proxy/http/HttpConfig.cc
@@ -1154,6 +1154,7 @@ HttpConfig::startup()
 
   HttpEstablishStaticConfigByte(c.no_origin_server_dns, "proxy.config.http.no_origin_server_dns");
   HttpEstablishStaticConfigByte(c.use_client_target_addr, "proxy.config.http.use_client_target_addr");
+  HttpEstablishStaticConfigByte(c.use_client_source_port, "proxy.config.http.use_client_source_port");
   HttpEstablishStaticConfigByte(c.oride.maintain_pristine_host_hdr, "proxy.config.url_remap.pristine_host_hdr");
 
   HttpEstablishStaticConfigByte(c.enable_url_expandomatic, "proxy.config.http.enable_url_expandomatic");
@@ -1417,6 +1418,7 @@ HttpConfig::reconfigure()
   params->uncacheable_requests_bypass_parent = INT_TO_BOOL(m_master.uncacheable_requests_bypass_parent);
   params->no_origin_server_dns = INT_TO_BOOL(m_master.no_origin_server_dns);
   params->use_client_target_addr = INT_TO_BOOL(m_master.use_client_target_addr);
+  params->use_client_source_port = INT_TO_BOOL(m_master.use_client_source_port);
   params->oride.maintain_pristine_host_hdr = INT_TO_BOOL(m_master.oride.maintain_pristine_host_hdr);
 
   params->disable_ssl_parenting = INT_TO_BOOL(m_master.disable_ssl_parenting);

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9f831282/proxy/http/HttpConfig.h
----------------------------------------------------------------------
diff --git a/proxy/http/HttpConfig.h b/proxy/http/HttpConfig.h
index 38f9692..6c92bd1 100644
--- a/proxy/http/HttpConfig.h
+++ b/proxy/http/HttpConfig.h
@@ -616,6 +616,7 @@ public:
   MgmtByte uncacheable_requests_bypass_parent;
   MgmtByte no_origin_server_dns;
   MgmtByte use_client_target_addr;
+  MgmtByte use_client_source_port;
 
   char *proxy_request_via_string;
   int proxy_request_via_string_len;
@@ -899,6 +900,7 @@ HttpConfigParams::HttpConfigParams()
     uncacheable_requests_bypass_parent(1),
     no_origin_server_dns(0),
     use_client_target_addr(0),
+    use_client_source_port(0),
     proxy_request_via_string(0),
     proxy_request_via_string_len(0),
     proxy_response_via_string(0),

http://git-wip-us.apache.org/repos/asf/trafficserver/blob/9f831282/proxy/http/HttpSM.cc
----------------------------------------------------------------------
diff --git a/proxy/http/HttpSM.cc b/proxy/http/HttpSM.cc
index 72e1cdc..f456181 100644
--- a/proxy/http/HttpSM.cc
+++ b/proxy/http/HttpSM.cc
@@ -4282,6 +4282,17 @@ HttpSM::do_http_server_open(bool raw)
     } else if (ua_session->f_outbound_transparent) {
       opt.addr_binding = NetVCOptions::FOREIGN_ADDR;
       opt.local_ip = t_state.client_info.addr;
+
+      /* If the connection is server side transparent, we can bind to the
+         port that the client chose instead of randomly assigning one at
+         the proxy.  This is controlled by the 'use_client_source_port'
+         configuration parameter.
+      */
+
+      NetVConnection *client_vc = ua_session->get_netvc();
+      if (t_state.http_config_param->use_client_source_port && NULL != client_vc) {
+        opt.local_port = client_vc->get_remote_port();
+      }
     }
   }