[or-cvs] r16156: Implement most of proposal 110. (in tor/trunk: . doc doc/spec/proposals src/or)

nickm at seul.org nickm at seul.org
Wed Jul 23 15:58:40 UTC 2008


Author: nickm
Date: 2008-07-23 11:58:38 -0400 (Wed, 23 Jul 2008)
New Revision: 16156

Modified:
   tor/trunk/
   tor/trunk/ChangeLog
   tor/trunk/doc/TODO
   tor/trunk/doc/spec/proposals/110-avoid-infinite-circuits.txt
   tor/trunk/src/or/circuitlist.c
   tor/trunk/src/or/command.c
   tor/trunk/src/or/or.h
   tor/trunk/src/or/relay.c
Log:
 r17323 at aud-055:  nickm | 2008-07-23 17:58:25 +0200
 Implement most of proposal 110.


/home/or/svnrepo/hooks/commit-email.pl: `/usr/bin/svnlook diff /home/or/svnrepo -r 16156' failed with this output:

Property changes on: tor/trunk
___________________________________________________________________
 svk:merge ticket from /tor/trunk [r17323] on 49666b30-7950-49c5-bedf-9dc8f3168102

Modified: tor/trunk/ChangeLog
===================================================================
--- tor/trunk/ChangeLog	2008-07-23 15:58:30 UTC (rev 16155)
+++ tor/trunk/ChangeLog	2008-07-23 15:58:38 UTC (rev 16156)
@@ -3,6 +3,13 @@
     - Send a bootstrap problem "warn" event on the first problem if the
       reason is NO_ROUTE (that is, our network is down).
 
+  o Major features:
+    - Implements most of proposal 110: The first K cells to be send
+      along a circuit are marked as special "early" cells; only K
+      "early" cells will be allowed.  Once this code is universal, we
+      can block certain kinds of DOS attack by only allowing EXTEND
+      commands in these cells.
+
   o Major bugfixes:
     - Try to attach connections immediately upon receiving a RENDEZVOUS2
       or RENDEZVOUS_ESTABLISHED cell. This can save a second or two

Modified: tor/trunk/doc/TODO
===================================================================
--- tor/trunk/doc/TODO	2008-07-23 15:58:30 UTC (rev 16155)
+++ tor/trunk/doc/TODO	2008-07-23 15:58:38 UTC (rev 16156)
@@ -214,7 +214,7 @@
 
 For 0.2.1.x:
   - Proposals to do:
-    - 110: avoid infinite-length circuits
+    o 110: avoid infinite-length circuits
 R   d 128: families of private bridges
     - 134: handle authority fragmentation.
 

Modified: tor/trunk/doc/spec/proposals/110-avoid-infinite-circuits.txt
===================================================================
--- tor/trunk/doc/spec/proposals/110-avoid-infinite-circuits.txt	2008-07-23 15:58:30 UTC (rev 16155)
+++ tor/trunk/doc/spec/proposals/110-avoid-infinite-circuits.txt	2008-07-23 15:58:38 UTC (rev 16156)
@@ -6,9 +6,11 @@
 Created: 13-Mar-2007
 Status: Accepted
 Target: 0.2.1.x
+Implemented-In: 0.2.1.3-alpha
 
 History:
 
+  Revised 28 July 2008 by nickm: set K.
   Revised 3 July 2008 by nickm: rename from relay_extend to
      relay_early.  Revise to current migration plan.  Allow K cells
      over circuit lifetime, not just at start.
@@ -85,17 +87,22 @@
   is not speaking the v2 link protocol, the server relays the cell as
   a RELAY cell.
 
-  In 0.2.1.x, clients begin using RELAY_EARLY cells on v2 connections.
-  This functionality can be safely backported to 0.2.0.x.  Clients
-  should pick a random number betweeen (say) 8 and 10 to send.
+  In 0.2.1.3-alpha, clients begin using RELAY_EARLY cells on v2
+  connections.  This functionality can be safely backported to
+  0.2.0.x.  Clients should pick a random number betweeen (say) K and
+  K-2 to send.
 
-  In 0.2.1.x, servers close any circuit in which more than K
+  In 0.2.1.3-alpha, servers close any circuit in which more than K
   relay_early cells are sent.
 
   Once all versions the do not send RELAY_EARLY cells are obsolete,
   servers can begin to reject any EXTEND requests not sent in a
   RELAY_EARLY cell.
 
+Parameters:
+
+  Let K = 8, for no terribly good reason.
+
 Spec:
 
   [We can formalize this part once we think the design is a good one.]

Modified: tor/trunk/src/or/circuitlist.c
===================================================================
--- tor/trunk/src/or/circuitlist.c	2008-07-23 15:58:30 UTC (rev 16155)
+++ tor/trunk/src/or/circuitlist.c	2008-07-23 15:58:38 UTC (rev 16156)
@@ -347,6 +347,8 @@
 
   circ->next_stream_id = crypto_rand_int(1<<16);
   circ->global_identifier = n_circuits_allocated++;
+  circ->remaining_relay_early_cells = MAX_RELAY_EARLY_CELLS_PER_CIRCUIT;
+  circ->remaining_relay_early_cells -= crypto_rand_int(2);
 
   init_circuit_base(TO_CIRCUIT(circ));
 
@@ -367,6 +369,8 @@
   if (p_conn)
     circuit_set_p_circid_orconn(circ, p_circ_id, p_conn);
 
+  circ->remaining_relay_early_cells = MAX_RELAY_EARLY_CELLS_PER_CIRCUIT;
+
   init_circuit_base(TO_CIRCUIT(circ));
 
   return circ;

Modified: tor/trunk/src/or/command.c
===================================================================
--- tor/trunk/src/or/command.c	2008-07-23 15:58:30 UTC (rev 16155)
+++ tor/trunk/src/or/command.c	2008-07-23 15:58:38 UTC (rev 16156)
@@ -353,8 +353,8 @@
   }
 }
 
-/** Process a 'relay' <b>cell</b> that just arrived from <b>conn</b>. Make sure
- * it came in with a recognized circ_id. Pass it on to
+/** Process a 'relay' or 'relay_early' <b>cell</b> that just arrived from
+ * <b>conn</b>. Make sure it came in with a recognized circ_id. Pass it on to
  * circuit_receive_relay_cell() for actual processing.
  */
 static void
@@ -390,6 +390,30 @@
   else
     direction = CELL_DIRECTION_IN;
 
+  /* If we have a relay_early cell, make sure that it's outbound, and we've
+   * gotten no more than MAX_RELAY_EARLY_CELLS_PER_CIRCUIT of them. */
+  if (cell->command == CELL_RELAY_EARLY) {
+    if (direction == CELL_DIRECTION_IN) {
+      log_fn(LOG_PROTOCOL_WARN, LD_OR,
+             "Received an inbound RELAY_EARLY cell on circuit %d from %s:%d."
+             "  Closing circuit.",
+             cell->circ_id, conn->_base.address, conn->_base.port);
+      circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
+      return;
+    } else {
+      or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
+      if (or_circ->remaining_relay_early_cells == 0) {
+        log_fn(LOG_PROTOCOL_WARN, LD_OR,
+               "Received too many RELAY_EARLY cells on circ %d from %s:%d."
+               "  Closing circuit.",
+               cell->circ_id, safe_str(conn->_base.address), conn->_base.port);
+        circuit_mark_for_close(circ, END_CIRC_REASON_TORPROTOCOL);
+        return;
+      }
+      --or_circ->remaining_relay_early_cells;
+    }
+  }
+
   if ((reason = circuit_receive_relay_cell(cell, circ, direction)) < 0) {
     log_fn(LOG_PROTOCOL_WARN,LD_PROTOCOL,"circuit_receive_relay_cell "
            "(%s) failed. Closing.",

Modified: tor/trunk/src/or/or.h
===================================================================
--- tor/trunk/src/or/or.h	2008-07-23 15:58:30 UTC (rev 16155)
+++ tor/trunk/src/or/or.h	2008-07-23 15:58:38 UTC (rev 16156)
@@ -1828,6 +1828,10 @@
   struct circuit_t *next; /**< Next circuit in linked list of all circuits. */
 } circuit_t;
 
+/** Largest number of relay_early cells that we can send on a given
+ * circuit. */
+#define MAX_RELAY_EARLY_CELLS_PER_CIRCUIT 8
+
 /** An origin_circuit_t holds data necessary to build and use a circuit.
  */
 typedef struct origin_circuit_t {
@@ -1870,15 +1874,19 @@
    */
   uint8_t rend_desc_version;
 
+  /** How many more relay_early cells can we send on this circuit, according
+   * to the specification? */
+  unsigned int remaining_relay_early_cells : 4;
+
+  /** The next stream_id that will be tried when we're attempting to
+   * construct a new AP stream originating at this circuit. */
+  streamid_t next_stream_id;
+
   /* The intro key replaces the hidden service's public key if purpose is
    * S_ESTABLISH_INTRO or S_INTRO, provided that no unversioned rendezvous
    * descriptor is used. */
   crypto_pk_env_t *intro_key;
 
-  /** The next stream_id that will be tried when we're attempting to
-   * construct a new AP stream originating at this circuit. */
-  streamid_t next_stream_id;
-
   /** Quasi-global identifier for this circuit; used for control.c */
   /* XXXX NM This can get re-used after 2**32 circuits. */
   uint32_t global_identifier;
@@ -1946,6 +1954,10 @@
   /* ???? move to a subtype or adjunct structure? Wastes 20 bytes -NM */
   char handshake_digest[DIGEST_LEN]; /**< Stores KH for the handshake. */
 
+  /** How many more relay_early cells can we send on this circuit, according
+   * to the specification? */
+  unsigned int remaining_relay_early_cells : 4;
+
   /** True iff this circuit was made with a CREATE_FAST cell. */
   unsigned int is_first_hop : 1;
 } or_circuit_t;

Modified: tor/trunk/src/or/relay.c
===================================================================



More information about the tor-commits mailing list