You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@trafficserver.apache.org by mark <mn...@haskalah.org> on 2011/03/18 13:27:00 UTC

set SOCKS proxy via API

I've tried to implement an API which would allow a plugin to set a SOCKS 
proxy per-txn. It might be a bit sloppy, but it seems to work:

Leif has suggested that I used a struct sockaddr_storage (or something 
like that) instead of an unsigned int for the IP. Also, I can't figure 
out how to set the timeout properly for the socks connection. It's 
hard-coded to five seconds.

Nevertheless, it's a proof-of-concept.

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;