pidgin: 123a3369: Implement support for resolving DNS via ...

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


-----------------------------------------------------------------
Revision: 123a3369e1dd05078b2707f46de36749d4147153
Ancestor: 7b95d266242475641ead6d9fe3f42f92f23a5561
Author: datallah at pidgin.im
Date: 2009-02-17T23:42:49
Branch: im.pidgin.pidgin
URL: http://d.pidgin.im/viewmtn/revision/info/123a3369e1dd05078b2707f46de36749d4147153

Modified files:
        ChangeLog libpurple/proxy.c pidgin/gtkprefs.c

ChangeLog: 

Implement support for resolving DNS via the SOCKS4 proxy in use.
Currently this relies on a global preference, which I'm not super happy about.
Ideally, we'd just try to always do this and fall back to a local DNS lookup
when the SOCKS4 server doesn't like it, but I don't think we can reliably detect
that.
Fixes #3230

-------------- next part --------------
============================================================
--- ChangeLog	b78503cb75e7dafd8306dfb6ee654034a5d02e51
+++ ChangeLog	881f7ba20fff8530993a020ca7aac55de6548789
@@ -9,6 +9,7 @@ version 2.5.5 (??/??/????):
 	* Fix a memory leak in SILC. (Luke Petre)
 	* Fix some string handling in the SIMPLE prpl, which fixes some buddy name
 	  handling and other issues. (Paul Aurich, Marcus Sundberg)
+	* Implement support for resolving DNS via the SOCKS4 proxy (SOCKS4a).
 
 	ICQ:
 	* Fix retrieval of status messages from users of ICQ 6.x, Miranda, and
============================================================
--- libpurple/proxy.c	ba3356b2afd6c77022cc554507c6f62c6ffab979
+++ libpurple/proxy.c	3f2f991039a9b641d218dd052271d71bd9e5c8c3
@@ -1201,12 +1201,12 @@ s4_host_resolved(GSList *hosts, gpointer
 	addr = hosts->data;
 	hosts = g_slist_delete_link(hosts, hosts);
 
-	packet[0] = 4;
-	packet[1] = 1;
+	packet[0] = 0x04;
+	packet[1] = 0x01;
 	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;
+	packet[8] = 0x00;
 
 	g_free(addr);
 
@@ -1252,19 +1252,47 @@ s4_canwrite(gpointer data, gint source, 
 	}
 
 	/*
-	 * The socks4 spec doesn't include support for doing host name
-	 * lookups by the proxy.  Some socks4 servers do this via
-	 * extensions to the protocol.  Since we don't know if a
-	 * server supports this, it would need to be implemented
-	 * with an option, or some detection mechanism - in the
-	 * meantime, stick with plain old SOCKS4.
+	 * The socks4 spec doesn't include support for doing host name lookups by
+	 * the proxy.  Many socks4 servers do this via the "socks4a" extension to
+	 * the protocol.  There doesn't appear to be a way to detect if a server
+	 * supports this, so we require that the user set a global option.
 	 */
-	connect_data->query_data = purple_dnsquery_a(connect_data->host,
-			connect_data->port, s4_host_resolved, connect_data);
+	if (purple_prefs_get_bool("/purple/proxy/socks4_remotedns")) {
+		unsigned char packet[9];
+		int len;
 
-	if (connect_data->query_data == NULL) {
-		purple_debug_error("proxy", "dns query failed unexpectedly.\n");
-		purple_proxy_connect_data_destroy(connect_data);
+		purple_debug_info("socks4 proxy", "Attempting to use remote DNS.\n");
+
+		packet[0] = 0x04;
+		packet[1] = 0x01;
+		packet[2] = connect_data->port >> 8;
+		packet[3] = connect_data->port & 0xff;
+		packet[4] = 0x00;
+		packet[5] = 0x00;
+		packet[6] = 0x00;
+		packet[7] = 0x01;
+		packet[8] = 0x00;
+
+		len = sizeof(packet) + strlen(connect_data->host) + 1;
+
+		connect_data->write_buffer = g_malloc0(len);
+		memcpy(connect_data->write_buffer, packet, sizeof(packet));
+		memcpy(connect_data->write_buffer + sizeof(packet), connect_data->host, strlen(connect_data->host));
+		connect_data->write_buf_len = len;
+		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);
+	} else {
+		connect_data->query_data = purple_dnsquery_a(connect_data->host,
+				connect_data->port, s4_host_resolved, connect_data);
+
+		if (connect_data->query_data == NULL) {
+			purple_debug_error("proxy", "dns query failed unexpectedly.\n");
+			purple_proxy_connect_data_destroy(connect_data);
+		}
 	}
 }
 
@@ -2323,6 +2351,7 @@ purple_proxy_init(void)
 	purple_prefs_add_int("/purple/proxy/port", 0);
 	purple_prefs_add_string("/purple/proxy/username", "");
 	purple_prefs_add_string("/purple/proxy/password", "");
+	purple_prefs_add_bool("/purple/proxy/socks4_remotedns", FALSE);
 
 	/* Setup callbacks for the preferences. */
 	handle = purple_proxy_get_handle();
============================================================
--- pidgin/gtkprefs.c	b27d0c6926a626ec324e79c95bb565bde83a8023
+++ pidgin/gtkprefs.c	cfa7fc8369cb73d6f3f887fcd79046b7b1e765d2
@@ -1342,6 +1342,10 @@ network_page(void)
 		purple_prefs_connect_callback(prefs, "/purple/proxy/type",
 					    proxy_changed_cb, prefs_proxy_frame);
 
+		/* This is a global option that affects SOCKS4 usage even with account-specific proxy settings */
+		pidgin_prefs_checkbox(_("Use remote DNS with SOCKS4 proxies"),
+							  "/purple/proxy/socks4_remotedns", prefs_proxy_frame);
+
 		table = gtk_table_new(4, 2, FALSE);
 		gtk_container_set_border_width(GTK_CONTAINER(table), 0);
 		gtk_table_set_col_spacings(GTK_TABLE(table), 5);


More information about the Commits mailing list