summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2016-11-25 12:53:00 -0500
committerNick Mathewson <nickm@torproject.org>2016-12-16 11:06:16 -0500
commit2ea5aa71823f385e36f20e643a20996dcb164464 (patch)
tree3a1d70c711bdd1fdf0917c2b43bf8c9fb8f3b2a4
parente56bc1e5de05d9bc6876d91d364d33f0771eb322 (diff)
downloadtor-2ea5aa71823f385e36f20e643a20996dcb164464.tar.gz
tor-2ea5aa71823f385e36f20e643a20996dcb164464.zip
Expire circuits that have been WAITING_FOR_BETTER_GUARD too long
(This is required by 3.9 in prop271, but is better done as a separate function IMO)
-rw-r--r--src/or/circuitlist.c12
-rw-r--r--src/or/circuitlist.h1
-rw-r--r--src/or/circuituse.c19
-rw-r--r--src/or/circuituse.h1
-rw-r--r--src/or/entrynodes.c18
-rw-r--r--src/or/entrynodes.h1
-rw-r--r--src/or/main.c1
7 files changed, 49 insertions, 4 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c
index 9d7a5d7f0e..0afe2f8059 100644
--- a/src/or/circuitlist.c
+++ b/src/or/circuitlist.c
@@ -553,7 +553,7 @@ circuit_close_all_marked(void)
smartlist_clear(circuits_pending_close);
}
-/** Return the head of the global linked list of circuits. */
+/** Return a pointer to the global list of circuits. */
MOCK_IMPL(smartlist_t *,
circuit_get_global_list,(void))
{
@@ -562,6 +562,16 @@ circuit_get_global_list,(void))
return global_circuitlist;
}
+/** */
+/** Return a pointer to the global list of origin circuits. */
+smartlist_t *
+circuit_get_global_origin_circuit_list(void)
+{
+ if (NULL == global_origin_circuit_list)
+ global_origin_circuit_list = smartlist_new();
+ return global_circuitlist;
+}
+
/** Function to make circ-\>state human-readable */
const char *
circuit_state_to_string(int state)
diff --git a/src/or/circuitlist.h b/src/or/circuitlist.h
index 73039cc06e..e2102a118b 100644
--- a/src/or/circuitlist.h
+++ b/src/or/circuitlist.h
@@ -15,6 +15,7 @@
#include "testsupport.h"
MOCK_DECL(smartlist_t *, circuit_get_global_list, (void));
+smartlist_t *circuit_get_global_origin_circuit_list(void);
const char *circuit_state_to_string(int state);
const char *circuit_purpose_to_controller_string(uint8_t purpose);
const char *circuit_purpose_to_controller_hs_state_string(uint8_t purpose);
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index b9f94fb3a2..b925729e01 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -800,6 +800,25 @@ circuit_expire_building(void)
} SMARTLIST_FOREACH_END(victim);
}
+/**
+ * Mark for close all circuits that start here, that were built through a
+ * guard we weren't sure if we wanted to use, and that have been waiting
+ * around for way too long.
+ */
+void
+circuit_expire_waiting_for_better_guard(void)
+{
+ SMARTLIST_FOREACH_BEGIN(circuit_get_global_origin_circuit_list(),
+ origin_circuit_t *, circ) {
+ if (TO_CIRCUIT(circ)->marked_for_close)
+ continue;
+ if (circ->guard_state == NULL)
+ continue;
+ if (entry_guard_state_should_expire(circ->guard_state))
+ circuit_mark_for_close(TO_CIRCUIT(circ), END_CIRC_REASON_NONE);
+ } SMARTLIST_FOREACH_END(circ);
+}
+
/** For debugging #8387: track when we last called
* circuit_expire_old_circuits_clientside. */
static time_t last_expired_clientside_circuits = 0;
diff --git a/src/or/circuituse.h b/src/or/circuituse.h
index 5973978c45..110bdda5b2 100644
--- a/src/or/circuituse.h
+++ b/src/or/circuituse.h
@@ -13,6 +13,7 @@
#define TOR_CIRCUITUSE_H
void circuit_expire_building(void);
+void circuit_expire_waiting_for_better_guard(void);
void circuit_remove_handled_ports(smartlist_t *needed_ports);
int circuit_stream_is_being_handled(entry_connection_t *conn, uint16_t port,
int min);
diff --git a/src/or/entrynodes.c b/src/or/entrynodes.c
index 951ce15f85..1c9349ee03 100644
--- a/src/or/entrynodes.c
+++ b/src/or/entrynodes.c
@@ -1605,9 +1605,6 @@ entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
"circuit had higher priority, so not upgrading.",
n_complete, n_waiting);
- /* XXXX prop271 implement: "(Time them out after a
- {NONPRIMARY_GUARD_IDLE_TIMEOUT} seconds.)"
- */
return 0;
}
}
@@ -1672,6 +1669,21 @@ entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
}
/**
+ * Return true iff the circuit whose state is <b>guard_state</b> should
+ * expire.
+ */
+int
+entry_guard_state_should_expire(circuit_guard_state_t *guard_state)
+{
+ if (guard_state == NULL)
+ return 0;
+ const time_t expire_if_waiting_since =
+ approx_time() - NONPRIMARY_GUARD_IDLE_TIMEOUT;
+ return (guard_state->state == GUARD_CIRC_STATE_WAITING_FOR_BETTER_GUARD
+ && guard_state->state_set_at < expire_if_waiting_since);
+}
+
+/**
* Update all derived pieces of the guard selection state in <b>gs</b>.
* Return true iff we should stop using all previously generated circuits.
*/
diff --git a/src/or/entrynodes.h b/src/or/entrynodes.h
index ec24011377..648e599310 100644
--- a/src/or/entrynodes.h
+++ b/src/or/entrynodes.h
@@ -337,6 +337,7 @@ int entry_guards_update_all(guard_selection_t *gs);
int entry_guards_upgrade_waiting_circuits(guard_selection_t *gs,
const smartlist_t *all_circuits,
smartlist_t *newly_complete_out);
+int entry_guard_state_should_expire(circuit_guard_state_t *guard_state);
void entry_guards_note_internet_connectivity(guard_selection_t *gs);
/* Used by bridges.c only. */
diff --git a/src/or/main.c b/src/or/main.c
index 16106612a9..96ff442c68 100644
--- a/src/or/main.c
+++ b/src/or/main.c
@@ -1402,6 +1402,7 @@ run_scheduled_events(time_t now)
/* (If our circuit build timeout can ever become lower than a second (which
* it can't, currently), we should do this more often.) */
circuit_expire_building();
+ circuit_expire_waiting_for_better_guard();
/* 3b. Also look at pending streams and prune the ones that 'began'
* a long time ago but haven't gotten a 'connected' yet.