[tor-dev] Torsocks development status

Matthew Finkel matthew.finkel at gmail.com
Thu Jun 27 21:29:57 UTC 2013

On Thu, Jun 27, 2013 at 03:11:23PM -0400, David Goulet wrote:
> Ian Goldberg:
> > Are non-blocking sockets, select/poll/etc. (especially at connect()
> > time), and optimistic data on the to-do list?
> Yes! Good point I should have put the todo list. So yes, non block socket support.
> For optimistic data, it is kind of tricky.

It definitely is tricky. You just need to find the best way to have
torsocks return the least untrue response that's allowed by the OS. I'm
not going to reiterate what Ian said, but I'll just make some points
about what I did.

> I can use it for DNS resolution
> without a problem because torsocks control the complete flow of data from
> opening a SOCKS5 connection to closing it after the DNS response is received
> however for actual real data (sendmsg, send, ...) a connect is needed before so
> it would means that a connect() call will return "yes OK socket connected" but
> where in fact it is not really true. So, when the first data are sent, there is
> a possibility that the Tor connections failed or even we block for an unknown
> amount of time during the send*/write() call.

Yup, this is exactly the case (in addition to SOCKS4/A also).

> Now the question is, is this the kind of behavior that would be acceptable
> meaning basically lying to the caller at connect() and possibly blocking I/O
> calls and returning something like ECONNRESET or ENOTCONN if the Tor socks5
> connection fails.

The main problem I foresee with this is when torsocks wraps a program that
does not fully implement error handling or does not implement it
correctly. And, to be honest, I don't think you can let potentially
faulty programs influence the features of *your* program (too much).

For what it's worth, I returned ENOTCONN and EBADF, but I think ENOTCONN
is the most descriptive, I'm just not sure most programs check for it
after a send()/write().

> This is *real* tricky especially with non blocking socket, if torsocks needs to
> do some possible blocking call for the SOCKS5 replies during an I/O call from
> the caller that is not suppose to block. Furthermore, having pending data that
> *might* come at any time on the connection from the SOCKS5 negotiation, the
> caller could put the file descriptor in poll() mode, wake up and try to receive
> the data but where in fact it's the socks5 reply... it's possible to handle that
> but it seems here a VERY intrusive behavior. Does optimistic data worth it here
> vis-a-vis the complexity of handling that it and high intrusiveness ?

Well, you actually have more guarantees than you may think (unless I
misunderstand you). You know torsocks will send the SOCKS5/4{,A) request
and you know that before torsocks returns anything to the client
application, torsocks *must* receive a response from Tor regarding the
success or failure of establishing the proxy connection. As such, if you
receive optdata from the client app and pass it to Tor which then will
pass it to the endpoint (if possible), you know Tor *must* return a
SOCKS reply *before* you receive any client data, so you simply read
that off the buffer and then handle the connection in an appropriate
manner. Simple. :)

Regarding poll(), torsocks really needs to wrap the multiplexing I/O
syscalls ({p,}poll, {p,}select, epoll, kqueue, etc) or else you will
run into some major problems (select() and poll() being much more
important than the others). This is intrusive, but it's only a single
write request (for all values of "write").

Personally, I think the most important feature of the optdata
implementation is that you make it configurable. 

> Cheers!
> David
> > 
> > Thanks,
> > 
> >    - Ian

- Matt

More information about the tor-dev mailing list