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