diff options
author | Nick Mathewson <nickm@torproject.org> | 2016-11-21 17:23:25 -0500 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2016-11-30 14:42:53 -0500 |
commit | dbbaa515183e250e20c40fa7b4c00df9487058fa (patch) | |
tree | ad7047ded85f1c231ff158e6aad8201824a72148 /src/or/circuitlist.c | |
parent | de617a471442342fc2abafdde4e250fd31eb45ac (diff) | |
download | tor-dbbaa515183e250e20c40fa7b4c00df9487058fa.tar.gz tor-dbbaa515183e250e20c40fa7b4c00df9487058fa.zip |
Use the new guard notification/selection APIs throughout Tor
This patch doesn't cover every case; omitted cases are marked with
"XXXX prop271", as usual. It leaves both the old interface and the
new interface for guard status notification, since they don't
actually work in the same way: the new API wants to be told when a
circuit has failed or succeeded, whereas the old API wants to know
when a channel has failed or succeeded.
I ran into some trouble with directory guard stuff, since when we
pick the directory guard, we don't actually have a circuit to
associate it with. I solved that by allowing guard states to be
associated with directory connections, not just circuits.
Diffstat (limited to 'src/or/circuitlist.c')
-rw-r--r-- | src/or/circuitlist.c | 42 |
1 files changed, 41 insertions, 1 deletions
diff --git a/src/or/circuitlist.c b/src/or/circuitlist.c index c274534759..2a03f8a0d9 100644 --- a/src/or/circuitlist.c +++ b/src/or/circuitlist.c @@ -92,6 +92,10 @@ static smartlist_t *global_origin_circuit_list = NULL; /** A list of all the circuits in CIRCUIT_STATE_CHAN_WAIT. */ static smartlist_t *circuits_pending_chans = NULL; +/** List of all the (origin) circuits whose state is + * CIRCUIT_STATE_GUARD_WAIT. */ +static smartlist_t *circuits_pending_other_guards = NULL; + /** A list of all the circuits that have been marked with * circuit_mark_for_close and which are waiting for circuit_about_to_free. */ static smartlist_t *circuits_pending_close = NULL; @@ -433,8 +437,10 @@ circuit_set_state(circuit_t *circ, uint8_t state) tor_assert(circ); if (state == circ->state) return; - if (!circuits_pending_chans) + if (PREDICT_UNLIKELY(!circuits_pending_chans)) circuits_pending_chans = smartlist_new(); + if (PREDICT_UNLIKELY(!circuits_pending_other_guards)) + circuits_pending_other_guards = smartlist_new(); if (circ->state == CIRCUIT_STATE_CHAN_WAIT) { /* remove from waiting-circuit list. */ smartlist_remove(circuits_pending_chans, circ); @@ -1022,6 +1028,9 @@ circuit_free_all(void) smartlist_free(circuits_pending_close); circuits_pending_close = NULL; + smartlist_free(circuits_pending_other_guards); + circuits_pending_other_guards = NULL; + { chan_circid_circuit_map_t **elt, **next, *c; for (elt = HT_START(chan_circid_map, &chan_circid_map); @@ -1721,6 +1730,37 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info, return best; } +/** + * Check whether any of the origin circuits that are waiting to see if + * their guard is good enough to use can be upgraded to "ready". If so, + * return a new smartlist containing them. Otherwise return NULL. + */ +smartlist_t * +circuit_find_circuits_to_upgrade_from_guard_wait(void) +{ + /* Only if some circuit is actually waiting on an upgrade should we + * run the algorithm. */ + if (! circuits_pending_other_guards || + smartlist_len(circuits_pending_other_guards)==0) + return NULL; + /* Only if we have some origin circuiuts should we run the algorithm. + */ + if (!global_origin_circuit_list) + return NULL; + + /* Okay; we can pass our circuit list to entrynodes.c.*/ + smartlist_t *result = smartlist_new(); + int r = entry_guards_upgrade_waiting_circuits(get_guard_selection_info(), + global_origin_circuit_list, + result); + if (r && smartlist_len(result)) { + return result; + } else { + smartlist_free(result); + return NULL; + } +} + /** Return the number of hops in circuit's path. If circ has no entries, * or is NULL, returns 0. */ int |