From 0888c2f8f55037b49fead49091013f2cc7de17c5 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Fri, 11 May 2012 12:52:21 -0400 Subject: When no usable exit satisfies a predicted port, stop predicting it. Fix for bug 3296. --- src/or/circuitbuild.c | 4 ++++ src/or/rephist.c | 20 ++++++++++++++++++++ src/or/rephist.h | 1 + 3 files changed, 25 insertions(+) (limited to 'src') diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 5481838cc..3b82ed745 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -2847,6 +2847,10 @@ choose_good_exit_server_general(int need_uptime, int need_capacity) if (node) break; smartlist_clear(supporting); + /* If we reach this point, we can't actually support any unhandled + * predicted ports, so clear all the remaining ones. */ + if (smartlist_len(needed_ports)) + rep_hist_remove_predicted_ports(needed_ports); } SMARTLIST_FOREACH(needed_ports, uint16_t *, cp, tor_free(cp)); smartlist_free(needed_ports); diff --git a/src/or/rephist.c b/src/or/rephist.c index 0cd60eeb8..c3f059839 100644 --- a/src/or/rephist.c +++ b/src/or/rephist.c @@ -1868,6 +1868,26 @@ rep_hist_get_predicted_ports(time_t now) return out; } +/** + * Take a list of uint16_t *, and remove every port in the list from the + * current list of predicted ports. + */ +void +rep_hist_remove_predicted_ports(const smartlist_t *rmv_ports) +{ + /* Let's do this on O(N), not O(N^2). */ + bitarray_t *remove_ports = bitarray_init_zero(UINT16_MAX); + SMARTLIST_FOREACH(rmv_ports, const uint16_t *, p, + bitarray_set(remove_ports, *p)); + SMARTLIST_FOREACH_BEGIN(predicted_ports_list, predicted_port_t *, pp) { + if (bitarray_is_set(remove_ports, pp->port)) { + tor_free(pp); + SMARTLIST_DEL_CURRENT(predicted_ports_list, pp); + } + } SMARTLIST_FOREACH_END(pp); + bitarray_free(remove_ports); +} + /** The user asked us to do a resolve. Rather than keeping track of * timings and such of resolves, we fake it for now by treating * it the same way as a connection to port 80. This way we will continue diff --git a/src/or/rephist.h b/src/or/rephist.h index 0a3e46ae1..800b957d5 100644 --- a/src/or/rephist.h +++ b/src/or/rephist.h @@ -49,6 +49,7 @@ const char *rep_hist_get_router_stability_doc(time_t now); void rep_hist_note_used_port(time_t now, uint16_t port); smartlist_t *rep_hist_get_predicted_ports(time_t now); +void rep_hist_remove_predicted_ports(const smartlist_t *rmv_ports); void rep_hist_note_used_resolve(time_t now); void rep_hist_note_used_internal(time_t now, int need_uptime, int need_capacity); -- cgit v1.2.3