pidgin: 5fccbc91: Use asynchronous DNS lookups for SOCKS4.

datallah at pidgin.im datallah at pidgin.im
Tue Feb 17 18:45:41 EST 2009


-----------------------------------------------------------------
Revision: 5fccbc91b7d8a087792aa5892f7ccec28f74ff5c
Ancestor: c532f1f33308f836950c2354a240bdf0ee0cb820
Author: datallah at pidgin.im
Date: 2009-02-17T22:39:16
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/5fccbc91b7d8a087792aa5892f7ccec28f74ff5c

Modified files:
        libpurple/proxy.c

ChangeLog: 

Use asynchronous DNS lookups for SOCKS4.

-------------- next part --------------
============================================================
--- libpurple/proxy.c	112accff674b00f35bfa8e46e367930b98beb6cc
+++ libpurple/proxy.c	40fe4513a9c3a13c7a183fb8ae9f45847a2701b6
@@ -1177,25 +1177,74 @@ static void
 }
 
 static void
-s4_canwrite(gpointer data, gint source, PurpleInputCondition cond)
+s4_host_resolved(GSList *hosts, gpointer data, const char *error_message)
 {
+	PurpleProxyConnectData *connect_data = data;
 	unsigned char packet[9];
-	struct hostent *hp;
+	struct sockaddr *addr;
+
+	connect_data->query_data = NULL;
+
+	if (error_message != NULL) {
+		purple_proxy_connect_data_disconnect(connect_data, error_message);
+		return;
+	}
+
+	if (hosts == NULL) {
+		purple_proxy_connect_data_disconnect_formatted(connect_data,
+				_("Error resolving %s"), connect_data->host);
+		return;
+	}
+
+	/* Discard the length... */
+	hosts = g_slist_delete_link(hosts, hosts);
+	addr = hosts->data;
+	hosts = g_slist_delete_link(hosts, hosts);
+
+	packet[0] = 4;
+	packet[1] = 1;
+	packet[2] = connect_data->port >> 8;
+	packet[3] = connect_data->port & 0xff;
+	memcpy(packet + 4, &((struct sockaddr_in *)addr)->sin_addr.s_addr, 4);
+	packet[8] = 0;
+
+	g_free(addr);
+
+	/* We could try the other hosts, but hopefully that shouldn't be necessary */
+	while (hosts != NULL) {
+		/* Discard the length... */
+		hosts = g_slist_delete_link(hosts, hosts);
+		/* Free the address... */
+		g_free(hosts->data);
+		hosts = g_slist_delete_link(hosts, hosts);
+	}
+
+	connect_data->write_buffer = g_memdup(packet, sizeof(packet));
+	connect_data->write_buf_len = sizeof(packet);
+	connect_data->written_len = 0;
+	connect_data->read_cb = s4_canread;
+
+	connect_data->inpa = purple_input_add(connect_data->fd, PURPLE_INPUT_WRITE, proxy_do_write, connect_data);
+
+	proxy_do_write(connect_data, connect_data->fd, PURPLE_INPUT_WRITE);
+}
+
+static void
+s4_canwrite(gpointer data, gint source, PurpleInputCondition cond)
+{
 	PurpleProxyConnectData *connect_data = data;
 	int error = ETIMEDOUT;
 	int ret;
 
 	purple_debug_info("socks4 proxy", "Connected.\n");
 
-	if (connect_data->inpa > 0)
-	{
+	if (connect_data->inpa > 0) {
 		purple_input_remove(connect_data->inpa);
 		connect_data->inpa = 0;
 	}
 
 	ret = purple_input_get_error(connect_data->fd, &error);
-	if ((ret != 0) || (error != 0))
-	{
+	if ((ret != 0) || (error != 0)) {
 		if (ret != 0)
 			error = errno;
 		purple_proxy_connect_data_disconnect(connect_data, g_strerror(error));
@@ -1210,32 +1259,13 @@ s4_canwrite(gpointer data, gint source, 
 	 * with an option, or some detection mechanism - in the
 	 * meantime, stick with plain old SOCKS4.
 	 */
-	/* TODO: Use purple_dnsquery_a() */
-	hp = gethostbyname(connect_data->host);
-	if (hp == NULL) {
-		purple_proxy_connect_data_disconnect_formatted(connect_data,
-				_("Error resolving %s"), connect_data->host);
-		return;
-	}
+	connect_data->query_data = purple_dnsquery_a(connect_data->host,
+			connect_data->port, s4_host_resolved, connect_data);
 
-	packet[0] = 4;
-	packet[1] = 1;
-	packet[2] = connect_data->port >> 8;
-	packet[3] = connect_data->port & 0xff;
-	packet[4] = (unsigned char)(hp->h_addr_list[0])[0];
-	packet[5] = (unsigned char)(hp->h_addr_list[0])[1];
-	packet[6] = (unsigned char)(hp->h_addr_list[0])[2];
-	packet[7] = (unsigned char)(hp->h_addr_list[0])[3];
-	packet[8] = 0;
-
-	connect_data->write_buffer = g_memdup(packet, sizeof(packet));
-	connect_data->write_buf_len = sizeof(packet);
-	connect_data->written_len = 0;
-	connect_data->read_cb = s4_canread;
-
-	connect_data->inpa = purple_input_add(connect_data->fd, PURPLE_INPUT_WRITE, proxy_do_write, connect_data);
-
-	proxy_do_write(connect_data, connect_data->fd, cond);
+	if (connect_data->query_data == NULL) {
+		purple_debug_error("proxy", "dns query failed unexpectedly.\n");
+		purple_proxy_connect_data_destroy(connect_data);
+	}
 }
 
 static void


More information about the Commits mailing list