<div class="gmail_quote">I&#39;m sure you&#39;ve thought of this, but adversaries can replicate any<br>
properties we&#39;re looking for to rate limit. In this case simply making<br>
yourself a slow relay and routing client traffic through yourself<br>
(being your own first hop) seems to get around the limitation. -Damian<br>
<div><div></div><div class="h5"><br>
On Sun, Dec 13, 2009 at 5:23 PM, Roger Dingledine &lt;<a href="mailto:arma@mit.edu">arma@mit.edu</a>&gt; wrote:<br>
&gt; Hi folks (Nick in particular),<br>
&gt;<br>
&gt; I&#39;ve been pondering other performance improvements. One of them is to<br>
&gt; rate-limit client connections as they enter the network. Rate limiting<br>
&gt; in the Tor client itself would work better, but it&#39;s not a very stable<br>
&gt; equilibrium -- it encourages people to switch to security disasters<br>
&gt; like tortunnel.<br>
&gt;<br>
&gt; So I&#39;m looking at rate-limiting non-relay OR connections. Here&#39;s the<br>
&gt; patch:<br>
&gt;<br>
&gt; diff --git a/src/or/connection_or.c b/src/or/connection_or.c<br>
&gt; index aa26bf8..3f984bf 100644<br>
&gt; --- a/src/or/connection_or.c<br>
&gt; +++ b/src/or/connection_or.c<br>
&gt; @@ -333,10 +333,24 @@ connection_or_init_conn_from_address(or_connection_t *conn<br>
&gt; ,<br>
&gt;  {<br>
&gt;   or_options_t *options = get_options();<br>
&gt;   routerinfo_t *r = router_get_by_digest(id_digest);<br>
&gt; -  conn-&gt;bandwidthrate = (int)options-&gt;BandwidthRate;<br>
&gt; -  conn-&gt;read_bucket = conn-&gt;bandwidthburst = (int)options-&gt;BandwidthBurst;<br>
&gt;   connection_or_set_identity_digest(conn, id_digest);<br>
&gt;<br>
&gt; +  if (r || router_get_consensus_status_by_id(id_digest)) {<br>
&gt; +    /* It&#39;s in the consensus, or we have a descriptor for it meaning it<br>
&gt; +     * was probably in a recent consensus. It&#39;s a recognized relay:<br>
&gt; +     * give it full bandwidth. */<br>
&gt; +    conn-&gt;bandwidthrate = (int)options-&gt;BandwidthRate;<br>
&gt; +    conn-&gt;read_bucket = conn-&gt;bandwidthburst = (int)options-&gt;BandwidthBurst;<br>
&gt; +  } else { /* Not a recognized relay. Squeeze it down based on the<br>
&gt; +            * suggested bandwidth parameters in the consensus. */<br>
&gt; +    conn-&gt;bandwidthrate =<br>
&gt; +      (int)networkstatus_get_param(NULL, &quot;bwconnrate&quot;,<br>
&gt; +                                   (int)options-&gt;BandwidthRate);<br>
&gt; +    conn-&gt;read_bucket = conn-&gt;bandwidthburst =<br>
&gt; +      (int)networkstatus_get_param(NULL, &quot;bwconnburst&quot;,<br>
&gt; +                                   (int)options-&gt;BandwidthBurst);<br>
&gt; +  }<br>
&gt; +<br>
&gt;   conn-&gt;_base.port = port;<br>
&gt;   tor_addr_copy(&amp;conn-&gt;_base.addr, addr);<br>
&gt;   tor_addr_copy(&amp;conn-&gt;real_addr, addr);<br>
&gt;<br>
&gt; As you can see, I&#39;m making it configurable inside the consensus, so we<br>
&gt; can experiment with it rather than rolling it out and then changing our<br>
&gt; minds later. I don&#39;t have a good sense of whether it will be a good move,<br>
&gt; but the only way I can imagine to find out is to try it.<br>
&gt;<br>
&gt; I&#39;m imagining trying it out with a rate of 20KB and a burst of 500KB.<br>
&gt;<br>
&gt; As a nice side effect, we&#39;ll also be rolling out the infrastructure for<br>
&gt; one defense against Sambuddho&#39;s &quot;approximating a global passive adversary&quot;<br>
&gt; congestion attack, if the attack ever gets precise enough that we can<br>
&gt; try out our defense and compare.<br>
&gt;<br>
&gt; In the distant future, where we&#39;ve deployed a design where not all relays<br>
&gt; get to see the unified networkstatus consensus, we&#39;ll have to stop voting<br>
&gt; for a modified bwconnrate and bwconnburst, since the relays won&#39;t be<br>
&gt; able to know (at least this way) if it&#39;s a genuine relay. Maybe part<br>
&gt; of that design will be to present a signed credential proving you&#39;re a<br>
&gt; public relay. In any case, we have a way to disable this feature when<br>
&gt; that distant future arrives.<br>
&gt;<br>
&gt; We&#39;re also squeezing down bridge relays by this feature, since the public<br>
&gt; relays can&#39;t tell the difference between a bridge and a client. At some<br>
&gt; point we should make sure that bridges send their client traffic over<br>
&gt; different TCP connections than their own traffic. That&#39;s a separate<br>
&gt; discussion though.<br>
&gt;<br>
&gt; It shouldn&#39;t impact bandwidth bootstrapping tests, since those aim to<br>
&gt; spread 500KB of traffic across 4 circuits.<br>
&gt;<br>
&gt; It would impact Mike&#39;s bwauthority tests. We&#39;d want to make an exception<br>
&gt; for those Tors. I think we&#39;d leave the torperf deployments alone, since<br>
&gt; after all their goal is to measure &quot;realistic&quot; client performance.<br>
&gt;<br>
&gt; It could also impact initial directory info bootstrapping -- if you try<br>
&gt; to fetch 1MB from a particular dir mirror, it would slow down the second<br>
&gt; half of that download. We&#39;d want to keep an eye on how much that changes.<br>
&gt;<br>
&gt; A more thorough solution would be to rate-limit all the OR conns coming<br>
&gt; from a particular non-relay into the same bucket, to prevent people<br>
&gt; getting around the limits by opening multiple TCP connections. But it&#39;s<br>
&gt; actually not so easy to open multiple conns to the same destination in<br>
&gt; Tor; plus I&#39;m aiming to solve this for the general case where people<br>
&gt; are overloading relays and don&#39;t even know it&#39;s a bad thing.<br>
&gt;<br>
&gt; My main concern here is that I wonder if we are being thorough enough at<br>
&gt; detecting &quot;is a relay&quot;. It checks the consensus and the descriptor cache<br>
&gt; currently. So if the authorities think you&#39;re not Running, they won&#39;t put<br>
&gt; you in the consensus, and no relays will hear about you. If you go up and<br>
&gt; down, relays that serve dirport info will have your descriptor cached,<br>
&gt; so they&#39;ll recognize you so long as you were around in the past day or so.<br>
&gt;<br>
&gt; Relays that don&#39;t serve dirport info will stop fetching descriptors,<br>
&gt; but they&#39;ll continue to fetch the consensus. So they&#39;ll still mostly work.<br>
&gt;<br>
&gt; Are there any other cases that are going to be a problem? Are there better<br>
&gt; (simple, easy to deploy soon) ways to decide if the peer is a relay?<br>
&gt;<br>
&gt; --Roger<br>
&gt;<br>
&gt;<br>
</div></div></div><br>