summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2013-10-31 16:53:31 -0400
committerRoger Dingledine <arma@torproject.org>2014-07-25 11:59:00 -0400
commitd5558f00729992a9abeeb1cb1512004de35ec007 (patch)
tree142367d1a19fe95092ed68d596ccb7a6f87c4e3d
parente001610c99bea661dbefc693ec173a90fcb3ee5e (diff)
downloadtor-d5558f00729992a9abeeb1cb1512004de35ec007.tar.gz
tor-d5558f00729992a9abeeb1cb1512004de35ec007.zip
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.)
-rw-r--r--src/or/circuituse.c9
-rw-r--r--src/or/command.c1
-rw-r--r--src/or/or.h3
3 files changed, 9 insertions, 4 deletions
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index c2d2b2e87c..06a51a04a2 100644
--- a/src/or/circuituse.c
+++ b/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) {
diff --git a/src/or/command.c b/src/or/command.c
index 699b02fb47..51d07b0485 100644
--- a/src/or/command.c
+++ b/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) {
diff --git a/src/or/or.h b/src/or/or.h
index 3eaf3447dc..34f055cf06 100644
--- a/src/or/or.h
+++ b/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? */