]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
three hacks to workaround bug 1038
authorRoger Dingledine <arma@torproject.org>
Tue, 28 Jul 2009 01:01:24 +0000 (21:01 -0400)
committerRoger Dingledine <arma@torproject.org>
Tue, 28 Jul 2009 01:58:32 +0000 (21:58 -0400)
The problem is that clients and hidden services are receiving
relay_early cells, and they tear down the circuit.

Hack #1 is for rendezvous points to rewrite relay_early cells to
relay cells. That way there are never any incoming relay_early cells.

Hack #2 is for clients and hidden services to never send a relay_early
cell on an established rendezvous circuit. That works around rendezvous
points that haven't upgraded yet.

Hack #3 is for clients and hidden services to not tear down the circuit
when they receive an inbound relay_early cell. We already refuse extend
cells at clients.

ChangeLog
src/or/command.c
src/or/or.h
src/or/relay.c

index 66664c18d13bdefdf8976ed5de6d8cbced438acc..59404929cfc1a88b23a21a2b46a75c6ac2914005 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+Changes in version 0.2.1.19 - 2009-07-??
+  o Major bugfixes:
+    - Make accessing hidden services on 0.2.1.x work right
+      again. Bugfix on 0.2.1.3-alpha; workaround for bug 1038.
+
+
 Changes in version 0.2.1.18 - 2009-07-24
   o Build fixes:
     - Add LIBS=-lrt to Makefile.am so the Tor RPMs use a static libevent.
index 9481e5bcc6df32d766f33307e19859c968053869..c36874be5c307d39b7ea3ce6bd6f7e271d7c9fae 100644 (file)
@@ -395,12 +395,8 @@ command_process_relay_cell(cell_t *cell, or_connection_t *conn)
    * 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;
+      /* XXX Allow an unlimited number of inbound relay_early cells for
+       * now, for hidden service compatibility. See bug 1038. -RD */
     } else {
       or_circuit_t *or_circ = TO_OR_CIRCUIT(circ);
       if (or_circ->remaining_relay_early_cells == 0) {
index eddeda1531dbcae145cb9e685e9033c907f68194..fba7af0da0bcfa72c4a0fadfe4b388f04206dd59 100644 (file)
@@ -488,6 +488,11 @@ typedef enum {
    (p)<=_CIRCUIT_PURPOSE_C_MAX)
 /** True iff the circuit_t <b>c</b> is actually an origin_circuit_t. */
 #define CIRCUIT_IS_ORIGIN(c) (CIRCUIT_PURPOSE_IS_ORIGIN((c)->purpose))
+/** True iff the circuit purpose <b>p</b> is for an established rendezvous
+ * circuit. */
+#define CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(p) \
+  ((p) == CIRCUIT_PURPOSE_C_REND_JOINED ||     \
+   (p) == CIRCUIT_PURPOSE_S_REND_JOINED)
 
 /** How many circuits do we want simultaneously in-progress to handle
  * a given stream? */
index 8099f4f072723ecb4d2bb72c3d1271291585599d..3419e3d19052740bb83896a7b8e00d08b75d3b5a 100644 (file)
@@ -208,6 +208,7 @@ circuit_receive_relay_cell(cell_t *cell, circuit_t *circ,
       tor_assert(circ->purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED);
       tor_assert(splice->_base.purpose == CIRCUIT_PURPOSE_REND_ESTABLISHED);
       cell->circ_id = splice->p_circ_id;
+      cell->command = CELL_RELAY; /* can't be relay_early anyway */
       if ((reason = circuit_receive_relay_cell(cell, TO_CIRCUIT(splice),
                                                CELL_DIRECTION_IN)) < 0) {
         log_warn(LD_REND, "Error relaying cell across rendezvous; closing "
@@ -541,11 +542,17 @@ relay_send_command_from_edge(uint16_t stream_id, circuit_t *circ,
     origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
     if (origin_circ->remaining_relay_early_cells > 0 &&
         (relay_command == RELAY_COMMAND_EXTEND ||
-         cpath_layer != origin_circ->cpath)) {
-      /* If we've got any relay_early cells left, and we're sending a relay
-       * cell or we're not talking to the first hop, use one of them.  Don't
-       * worry about the conn protocol version: append_cell_to_circuit_queue
-       * will fix it up. */
+         (cpath_layer != origin_circ->cpath &&
+          !CIRCUIT_PURPOSE_IS_ESTABLISHED_REND(circ->purpose)))) {
+      /* If we've got any relay_early cells left, and we're sending
+       * an extend cell or (we're not talking to the first hop and we're
+       * not talking to a rendezvous circuit), use one of them.
+       * Don't worry about the conn protocol version:
+       * append_cell_to_circuit_queue will fix it up. */
+      /* XXX For now, clients don't use RELAY_EARLY cells when sending
+       * relay cells on rendezvous circuits. See bug 1038. Eventually,
+       * we can take this behavior away in favor of having clients avoid
+       * rendezvous points running 0.2.1.3-alpha through 0.2.1.18. -RD */
       cell.command = CELL_RELAY_EARLY;
       --origin_circ->remaining_relay_early_cells;
       log_debug(LD_OR, "Sending a RELAY_EARLY cell; %d remaining.",