Fix SOCKS breakage and allow for setting next-hop SOCKS
-------------------------------------------------------

                 Key: TS-803
                 URL: https://issues.apache.org/jira/browse/TS-803
             Project: Traffic Server
          Issue Type: New Feature
          Components: Network
         Environment: Wherever ATS might run
            Reporter: M. Nunberg


Here is a patch I drew up a few months ago against a snapshot of ATS/2.1.7 
unstable/git. There are some quirks here, and I'm not that sure any more what 
this patch does exactly. However it:

1) Does fix SOCKS connections in general
2) Allows setting next-hop SOCKS proxy via the API

Problems:
See https://issues.apache.org/jira/browse/TS-802
This has no effect on connections which are drawn from the connection pool, as 
it seems ATS currently doesn't maintain unique identities for peripheral 
connection params (source IP, SOCKS etc); i.e. this only affects new TCP 
connections to an OS.

diff -x '*.o' -ru tsorig/iocore/net/I_NetVConnection.h 
tsgit217/iocore/net/I_NetVConnection.h
--- tsorig/iocore/net/I_NetVConnection.h    2011-03-09 21:43:58.000000000 +0000
+++ tsgit217/iocore/net/I_NetVConnection.h    2011-03-17 14:37:18.000000000 
+0000
@@ -120,6 +120,13 @@
   /// Version of SOCKS to use.
   unsigned char socks_version;

+  struct {
+      unsigned int ip;
+      int port;
+      char *username;
+      char *password;
+  } socks_override;
+
   int socket_recv_bufsize;
   int socket_send_bufsize;

Only in tsgit217/iocore/net: Makefile
Only in tsgit217/iocore/net: Makefile.in
diff -x '*.o' -ru tsorig/iocore/net/P_Socks.h tsgit217/iocore/net/P_Socks.h
--- tsorig/iocore/net/P_Socks.h    2011-03-09 21:43:58.000000000 +0000
+++ tsgit217/iocore/net/P_Socks.h    2011-03-17 13:17:20.000000000 +0000
@@ -126,7 +126,7 @@
   unsigned char version;

   bool write_done;
-
+  bool manual_parent_selection;
   SocksAuthHandler auth_handler;
   unsigned char socks_cmd;

@@ -145,7 +145,8 @@

     SocksEntry():Continuation(NULL), netVConnection(0),
     ip(0), port(0), server_ip(0), server_port(0), nattempts(0),
-    lerrno(0), timeout(0), version(5), write_done(false), auth_handler(NULL), 
socks_cmd(NORMAL_SOCKS)
+    lerrno(0), timeout(0), version(5), write_done(false), 
manual_parent_selection(false),
+    auth_handler(NULL), socks_cmd(NORMAL_SOCKS)
   {
   }
 };
diff -x '*.o' -ru tsorig/iocore/net/Socks.cc tsgit217/iocore/net/Socks.cc
--- tsorig/iocore/net/Socks.cc    2011-03-09 21:43:58.000000000 +0000
+++ tsgit217/iocore/net/Socks.cc    2011-03-17 13:46:07.000000000 +0000
@@ -73,7 +73,8 @@
   nattempts = 0;
   findServer();

-  timeout = this_ethread()->schedule_in(this, 
HRTIME_SECONDS(netProcessor.socks_conf_stuff->server_connect_timeout));
+//  timeout = this_ethread()->schedule_in(this, 
HRTIME_SECONDS(netProcessor.socks_conf_stuff->server_connect_timeout));
+  timeout = this_ethread()->schedule_in(this, HRTIME_SECONDS(5));
   write_done = false;
 }

