Browse Source

circuit_build_failed: distinguish "first hop chan failed", "CREATE failed"

Roger spotted this on tor-dev in his comments on proposal 221.

(Actually, detect DESTROY vs everything else, since arma likes
network timeout indicating failure but not overload indicating failure.)
Nick Mathewson 10 years ago
parent
commit
d5558f0072
3 changed files with 9 additions and 4 deletions
  1. 5 4
      src/or/circuituse.c
  2. 1 0
      src/or/command.c
  3. 3 0
      src/or/or.h

+ 5 - 4
src/or/circuituse.c

@@ -1382,10 +1382,11 @@ circuit_build_failed(origin_circuit_t *circ)
     failed_at_last_hop = 1;
   }
   if (circ->cpath &&
-      circ->cpath->state != CPATH_STATE_OPEN) {
-    /* We failed at the first hop. If there's an OR connection
-     * to blame, blame it. Also, avoid this relay for a while, and
-     * fail any one-hop directory fetches destined for it. */
+      circ->cpath->state != CPATH_STATE_OPEN &&
+      ! circ->base_.received_destroy) {
+    /* We failed at the first hop for some reason other than a DESTROY cell.
+     * If there's an OR connection to blame, blame it. Also, avoid this relay
+     * for a while, and fail any one-hop directory fetches destined for it. */
     const char *n_chan_id = circ->cpath->extend_info->identity_digest;
     int already_marked = 0;
     if (circ->base_.n_chan) {

+ 1 - 0
src/or/command.c

@@ -499,6 +499,7 @@ command_process_destroy_cell(cell_t *cell, channel_t *chan)
   log_debug(LD_OR,"Received for circID %u.",(unsigned)cell->circ_id);
 
   reason = (uint8_t)cell->payload[0];
+  circ->received_destroy = 1;
 
   if (!CIRCUIT_IS_ORIGIN(circ) &&
       cell->circ_id == TO_OR_CIRCUIT(circ)->p_circ_id) {

+ 3 - 0
src/or/or.h

@@ -2785,6 +2785,9 @@ typedef struct circuit_t {
    * allowing n_streams to add any more cells. (OR circuit only.) */
   unsigned int streams_blocked_on_p_chan : 1;
 
+  /** True iff this circuit has received a DESTROY cell in either direction */
+  unsigned int received_destroy : 1;
+
   uint8_t state; /**< Current status of this circuit. */
   uint8_t purpose; /**< Why are we creating this circuit? */