# HG changeset patch # User Daniel Atallah # Date 1304398637 0 # Node ID b9f58c31afc7e2c237ebed7de99f4d490560e350 # Parent db082e0421f6d161e3cfff6356127666fd70cd68 proxy: Use account proxy when making standalone SOCKS5 connections. This ends up being potentially weird in that you may end up tunnelling a SOCKS5 proxy connection though another SOCKS5 proxy. It may mean that non-IBB file xmpp transfers work more consistently on restricted networks, but may make the situation worse some situations e.g. when a proxy is required to connect to the xmpp server, but you want to send a file to someone on your local network. What it does do though is to allow you to prevent the streamhost from knowing where you're connecting from. Fixes #13928 diff -r db082e0421f6 -r b9f58c31afc7 libpurple/proxy.c --- a/libpurple/proxy.c Tue May 03 02:26:35 2011 +0000 +++ b/libpurple/proxy.c Tue May 03 04:57:17 2011 +0000 @@ -2397,9 +2397,6 @@ return connect_data; } -/* - * Combine some of this code with purple_proxy_connect() - */ PurpleProxyConnectData * purple_proxy_connect_socks5(void *handle, PurpleProxyInfo *gpi, const char *host, int port, @@ -2409,6 +2406,42 @@ return purple_proxy_connect_socks5_account(NULL, handle, gpi, host, port, connect_cb, data); } + + +/* This is called when we connect to the SOCKS5 proxy server (through any + * relevant account proxy) + */ +static void socks5_connected_to_proxy(gpointer data, gint source, + const gchar *error_message) { + /* This is the PurpleProxyConnectData for the overall SOCKS5 connection */ + PurpleProxyConnectData *connect_data = data; + + /* Check that the overall SOCKS5 connection wasn't cancelled while we were + * connecting to it (we don't have a way of associating the process of + * connecting to the SOCKS5 server to the overall PurpleProxyConnectData) + */ + if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data)) + return; + + if (error_message != NULL) { + purple_debug_error("proxy", "Unable to connect to SOCKS5 host.\n"); + connect_data->connect_cb(connect_data->data, source, error_message); + return; + } + + purple_debug_info("proxy", "Initiating SOCKS5 negotiation.\n"); + + purple_debug_info("proxy", + "Connecting to %s:%d via %s:%d using SOCKS5\n", + connect_data->host, connect_data->port, + purple_proxy_info_get_host(connect_data->gpi), + purple_proxy_info_get_port(connect_data->gpi)); + + connect_data->fd = source; + + s5_canwrite(connect_data, connect_data->fd, PURPLE_INPUT_WRITE); +} + /* * Combine some of this code with purple_proxy_connect() */ @@ -2420,6 +2453,7 @@ gpointer data) { PurpleProxyConnectData *connect_data; + PurpleProxyConnectData *account_proxy_conn_data; g_return_val_if_fail(host != NULL, NULL); g_return_val_if_fail(port >= 0, NULL); @@ -2436,17 +2470,26 @@ connect_data->gpi = gpi; connect_data->account = account; - connect_data->query_data = - purple_dnsquery_a_account(account, - purple_proxy_info_get_host(gpi), - purple_proxy_info_get_port(gpi), - connection_host_resolved, connect_data); - if (connect_data->query_data == NULL) - { + /* If there is an account proxy, use it to connect to the desired SOCKS5 + * proxy. + */ + account_proxy_conn_data = purple_proxy_connect(connect_data->handle, + connect_data->account, + purple_proxy_info_get_host(connect_data->gpi), + purple_proxy_info_get_port(connect_data->gpi), + socks5_connected_to_proxy, connect_data); + + if (account_proxy_conn_data == NULL) { + purple_debug_error("proxy", "Unable to initiate connection to account proxy.\n"); purple_proxy_connect_data_destroy(connect_data); return NULL; } + /* The API doesn't really provide us with a way to cancel the specific + * proxy connection attempt (account_proxy_conn_data) when the overall + * SOCKS5 connection (connect_data) attempt is cancelled :( + */ + handles = g_slist_prepend(handles, connect_data); return connect_data; diff -r db082e0421f6 -r b9f58c31afc7 libpurple/proxy.h --- a/libpurple/proxy.h Tue May 03 02:26:35 2011 +0000 +++ b/libpurple/proxy.h Tue May 03 04:57:17 2011 +0000 @@ -289,11 +289,15 @@ /** * Makes a connection through a SOCKS5 proxy. * + * Note that if the account that is making the connection uses a proxy, this + * connection to a SOCKS5 proxy will be made through the account proxy. + * * @param handle A handle that should be associated with this * connection attempt. The handle can be used * to cancel the connection attempt using the * purple_proxy_connect_cancel_with_handle() * function. + * @param account The account making the connection. * @param gpi The PurpleProxyInfo specifying the proxy settings * @param host The destination host. * @param port The destination port.