@@ -81,6 +82,15 @@
 SocksEntry::findServer()
 {
   nattempts++;
+  if(manual_parent_selection) {
+      if(nattempts > 1) {
+          //Nullify IP and PORT
+          server_ip = -1;
+          server_port = 0;
+      }
+      Debug("mndebug(Socks)", "findServer() is a noop with manual socks 
selection");
+      return;
+  }

 #ifdef SOCKS_WITH_TS
   if (nattempts == 1) {
@@ -187,7 +197,6 @@
     }

     Debug("Socks", "Failed to connect to %u.%u.%u.%u:%d", PRINT_IP(server_ip), 
server_port);
-
     findServer();

     if (server_ip == (uint32_t) - 1) {
diff -x '*.o' -ru tsorig/iocore/net/UnixNetProcessor.cc 
tsgit217/iocore/net/UnixNetProcessor.cc
--- tsorig/iocore/net/UnixNetProcessor.cc    2011-03-09 21:43:58.000000000 +0000
+++ tsgit217/iocore/net/UnixNetProcessor.cc    2011-03-17 15:48:38.000000000 
+0000
@@ -228,6 +228,11 @@
                           !socks_conf_stuff->ip_range.match(ip))
 #endif
     );
+  if(opt->socks_override.ip >= 1) {
+      using_socks = true;
+      Debug("mndebug", "trying to set using_socks to true");
+  }
+
   SocksEntry *socksEntry = NULL;
 #endif
   NET_SUM_GLOBAL_DYN_STAT(net_connections_currently_open_stat, 1);
@@ -242,6 +247,16 @@
   if (using_socks) {
     Debug("Socks", "Using Socks ip: %u.%u.%u.%u:%d\n", PRINT_IP(ip), port);
     socksEntry = socksAllocator.alloc();
+
+    if (opt->socks_override.ip) {
+        //Needs to be done before socksEntry->init()
+        socksEntry->server_ip = opt->socks_override.ip;
+        socksEntry->server_port = opt->socks_override.port;
+        socksEntry->manual_parent_selection = true;
+        opt->socks_support = NORMAL_SOCKS;
+        Debug("mndebug(Socks)", "SOCKS proxy selected manually");
+    }
+
     socksEntry->init(cont->mutex, vc, opt->socks_support, opt->socks_version); 
       /*XXXX remove last two args */
     socksEntry->action_ = cont;
     cont = socksEntry;

diff -x '*.o' -ru tsorig/proxy/InkAPI.cc tsgit217/proxy/InkAPI.cc
--- tsorig/proxy/InkAPI.cc    2011-03-09 21:43:58.000000000 +0000
+++ tsgit217/proxy/InkAPI.cc    2011-03-17 15:43:23.000000000 +0000
@@ -5239,6 +5239,15 @@
 }

 void
+TSHttpTxnSocksProxySet(TSHttpTxn txnp, unsigned int ipaddr, int port)
+{
+    sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);
+    HttpSM *sm = (HttpSM*) txnp;
+    sm->t_state.api_info.socks_proxy_ipaddr = ipaddr;
+    sm->t_state.api_info.socks_proxy_port = port;
+}
+
+void
 TSHttpTxnUntransformedRespCache(TSHttpTxn txnp, int on)
 {
   sdk_assert(sdk_sanity_check_txn(txnp) == TS_SUCCESS);

diff -x '*.o' -ru tsorig/proxy/api/ts/ts.h.in tsgit217/proxy/api/ts/ts.h.in
--- tsorig/proxy/api/ts/ts.h.in    2011-03-09 21:43:58.000000000 +0000
+++ tsgit217/proxy/api/ts/ts.h.in    2011-03-17 15:43:04.000000000 +0000
@@ -2134,6 +2134,7 @@

    */
   tsapi void TSHttpTxnParentProxySet(TSHttpTxn txnp, char* hostname, int port);
+  tsapi void TSHttpTxnSocksProxySet(TSHttpTxn txnp, unsigned int ipaddr, int 
port);

   tsapi void TSHttpTxnUntransformedRespCache(TSHttpTxn txnp, int on);
   tsapi void TSHttpTxnTransformedRespCache(TSHttpTxn txnp, int on);

diff -x '*.o' -ru tsorig/proxy/http/HttpSM.cc tsgit217/proxy/http/HttpSM.cc
--- tsorig/proxy/http/HttpSM.cc    2011-03-09 21:43:58.000000000 +0000
+++ tsgit217/proxy/http/HttpSM.cc    2011-03-17 15:53:07.000000000 +0000
@@ -3658,6 +3658,7 @@
   // before we return from this function for forward proxy
   
t_state.pristine_url.create(t_state.hdr_info.client_request.url_get()->m_heap);
   t_state.pristine_url.copy(t_state.hdr_info.client_request.url_get());
+  Debug("url_rewrite", "URL is %s", t_state.pristine_url.string_get_ref(NULL));

   if (!ret) {
     Debug("url_rewrite", "Could not find a valid remapping entry for this 
request [%" PRId64 "]", sm_id);
@@ -4077,6 +4078,8 @@
     opt.addr_binding = NetVCOptions::FOREIGN_ADDR;
     opt.local_addr = t_state.client_info.ip;
   }
+  opt.socks_override.ip = t_state.api_info.socks_proxy_ipaddr;
+  opt.socks_override.port = t_state.api_info.socks_proxy_port;

   Debug("http", "[%" PRId64 "] open connection to %s: %u.%u.%u.%u",
         sm_id, t_state.current.server->name, 
PRINT_IP(t_state.current.server->ip));
@@ -4124,6 +4127,11 @@
   // to do this but as far I can tell the code that prevented keep-alive if
   // there is a request body has been removed.

+  //FIXME: We won't always be using from the shared connection pool. In the 
new architecture, the only time
+  //We don't need a new connection is in the case of chaining HTTP proxies. 
Otherwise the session manager
+  //Doesn't keep track of src IPs or SOCKS proxies.
+
+
   if (raw == false && t_state.http_config_param->share_server_sessions &&
       (t_state.txn_conf->keep_alive_post_out == 1 || 
t_state.hdr_info.request_content_length == 0) &&
       ua_session != NULL) {

diff -x '*.o' -ru tsorig/proxy/http/HttpTransact.h 
tsgit217/proxy/http/HttpTransact.h
--- tsorig/proxy/http/HttpTransact.h    2011-03-09 21:43:58.000000000 +0000
+++ tsgit217/proxy/http/HttpTransact.h    2011-03-17 15:39:05.000000000 +0000
@@ -317,6 +317,8 @@
 {
   char *parent_proxy_name;
   int parent_proxy_port;
+  unsigned int socks_proxy_ipaddr;
+  int socks_proxy_port;
   bool cache_untransformed;
   bool cache_transformed;
   bool logging_enabled;
@@ -325,6 +327,8 @@
   _HttpApiInfo()
   : parent_proxy_name(NULL),
     parent_proxy_port(-1),
+    socks_proxy_ipaddr(0),
+    socks_proxy_port(0),
     cache_untransformed(false), cache_transformed(true), 
logging_enabled(true), retry_intercept_failures(false)
   { }
 } HttpApiInfo; 


--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

Reply via email to