Browse Source

Merge remote-tracking branch 'public/bug12848_024' into maint-0.2.5

Conflicts:
	src/or/circuitbuild.c
Nick Mathewson 9 years ago
parent
commit
d443658fad
3 changed files with 20 additions and 4 deletions
  1. 4 0
      changes/bug12848
  2. 8 0
      src/or/channel.c
  3. 8 4
      src/or/circuitbuild.c

+ 4 - 0
changes/bug12848

@@ -0,0 +1,4 @@
+  o Major bugfixes (relay):
+    - Avoid queuing or sending destroy cells for circuit ID zero when
+      we fail to send a CREATE cell. Fixes bug 12848; bugfix on
+      0.0.8pre1. Found and fixed by "cypherpunks".

+ 8 - 0
src/or/channel.c

@@ -2682,6 +2682,14 @@ int
 channel_send_destroy(circid_t circ_id, channel_t *chan, int reason)
 {
   tor_assert(chan);
+  if (circ_id == 0) {
+    log_warn(LD_BUG, "Attempted to send a destroy cell for circID 0 "
+             "on a channel " U64_FORMAT " at %p in state %s (%d)",
+             U64_PRINTF_ARG(chan->global_identifier),
+             chan, channel_state_to_string(chan->state),
+             chan->state);
+    return 0;
+  }
 
   /* Check to make sure we can send on this channel first */
   if (!(chan->state == CHANNEL_STATE_CLOSING ||

+ 8 - 4
src/or/circuitbuild.c

@@ -549,6 +549,7 @@ circuit_handle_first_hop(origin_circuit_t *circ)
     log_debug(LD_CIRC,"Conn open. Delivering first onion skin.");
     if ((err_reason = circuit_send_next_onion_skin(circ)) < 0) {
       log_info(LD_CIRC,"circuit_send_next_onion_skin failed.");
+      circ->base_.n_chan = NULL;
       return err_reason;
     }
   }
@@ -660,18 +661,18 @@ circuit_deliver_create_cell(circuit_t *circ, const create_cell_t *create_cell,
     static ratelim_t circid_warning_limit = RATELIM_INIT(9600);
     log_fn_ratelim(&circid_warning_limit, LOG_WARN, LD_CIRC,
                    "failed to get unique circID.");
-    return -1;
+    goto error;
   }
-  log_debug(LD_CIRC,"Chosen circID %u.", (unsigned)id);
-  circuit_set_n_circid_chan(circ, id, circ->n_chan);
 
   memset(&cell, 0, sizeof(cell_t));
   r = relayed ? create_cell_format_relayed(&cell, create_cell)
               : create_cell_format(&cell, create_cell);
   if (r < 0) {
     log_warn(LD_CIRC,"Couldn't format create cell");
-    return -1;
+    goto error;
   }
+  log_debug(LD_CIRC,"Chosen circID %u.", (unsigned)id);
+  circuit_set_n_circid_chan(circ, id, circ->n_chan);
   cell.circ_id = circ->n_circ_id;
 
   append_cell_to_circuit_queue(circ, circ->n_chan, &cell,
@@ -695,6 +696,9 @@ circuit_deliver_create_cell(circuit_t *circ, const create_cell_t *create_cell,
   }
 
   return 0;
+ error:
+  circ->n_chan = NULL;
+  return -1;
 }
 
 /** We've decided to start our reachability testing. If all