As more Tor exit nodes start supporting IPv6, I have been seeing
connections failures in polipo when it is configured to talk
to a tor server over socks5.  My initial work-around was to
downgrade to using socks4a in the polipo configuration, but I
was motivated today to further track down the problem.

The issue resolves to the fact that socks.c:socks5ReadHandler2()
explicitly checks the response type, and only accepts (and ignores
the content of) IPv4 responses from the upstream socks5 server.
Attached is a patch which fixes this to accept (and ignore the
content of) IPv6 responses as well.

This patch "works for me" in testing against both IPv4 and IPv6
destinations, though I haven't examined the code carefully
enough to be certain that my "request 22" in the do_stream()
call is really legitimate (an IPv4 response will be length 10,
and an IPv6 response will be length 22).  If I've just been lucky
and this really isn't appropriate, then the proper fix would be
to read the response in two chunks: first the four-byte prefix,
then based on the contents of request->buf[3], either 6 more
bytes for IPv4 or 18 more bytes for IPv6.

To be fully robust, it might be good to also handle the
request->buf[3] == 3 case.  The simplest way, if it is safe to
call do_stream() with an excess length (during this socks set-up
phase), is to call do_stream() with a request length of 261,
and then add any deisred sanity checks (and a break) to "case 3"
in the switch.  On the other hand, I didn't bother coding it
because I can't test this case, as I don't have (nor know of)
a socks5 server which gives domainname responses.  So unless
someone else knows of a server to test against it may be best
to leave this case as I have it: stubbed with a comment.

HTH,
                --Ken Pizzini
diff -ru polipo-1.1.1/socks.c polipo-1.1.1-ipv6socks5fix/socks.c
--- polipo-1.1.1/socks.c	2014-05-14 15:19:43.000000000 -0700
+++ polipo-1.1.1-ipv6socks5fix/socks.c	2015-01-14 15:19:56.472560145 -0800
@@ -458,7 +458,7 @@
         return 0;
     }
 
-    do_stream(IO_READ | IO_NOTNOW, request->fd, 0, request->buf, 10,
+    do_stream(IO_READ | IO_NOTNOW, request->fd, 0, request->buf, 22,
               socks5ReadHandler2, request);
     return 1;
 
@@ -496,13 +496,21 @@
         goto error;
     }
 
-    if(request->buf[3] != 1) {
-        status = -ESOCKS_PROTOCOL;
-        goto error;
+    switch (request->buf[3]) {
+	case 1: /* ipv4 */
+	    if (srequest->offset < 10)
+		return 0;
+	    break;
+	case 4: /* ipv6 */
+	    if (srequest->offset < 22)
+		return 0;
+	    break;
+	case 3: /* domainname -- not currently supported */
+	default:
+	    status = -ESOCKS_PROTOCOL;
+	    goto error;
     }
 
-    if(srequest->offset < 10)
-        return 0;
 
     request->handler(1, request);
     destroySocksRequest(request);
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
_______________________________________________
Polipo-users mailing list
Polipo-users@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/polipo-users

Reply via email to