#759125 tsocks: racey non-blocking connect() + sendto() skips SOCKS connect

Package:
tsocks
Source:
tsocks
Description:
transparent network access through a SOCKS 4 or 5 proxy
Submitter:
Alexander Clouter
Date:
2014-08-24 16:09:06 UTC
Severity:
normal
#759125#5
Date:
2014-08-24 15:25:41 UTC
From:
To:
Dear Maintainer,

Found that I could not use 'user mode' of qemu with tsocks (although I could
use proxychains) and so did some digging; proxychains does not support
specifying subnets to bypass a SOCKS server to so does not suit my needs.

Turns out qemu uses a non-blocking connect, and then always starts off
using the socket immediately with sendto("");sendto("....").  As tsocks has
not yet sent the SOCKS request header, my 'ssh -D 1080 ...' gets very annoyed
very quickly :)
----
[pid 23463] connect(46, {sa_family=AF_INET, sin_port=htons(1080), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress)
[pid 23463] sendto(46, "", 0, 0, NULL, 0) = 0
[pid 23463] sendto(46, "GET /ncsi.txt HTTP/1.1\r\nConnecti"..., 97, 0, NULL, 0) = 97
[pid 23463] recvfrom(46, "", 8760, 0, NULL, NULL) = 0
[pid 23463] shutdown(46, 0 /* receive */) = 0
[pid 23463] shutdown(46, 1 /* send */)  = 0
----

The fix is to force the socket to connect() blocking (turns out peeking in
the proxychains source, they do just this).

The attached patch takes the ifdef 0'd lines at the end and splices them
into the connect_server() where I suspect they used to live a while back.

Now, 'TSOCKS_CONNECT_BLOCKING=1 tsocks qemu -net user ...' works great! :)
----
[pid 23488] connect(47, {sa_family=AF_INET, sin_port=htons(1080), sin_addr=inet_addr("127.0.0.1")}, 16) = 0
[pid 23488] sendto(47, "\5\2\0\2", 4, 0, NULL, 0) = 4
[pid 23488] recvfrom(47, "\5\0", 2, 0, NULL, NULL) = 2
[pid 23488] sendto(47, "\5\1\0\1\27?cj\0P", 10, 0, NULL, 0) = 10
[pid 23488] recvfrom(47, 0x7fd4c8897668, 10, 0, 0, 0) = -1 EAGAIN (Resource temporarily unavailable)
[pid 23488] sendto(47, "", 0, 0, NULL, 0) = 0
[pid 23488] sendto(47, "GET /ncsi.txt HTTP/1.1\r\nConnecti"..., 97, 0, NULL, 0) = 97
[pid 23488] recvfrom(47, "\5\0\0\1\0\0\0\0\0\0", 8760, 0, NULL, NULL) = 10
[pid 23488] shutdown(47, 1 /* send */)  = 0
[pid 23488] recvfrom(47, "HTTP/1.1 200 OK\r\nContent-Length:"..., 8750, 0, NULL, NULL) = 179
[pid 23488] recvfrom(47, "", 7300, 0, NULL, NULL) = 0
[pid 23488] shutdown(47, 0 /* receive */) = -1 ENOTCONN (Transport endpoint is not connected)
----