[tor-dev] Optimistic SOCKS Data

Matthew Finkel matthew.finkel at gmail.com
Tue Oct 15 15:17:54 UTC 2019

On Fri, Oct 11, 2019 at 6:30 AM Tom Ritter <tom at ritter.vg> wrote:
> On Thu, 10 Oct 2019 at 10:37, George Kadianakis <desnacked at riseup.net> wrote:
> > So are you suggesting that we can still do SOCKS error codes? But as
> > David said, some of the errors we care about are after the descriptor
> > fetch, so how would we do those?
> Only 'X'F3' Onion Service Rendezvous Failed' - right?


> I think David is proposing we just don't do that one because in his
> experience it's pretty rare.
> > Also, please help me understand the race condition you refer to. I tried
> > to draw this in a diagram form:
> >       https://gist.github.com/asn-d6/55fbe7a3d746dc7e00da25d3ce90268a
> I edited this:
> https://gist.github.com/tomrittervg/e0552ed007dbe50077528936b09a2eff
> Whose first diagram (normal situation) is correct?  Something looks
> off in yours... You obviously know tor much better; but latency gain
> for optimistic socks doesn't come from sending the HTTP GET to tor
> sooner, it comes from sending it to the destination sooner - so I
> think that the GET must travel to the destination before the
> destination replies with CONNECTED, doesn't it?

I think Tom's diagram is correct. We're worried about: "Does the
application send the "HTTP GET" bytes before or after tor sends the
RELAY_BEGIN relay cell?" If the application payload arrives before the
RELAY_BEGIN command is sent, then we can send optimistic data --else
we can't. The remaining (open) question is *when* do we send the
application "FAKE SUCCESSFUL SOCKS REPLY". If we send it after
receiving an INTRODUCE_ACK command relay cell, then the application
will almost certainly win the race but it must watch the controller
events for a rendezvous failure. If we send the "fake success socks
reply" after receiving a RENDEZVOUS2 command relay cell, then the
application will likely lose the race because tor will immediately
attach the stream on the circuit and send a RELAY_BEGIN relay cell
(and the application payload will arrive after the stream is

The optimistic data simply saves us time. The race condition only
exists on the client-side. The application's payload (via optimistic
data) doesn't need to reach the service-side tor client before the
service-side replies with the CONNECTED relay cell. If the rendezvous
circuit is established and the stream is attached, then the
application on the service-side will receive the client-side's payload
and handle it normally.

The main advantage of optimistic data is that we don't wait the full
round-trip time. The RELAY_DATA relay cell is sent immediately after
the RELAY_BEGIN relay cell, so it is already in-flight when the stream
is connected. When this fails, then (I believe) the rendezvous circuit
should be destroyed and the client application's connection with the
SocksPort is closed. This is where we need the unique ID, so we can
correlate the error message from the controller event with the closed
TCP connection. I believe Mark and/or Kathy mentioned how handling
this error case in Tor Browser will be difficult, because the
controller error message may be emitted after Tor Browser handles the
closed connection.

More information about the tor-dev mailing list