Proposal: Prioritizing local traffic over relayed traffic

Roger Dingledine arma at
Fri Mar 16 03:43:34 UTC 2007

On Wed, Mar 14, 2007 at 06:22:37PM -0400, Roger Dingledine wrote:
>   Option 2: build separate TCP connections for local traffic and for
>   relayed traffic. In practice this will actually only require a few
>   extra TCP connections: we would only need redundant TCP connections
>   to at most the number of entry guards in use.
>   However, this approach has some drawbacks. First, if the remote side
>   wants to extend a circuit to you, how does it know which TCP connection
>   to send it on? We would need some extra scheme to label some connections
>   "client-only" during construction. Perhaps we could do this by seeing
>   whether any circuit was made via CREATE_FAST; but this still opens
>   up a race condition where the other side sends a create request
>   immediately. The only ways I can imagine to avoid the race entirely
>   are to specify our preference in the VERSIONS cell, or to add some
>   sort of "nope, not this connection, why don't you try another rather
>   than failing" response to create cells, or to forbid create cells on
>   connections that you didn't initiate and on which you haven't seen
>   any circuit creation requests yet -- this last one would lead to a bit
>   more connection bloat but doesn't seem so bad. And we already accept
>   this race for the case where directory authorities establish new TCP
>   connections periodically to check reachability, and then hope to hang
>   up on them soon after. (In any case this issue is moot for bridges,
>   since each destination will be one-way with respect to extend requests:
>   either receiving extend requests from bridge users or sending extend
>   requests to the Tor server, never both.)

A cleaner way to solve this issue would be to not provide your identity
key during the TLS handshake for the "local traffic" connections. Then
there's no worry that the remote side will try to send create cells over
it -- he doesn't even know for sure that it's you.

For servers running or later, we can implement this by just
not sending any certificates. We could leave it at that, and this feature
would slowly become more effective as the network upgrades. Alas, that
approach conflicts with proposal 105, since not sending any certs will
be equivalent to claiming to support link and circuit versions 2.

Another option so we don't have to wait for proposal 105 would be to
maintain two TLS contexts, and use one or the other depending. This
is a bit of a hassle since src/common/tortls.c keeps all its state
internally. But we could add arguments to those functions (specifically,
tor_tls_context_new and tor_tls_new, and that's it) to say "now I'm
talking about the client context" or "now I'm talking about the server
context", and it can keep two internally. That seems pretty easy actually.

> [Not writing the rest of the proposal until we sort out which option
> we'll take.]

Just to make things more complex... where do directory fetches fit into
this? If you're fetching a hidden service descriptor, you want it to
count as local traffic, but that's already solved because you do it
using your local Tor connections. If you're fetching the v1 directory
so you can cache it for somebody else, or indeed serving any dir info,
that's relayed traffic. What about fetching v2 dir info? If you make
an encrypted dir connection so you can use begin_dir, do you need to
make a separate "local traffic" connection?

The easy answer is to put all directory activity into the "relayed
traffic" category. But what if we're acting as a bridge and limiting
relayed traffic to 10KB/s? It will take a long time to pull down directory
info, making *your* Tor activity suffer; plus your bridge users will be
sad while you're doing it.

The better option is to consider all locally initiated directory
connections to be local traffic. If the user wants to enforce rate
limiting even for these connections, then he can put a limit on the
"local traffic" bucket. This may cause more duplicate TCP connections at
first, if we're doing encrypted begin_dir's to arbitrary servers; but
when we get around to implementing directory guards that concern will
become mostly moot. If necessary, down the road we can add a third rate
limiting bucket, specifically for locally initiated directory connections
-- but let's not tackle that until it becomes clear that we need to.


More information about the tor-dev mailing list