pidgin: 4058cef5: Add purple_proxy_connect_udp. Closes #65...
darkrain42 at pidgin.im
darkrain42 at pidgin.im
Thu Jun 4 22:00:40 EDT 2009
-----------------------------------------------------------------
Revision: 4058cef57f6b327fdd64981adbfe7ec8e908f401
Ancestor: 225731be6a8e7a03701b0a50700348baa07afb3f
Author: ccpaging at pidgin.im
Date: 2009-06-05T01:58:22
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/4058cef57f6b327fdd64981adbfe7ec8e908f401
Modified files:
ChangeLog.API libpurple/proxy.c libpurple/proxy.h
ChangeLog:
Add purple_proxy_connect_udp. Closes #6589.
Patch from ccpaging with two modifications by me:
* Connections are attempted when a proxy is set (bypassing proxy). A note is logged about this.
* Change the type of socket_type to int.
-------------- next part --------------
============================================================
--- ChangeLog.API 6f29af39ec81834a8433f7473785276404c6e347
+++ ChangeLog.API 79e09249a8b42ff533c297e574fe20d0376a29ea
@@ -42,6 +42,7 @@ version 2.6.0 (??/??/2009):
* purple_network_set_turn_server
* purple_network_get_stun_ip
* purple_network_get_turn_ip
+ * purple_proxy_connect_udp
* purple_prpl_get_media_caps
* purple_prpl_got_account_actions
* purple_prpl_initiate_media
============================================================
--- libpurple/proxy.c 3e24bcdd87bc059b59f2775b2460aa687aa76a9c
+++ libpurple/proxy.c 895e29e05d6a3de70a21248e005918a221174f24
@@ -47,6 +47,7 @@ struct _PurpleProxyConnectData {
gchar *host;
int port;
int fd;
+ int socket_type;
guint inpa;
PurpleProxyInfo *gpi;
PurpleDnsQueryData *query_data;
@@ -676,6 +677,68 @@ static void
}
static void
+proxy_connect_udp_none(PurpleProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen)
+{
+ int flags;
+
+ purple_debug_info("proxy", "UDP Connecting to %s:%d with no proxy\n",
+ connect_data->host, connect_data->port);
+
+ connect_data->fd = socket(addr->sa_family, SOCK_DGRAM, 0);
+ if (connect_data->fd < 0)
+ {
+ purple_proxy_connect_data_disconnect_formatted(connect_data,
+ _("Unable to create socket:\n%s"), g_strerror(errno));
+ return;
+ }
+
+ flags = fcntl(connect_data->fd, F_GETFL);
+ fcntl(connect_data->fd, F_SETFL, flags | O_NONBLOCK);
+#ifndef _WIN32
+ fcntl(connect_data->fd, F_SETFD, FD_CLOEXEC);
+#endif
+
+ if (connect(connect_data->fd, addr, addrlen) != 0)
+ {
+ if ((errno == EINPROGRESS) || (errno == EINTR))
+ {
+ purple_debug_info("proxy", "UDP Connection in progress\n");
+ connect_data->inpa = purple_input_add(connect_data->fd,
+ PURPLE_INPUT_WRITE, socket_ready_cb, connect_data);
+ }
+ else
+ {
+ purple_proxy_connect_data_disconnect(connect_data, g_strerror(errno));
+ }
+ }
+ else
+ {
+ /*
+ * The connection happened IMMEDIATELY... strange, but whatever.
+ */
+ int error = ETIMEDOUT;
+ int ret;
+
+ purple_debug_info("proxy", "UDP Connected immediately.\n");
+
+ ret = purple_input_get_error(connect_data->fd, &error);
+ if ((ret != 0) || (error != 0))
+ {
+ if (ret != 0)
+ error = errno;
+ purple_proxy_connect_data_disconnect(connect_data, g_strerror(error));
+ return;
+ }
+
+ /*
+ * We want to call the "connected" callback eventually, but we
+ * don't want to call it before we return, just in case.
+ */
+ purple_timeout_add(10, clean_connect, connect_data);
+ }
+}
+
+static void
proxy_connect_none(PurpleProxyConnectData *connect_data, struct sockaddr *addr, socklen_t addrlen)
{
int flags;
@@ -2042,6 +2105,12 @@ static void try_connect(PurpleProxyConne
#endif
purple_debug_info("proxy", "Attempting connection to %s\n", ipaddr);
+ if (connect_data->socket_type == SOCK_DGRAM) {
+ proxy_connect_udp_none(connect_data, addr, addrlen);
+ g_free(addr);
+ return;
+ }
+
switch (purple_proxy_info_get_type(connect_data->gpi)) {
case PURPLE_PROXY_NONE:
proxy_connect_none(connect_data, addr, addrlen);
@@ -2193,6 +2262,7 @@ purple_proxy_connect(void *handle, Purpl
connect_data = g_new0(PurpleProxyConnectData, 1);
connect_data->fd = -1;
+ connect_data->socket_type = SOCK_STREAM;
connect_data->handle = handle;
connect_data->connect_cb = connect_cb;
connect_data->data = data;
@@ -2243,6 +2313,71 @@ purple_proxy_connect(void *handle, Purpl
return connect_data;
}
+PurpleProxyConnectData *
+purple_proxy_connect_udp(void *handle, PurpleAccount *account,
+ const char *host, int port,
+ PurpleProxyConnectFunction connect_cb, gpointer data)
+{
+ const char *connecthost = host;
+ int connectport = port;
+ PurpleProxyConnectData *connect_data;
+
+ g_return_val_if_fail(host != NULL, NULL);
+ g_return_val_if_fail(port > 0, NULL);
+ g_return_val_if_fail(connect_cb != NULL, NULL);
+
+ connect_data = g_new0(PurpleProxyConnectData, 1);
+ connect_data->fd = -1;
+ connect_data->socket_type = SOCK_DGRAM;
+ connect_data->handle = handle;
+ connect_data->connect_cb = connect_cb;
+ connect_data->data = data;
+ connect_data->host = g_strdup(host);
+ connect_data->port = port;
+ connect_data->gpi = purple_proxy_get_setup(account);
+
+ if ((purple_proxy_info_get_type(connect_data->gpi) != PURPLE_PROXY_NONE) &&
+ (purple_proxy_info_get_host(connect_data->gpi) == NULL ||
+ purple_proxy_info_get_port(connect_data->gpi) <= 0)) {
+
+ purple_notify_error(NULL, NULL, _("Invalid proxy settings"), _("Either the host name or port number specified for your given proxy type is invalid."));
+ purple_proxy_connect_data_destroy(connect_data);
+ return NULL;
+ }
+
+ switch (purple_proxy_info_get_type(connect_data->gpi))
+ {
+ case PURPLE_PROXY_NONE:
+ break;
+
+ case PURPLE_PROXY_HTTP:
+ case PURPLE_PROXY_SOCKS4:
+ case PURPLE_PROXY_SOCKS5:
+ case PURPLE_PROXY_USE_ENVVAR:
+ purple_debug_info("proxy", "Ignoring Proxy type (%d) for UDP.\n",
+ purple_proxy_info_get_type(connect_data->gpi));
+ break;
+
+ default:
+ purple_debug_error("proxy", "Invalid Proxy type (%d) specified.\n",
+ purple_proxy_info_get_type(connect_data->gpi));
+ purple_proxy_connect_data_destroy(connect_data);
+ return NULL;
+ }
+
+ connect_data->query_data = purple_dnsquery_a(connecthost,
+ connectport, connection_host_resolved, connect_data);
+ if (connect_data->query_data == NULL)
+ {
+ purple_proxy_connect_data_destroy(connect_data);
+ return NULL;
+ }
+
+ handles = g_slist_prepend(handles, connect_data);
+
+ return connect_data;
+}
+
/*
* Combine some of this code with purple_proxy_connect()
*/
@@ -2260,6 +2395,7 @@ purple_proxy_connect_socks5(void *handle
connect_data = g_new0(PurpleProxyConnectData, 1);
connect_data->fd = -1;
+ connect_data->socket_type = SOCK_STREAM;
connect_data->handle = handle;
connect_data->connect_cb = connect_cb;
connect_data->data = data;
============================================================
--- libpurple/proxy.h dedab01a064de80b7c38d46c8625a9b25da78cd9
+++ libpurple/proxy.h a82a819d623ff893bd273b9d6a717c948fc0e896
@@ -257,6 +257,35 @@ PurpleProxyConnectData *purple_proxy_con
PurpleProxyConnectFunction connect_cb, gpointer data);
/**
+ * Makes a connection to the specified host and port. Note that this
+ * function name can be misleading--although it is called "proxy
+ * connect," it is used for establishing any outgoing UDP connection,
+ * whether through a proxy or not.
+ *
+ * @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 host The destination host.
+ * @param port The destination port.
+ * @param connect_cb The function to call when the connection is
+ * established. If the connection failed then
+ * fd will be -1 and error message will be set
+ * to something descriptive (hopefully).
+ * @param data User-defined data.
+ *
+ * @return NULL if there was an error, or a reference to an
+ * opaque data structure that can be used to cancel
+ * the pending connection, if needed.
+ */
+PurpleProxyConnectData *purple_proxy_connect_udp(void *handle,
+ PurpleAccount *account,
+ const char *host, int port,
+ PurpleProxyConnectFunction connect_cb, gpointer data);
+
+/**
* Makes a connection through a SOCKS5 proxy.
*
* @param handle A handle that should be associated with this
More information about the Commits
mailing list