From 127f37ad29260e040002b8fc49857defc661e391 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Thu, 23 Sep 2010 22:10:13 -0400 Subject: [PATCH 1/8] refactor; no actual changes --- src/or/circuitbuild.c | 32 +++++++++++--------------------- src/or/circuitbuild.h | 4 ++-- src/or/main.c | 4 ++-- 3 files changed, 15 insertions(+), 25 deletions(-) diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index d696fe1b9b..cc94a74d4b 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -3209,7 +3209,7 @@ entry_guard_set_status(entry_guard_t *e, routerinfo_t *ri, char buf[HEX_DIGEST_LEN+1]; int changed = 0; - tor_assert(options); + tor_assert(options); /* dead code */ *reason = NULL; @@ -3468,9 +3468,8 @@ add_an_entry_guard(routerinfo_t *chosen, int reset_status) /** If the use of entry guards is configured, choose more entry guards * until we have enough in the list. */ static void -pick_entry_guards(void) +pick_entry_guards(or_options_t *options) { - or_options_t *options = get_options(); int changed = 0; tor_assert(entry_guards); @@ -3502,10 +3501,9 @@ entry_guard_free(entry_guard_t *e) * or which was selected by a version of Tor that's known to select * entry guards badly. */ static int -remove_obsolete_entry_guards(void) +remove_obsolete_entry_guards(time_t now) { int changed = 0, i; - time_t now = time(NULL); for (i = 0; i < smartlist_len(entry_guards); ++i) { entry_guard_t *entry = smartlist_get(entry_guards, i); @@ -3565,11 +3563,10 @@ remove_obsolete_entry_guards(void) * long that we don't think they'll come up again. Return 1 if we * removed any, or 0 if we did nothing. */ static int -remove_dead_entry_guards(void) +remove_dead_entry_guards(time_t now) { char dbuf[HEX_DIGEST_LEN+1]; char tbuf[ISO_TIME_LEN+1]; - time_t now = time(NULL); int i; int changed = 0; @@ -3604,23 +3601,18 @@ remove_dead_entry_guards(void) * think that things are unlisted. */ void -entry_guards_compute_status(void) +entry_guards_compute_status(or_options_t *options, time_t now) { - time_t now; int changed = 0; int severity = LOG_DEBUG; - or_options_t *options; digestmap_t *reasons; if (! entry_guards) return; - options = get_options(); if (options->EntryNodes) /* reshuffle the entry guard list if needed */ entry_nodes_should_be_added(); - now = time(NULL); - reasons = digestmap_new(); SMARTLIST_FOREACH_BEGIN(entry_guards, entry_guard_t *, entry) { @@ -3636,7 +3628,7 @@ entry_guards_compute_status(void) } SMARTLIST_FOREACH_END(entry); - if (remove_dead_entry_guards()) + if (remove_dead_entry_guards(now)) changed = 1; severity = changed ? LOG_DEBUG : LOG_INFO; @@ -3801,9 +3793,8 @@ entry_nodes_should_be_added(void) /** Add all nodes in EntryNodes that aren't currently guard nodes to the list * of guard nodes, at the front. */ static void -entry_guards_prepend_from_config(void) +entry_guards_prepend_from_config(or_options_t *options) { - or_options_t *options = get_options(); smartlist_t *entry_routers, *entry_fps; smartlist_t *old_entry_guards_on_list, *old_entry_guards_not_on_list; tor_assert(entry_guards); @@ -3931,11 +3922,11 @@ choose_random_entry(cpath_build_state_t *state) entry_guards = smartlist_create(); if (should_add_entry_nodes) - entry_guards_prepend_from_config(); + entry_guards_prepend_from_config(options); if (!entry_list_is_constrained(options) && smartlist_len(entry_guards) < options->NumEntryGuards) - pick_entry_guards(); + pick_entry_guards(options); retry: smartlist_clear(live_entry_guards); @@ -4164,7 +4155,7 @@ entry_guards_parse_state(or_state_t *state, int set, char **msg) entry_guards_dirty = 0; /* XXX022 hand new_entry_guards to this func, and move it up a * few lines, so we don't have to re-dirty it */ - if (remove_obsolete_entry_guards()) + if (remove_obsolete_entry_guards(now)) entry_guards_dirty = 1; } digestmap_free(added_by, _tor_free); @@ -4469,9 +4460,8 @@ retry_bridge_descriptor_fetch_directly(const char *digest) * descriptor, fetch a new copy of its descriptor -- either directly * from the bridge or via a bridge authority. */ void -fetch_bridge_descriptors(time_t now) +fetch_bridge_descriptors(or_options_t *options, time_t now) { - or_options_t *options = get_options(); int num_bridge_auths = get_n_authorities(BRIDGE_AUTHORITY); int ask_bridge_directly; int can_use_bridge_authority; diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index f4cc2a904d..6cc461c98d 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -49,7 +49,7 @@ void extend_info_free(extend_info_t *info); routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state); const char *build_state_get_exit_nickname(cpath_build_state_t *state); -void entry_guards_compute_status(void); +void entry_guards_compute_status(or_options_t *options, time_t now); int entry_guard_register_connect_status(const char *digest, int succeeded, int mark_relay_status, time_t now); void entry_nodes_should_be_added(void); @@ -68,7 +68,7 @@ learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest); void bridge_add_from_config(const tor_addr_t *addr, uint16_t port, char *digest); void retry_bridge_descriptor_fetch_directly(const char *digest); -void fetch_bridge_descriptors(time_t now); +void fetch_bridge_descriptors(or_options_t *options, time_t now); void learned_bridge_descriptor(routerinfo_t *ri, int from_cache); int any_bridge_descriptors_known(void); int any_pending_bridge_descriptor_fetches(void); diff --git a/src/or/main.c b/src/or/main.c index 477a274d54..b59351cf09 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -710,7 +710,7 @@ directory_info_has_arrived(time_t now, int from_cache) /* if we have enough dir info, then update our guard status with * whatever we just learned. */ - entry_guards_compute_status(); + entry_guards_compute_status(options, now); /* Don't even bother trying to get extrainfo until the rest of our * directory info is up-to-date */ if (options->DownloadExtraInfo) @@ -912,7 +912,7 @@ run_scheduled_events(time_t now) update_router_descriptor_downloads(now); update_extrainfo_downloads(now); if (options->UseBridges) - fetch_bridge_descriptors(now); + fetch_bridge_descriptors(options, now); if (router_have_minimum_dir_info()) time_to_try_getting_descriptors = now + LAZY_DESCRIPTOR_RETRY_INTERVAL; else From 8bac1885729ba995397f673575ed58bbb0d698a8 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Thu, 23 Sep 2010 22:10:30 -0400 Subject: [PATCH 2/8] remove a redundant assert --- src/or/circuitbuild.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index cc94a74d4b..90ae92a451 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -3209,8 +3209,6 @@ entry_guard_set_status(entry_guard_t *e, routerinfo_t *ri, char buf[HEX_DIGEST_LEN+1]; int changed = 0; - tor_assert(options); /* dead code */ - *reason = NULL; /* Do we want to mark this guard as bad? */ From bb22360bad4d19483ff488c9e4a0eae8616fcd81 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Thu, 23 Sep 2010 22:41:01 -0400 Subject: [PATCH 3/8] optimistically retry EntryNodes on socks request We used to mark all our known bridges up when they're all down and we get a new socks request. Now do that when we've set EntryNodes too. --- src/or/circuitbuild.c | 29 +++++++++++++++++------------ src/or/circuitbuild.h | 4 ++-- src/or/circuituse.c | 8 +++++--- 3 files changed, 24 insertions(+), 17 deletions(-) diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 90ae92a451..a14ab6a46b 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4583,24 +4583,27 @@ any_pending_bridge_descriptor_fetches(void) return 0; } -/** Return 1 if we have at least one descriptor for a bridge and - * all descriptors we know are down. Else return 0. If act is - * 1, then mark the down bridges up; else just observe and report. */ +/** Return 1 if we have at least one descriptor for an entry guard + * (bridge or member of EntryNodes) and all descriptors we know are + * down. Else return 0. If act is 1, then mark the down guards + * up; else just observe and report. */ static int -bridges_retry_helper(int act) +entries_retry_helper(or_options_t *options, int act) { routerinfo_t *ri; int any_known = 0; int any_running = 0; + int purpose = options->UseBridges ? + ROUTER_PURPOSE_BRIDGE : ROUTER_PURPOSE_GENERAL; if (!entry_guards) entry_guards = smartlist_create(); SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e, { ri = router_get_by_digest(e->identity); - if (ri && ri->purpose == ROUTER_PURPOSE_BRIDGE) { + if (ri && ri->purpose == purpose) { any_known = 1; if (ri->is_running) - any_running = 1; /* some bridge is both known and running */ + any_running = 1; /* some entry is both known and running */ else if (act) { /* mark it for retry */ ri->is_running = 1; e->can_retry = 1; @@ -4613,19 +4616,21 @@ bridges_retry_helper(int act) return any_known && !any_running; } -/** Do we know any descriptors for our bridges, and are they all - * down? */ +/** Do we know any descriptors for our bridges / entrynodes, and are + * all the ones we have descriptors for down? */ int -bridges_known_but_down(void) +entries_known_but_down(or_options_t *options) { - return bridges_retry_helper(0); + tor_assert(entry_list_is_constrained(options)); + return entries_retry_helper(options, 0); } /** Mark all down known bridges up. */ void -bridges_retry_all(void) +entries_retry_all(or_options_t *options) { - bridges_retry_helper(1); + tor_assert(entry_list_is_constrained(options)); + entries_retry_helper(options, 1); } /** Release all storage held by the list of entry guards and related diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h index 6cc461c98d..033dd79c4c 100644 --- a/src/or/circuitbuild.h +++ b/src/or/circuitbuild.h @@ -72,8 +72,8 @@ void fetch_bridge_descriptors(or_options_t *options, time_t now); void learned_bridge_descriptor(routerinfo_t *ri, int from_cache); int any_bridge_descriptors_known(void); int any_pending_bridge_descriptor_fetches(void); -int bridges_known_but_down(void); -void bridges_retry_all(void); +int entries_known_but_down(or_options_t *options); +void entries_retry_all(or_options_t *options); void entry_guards_free_all(void); diff --git a/src/or/circuituse.c b/src/or/circuituse.c index e9335b18d6..ee1705b4c9 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -1192,11 +1192,13 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn, int severity = LOG_NOTICE; /* FFFF if this is a tunneled directory fetch, don't yell * as loudly. the user doesn't even know it's happening. */ - if (options->UseBridges && bridges_known_but_down()) { + if (entry_list_is_constrained(options) && + entries_known_but_down(options)) { log_fn(severity, LD_APP|LD_DIR, "Application request when we haven't used client functionality " - "lately. Optimistically trying known bridges again."); - bridges_retry_all(); + "lately. Optimistically trying known %s again.", + options->UseBridges ? "bridges" : "entrynodes"); + entries_retry_all(options); } else if (!options->UseBridges || any_bridge_descriptors_known()) { log_fn(severity, LD_APP|LD_DIR, "Application request when we haven't used client functionality " From 7de1caa33f025db5474dba5f7e256d28c5ab4969 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Tue, 28 Sep 2010 21:59:31 -0400 Subject: [PATCH 4/8] Actually notice when our last entrynode goes down Otherwise we'd never set have_minimum_dir_info to false, so the "optimistic retry" would never trigger. --- src/or/circuitbuild.c | 4 ++-- src/or/routerlist.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index a14ab6a46b..a9920e2bcb 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4605,7 +4605,7 @@ entries_retry_helper(or_options_t *options, int act) if (ri->is_running) any_running = 1; /* some entry is both known and running */ else if (act) { /* mark it for retry */ - ri->is_running = 1; + router_set_status(ri->cache_info.identity_digest, 1); e->can_retry = 1; e->bad_since = 0; } @@ -4625,7 +4625,7 @@ entries_known_but_down(or_options_t *options) return entries_retry_helper(options, 0); } -/** Mark all down known bridges up. */ +/** Mark all down known bridges / entrynodes up. */ void entries_retry_all(or_options_t *options) { diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 1f542b1f46..a6ca03cde3 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -4786,7 +4786,7 @@ update_router_have_minimum_dir_info(void) count_usable_descriptors(&num_present, &num_usable, consensus, options, now, options->EntryNodes); - if (num_usable && (num_present == 0)) { + if (!num_usable || !num_present) { tor_snprintf(dir_info_status, sizeof(dir_info_status), "We have only %d/%d usable entry node descriptors.", num_present, num_usable); From 9997676802c140aceddb849090c7b3795fc83361 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Tue, 28 Sep 2010 22:32:38 -0400 Subject: [PATCH 5/8] handle ugly edge case in retrying entrynodes Specifically, a circ attempt that we'd launched while the network was down could timeout after we've marked our entrynodes up, marking them back down again. The fix is to annotate as bad the OR conns that were around before we did the retry, so if a circuit that's attached to them times out we don't do anything about it. --- src/or/circuitbuild.c | 11 ++++++++++- src/or/circuituse.c | 9 ++++++++- src/or/connection_or.c | 16 ++++++++++------ src/or/connection_or.h | 2 +- src/or/main.c | 2 +- 5 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index a9920e2bcb..dd92e78cb5 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4604,7 +4604,16 @@ entries_retry_helper(or_options_t *options, int act) any_known = 1; if (ri->is_running) any_running = 1; /* some entry is both known and running */ - else if (act) { /* mark it for retry */ + else if (act) { + /* Mark-for-close all TLS connections to this node, since + * otherwise there could be one that started 30 seconds + * ago, and in 30 seconds it will time out, causing us to mark + * the node down and undermine the retry attempt. We mark even + * the established conns, since if the network just came back + * we'll want to attach circuits to fresh conns. */ + connection_or_set_bad_connections(ri->cache_info.identity_digest, 1); + + /* mark it for retry */ router_set_status(ri->cache_info.identity_digest, 1); e->can_retry = 1; e->bad_since = 0; diff --git a/src/or/circuituse.c b/src/or/circuituse.c index ee1705b4c9..f651ef7c33 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -955,8 +955,15 @@ circuit_build_failed(origin_circuit_t *circ) * to blame, blame it. Also, avoid this relay for a while, and * fail any one-hop directory fetches destined for it. */ const char *n_conn_id = circ->cpath->extend_info->identity_digest; + int already_marked = 0; if (circ->_base.n_conn) { or_connection_t *n_conn = circ->_base.n_conn; + if (n_conn->is_bad_for_new_circs) { + /* no need to blow away circuits/streams/etc. Also, don't mark this + * router as newly down, since maybe this was just an old circuit + * attempt that's finally timing out now. */ + already_marked = 1; + } log_info(LD_OR, "Our circuit failed to get a response from the first hop " "(%s:%d). I'm going to try to rotate to a better connection.", @@ -966,7 +973,7 @@ circuit_build_failed(origin_circuit_t *circ) log_info(LD_OR, "Our circuit died before the first hop with no connection"); } - if (n_conn_id) { + if (n_conn_id && !already_marked) { entry_guard_register_connect_status(n_conn_id, 0, 1, time(NULL)); /* if there are any one-hop streams waiting on this circuit, fail * them now so they can retry elsewhere. */ diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 6b648b124d..836e7faef5 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -610,7 +610,7 @@ connection_or_get_for_extend(const char *digest, * appropriate. Helper for connection_or_set_bad_connections(). */ static void -connection_or_group_set_badness(or_connection_t *head) +connection_or_group_set_badness(or_connection_t *head, int force) { or_connection_t *or_conn = NULL, *best = NULL; int n_old = 0, n_inprogress = 0, n_canonical = 0, n_other = 0; @@ -622,8 +622,9 @@ connection_or_group_set_badness(or_connection_t *head) if (or_conn->_base.marked_for_close || or_conn->is_bad_for_new_circs) continue; - if (or_conn->_base.timestamp_created + TIME_BEFORE_OR_CONN_IS_TOO_OLD - < now) { + if (force || + or_conn->_base.timestamp_created + TIME_BEFORE_OR_CONN_IS_TOO_OLD + < now) { log_info(LD_OR, "Marking OR conn to %s:%d as too old for new circuits " "(fd %d, %d secs old).", @@ -718,8 +719,10 @@ connection_or_group_set_badness(or_connection_t *head) } } -/** Go through all the OR connections, and set the is_bad_for_new_circs +/** Go through all the OR connections (or if digest is non-NULL, just + * the OR connections with that digest), and set the is_bad_for_new_circs * flag on: + * - all connections if force is true. * - all connections that are too old. * - all open non-canonical connections for which a canonical connection * exists to the same router. @@ -732,13 +735,14 @@ connection_or_group_set_badness(or_connection_t *head) * better than another. */ void -connection_or_set_bad_connections(void) +connection_or_set_bad_connections(const char *digest, int force) { if (!orconn_identity_map) return; DIGESTMAP_FOREACH(orconn_identity_map, identity, or_connection_t *, conn) { - connection_or_group_set_badness(conn); + if (!digest || !memcmp(digest, conn->identity_digest, DIGEST_LEN)) + connection_or_group_set_badness(conn, force); } DIGESTMAP_FOREACH_END; } diff --git a/src/or/connection_or.h b/src/or/connection_or.h index 717630217c..216a9bd648 100644 --- a/src/or/connection_or.h +++ b/src/or/connection_or.h @@ -18,7 +18,7 @@ or_connection_t *connection_or_get_for_extend(const char *digest, const tor_addr_t *target_addr, const char **msg_out, int *launch_out); -void connection_or_set_bad_connections(void); +void connection_or_set_bad_connections(const char *digest, int force); int connection_or_reached_eof(or_connection_t *conn); int connection_or_process_inbuf(or_connection_t *conn); diff --git a/src/or/main.c b/src/or/main.c index b59351cf09..582a1c287b 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -1173,7 +1173,7 @@ run_scheduled_events(time_t now) circuit_expire_old_circuits_serverside(now); /** 5. We do housekeeping for each connection... */ - connection_or_set_bad_connections(); + connection_or_set_bad_connections(NULL, 0); for (i=0;i Date: Tue, 28 Sep 2010 22:49:36 -0400 Subject: [PATCH 6/8] a changelog entry for the entrynodes retry mess --- changes/bug1882 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 changes/bug1882 diff --git a/changes/bug1882 b/changes/bug1882 new file mode 100644 index 0000000000..d495d2f418 --- /dev/null +++ b/changes/bug1882 @@ -0,0 +1,4 @@ + o Minor features: + - If we've configured EntryNodes and our network goes away and/or all + our entrynodes get marked down, optimistically retry them all when + a new socks application request appears. Fixes bug 1882. From 512433346f01f054e99c2dccede324a41a819fe8 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Tue, 28 Sep 2010 23:27:00 -0400 Subject: [PATCH 7/8] improve code comments, based on comments from nick --- src/or/circuitbuild.c | 4 ++-- src/or/circuituse.c | 10 +++++++--- src/or/connection_or.c | 31 +++++++++++++++++-------------- 3 files changed, 26 insertions(+), 19 deletions(-) diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index dd92e78cb5..2b4540bf3b 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -4605,7 +4605,7 @@ entries_retry_helper(or_options_t *options, int act) if (ri->is_running) any_running = 1; /* some entry is both known and running */ else if (act) { - /* Mark-for-close all TLS connections to this node, since + /* Mark all current connections to this OR as unhealthy, since * otherwise there could be one that started 30 seconds * ago, and in 30 seconds it will time out, causing us to mark * the node down and undermine the retry attempt. We mark even @@ -4613,7 +4613,7 @@ entries_retry_helper(or_options_t *options, int act) * we'll want to attach circuits to fresh conns. */ connection_or_set_bad_connections(ri->cache_info.identity_digest, 1); - /* mark it for retry */ + /* mark this entry node for retry */ router_set_status(ri->cache_info.identity_digest, 1); e->can_retry = 1; e->bad_since = 0; diff --git a/src/or/circuituse.c b/src/or/circuituse.c index f651ef7c33..f369678ab0 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -959,9 +959,13 @@ circuit_build_failed(origin_circuit_t *circ) if (circ->_base.n_conn) { or_connection_t *n_conn = circ->_base.n_conn; if (n_conn->is_bad_for_new_circs) { - /* no need to blow away circuits/streams/etc. Also, don't mark this - * router as newly down, since maybe this was just an old circuit - * attempt that's finally timing out now. */ + /* We only want to blame this router when a fresh healthy + * connection fails. So don't mark this router as newly failed, + * since maybe this was just an old circuit attempt that's + * finally timing out now. Also, there's no need to blow away + * circuits/streams/etc, since the failure of an unhealthy conn + * doesn't tell us much about whether a healthy conn would + * succeed. */ already_marked = 1; } log_info(LD_OR, diff --git a/src/or/connection_or.c b/src/or/connection_or.c index 836e7faef5..09f310a3df 100644 --- a/src/or/connection_or.c +++ b/src/or/connection_or.c @@ -606,8 +606,21 @@ connection_or_get_for_extend(const char *digest, #define TIME_BEFORE_OR_CONN_IS_TOO_OLD (60*60*24*7) /** Given the head of the linked list for all the or_connections with a given - * identity, set elements of that list as is_bad_for_new_circs() as - * appropriate. Helper for connection_or_set_bad_connections(). + * identity, set elements of that list as is_bad_for_new_circs as + * appropriate. Helper for connection_or_set_bad_connections(). + * + * Specifically, we set the is_bad_for_new_circs flag on: + * - all connections if force is true. + * - all connections that are too old. + * - all open non-canonical connections for which a canonical connection + * exists to the same router. + * - all open canonical connections for which a 'better' canonical + * connection exists to the same router. + * - all open non-canonical connections for which a 'better' non-canonical + * connection exists to the same router at the same address. + * + * See connection_or_is_better() for our idea of what makes one OR connection + * better than another. */ static void connection_or_group_set_badness(or_connection_t *head, int force) @@ -721,18 +734,8 @@ connection_or_group_set_badness(or_connection_t *head, int force) /** Go through all the OR connections (or if digest is non-NULL, just * the OR connections with that digest), and set the is_bad_for_new_circs - * flag on: - * - all connections if force is true. - * - all connections that are too old. - * - all open non-canonical connections for which a canonical connection - * exists to the same router. - * - all open canonical connections for which a 'better' canonical - * connection exists to the same router. - * - all open non-canonical connections for which a 'better' non-canonical - * connection exists to the same router at the same address. - * - * See connection_or_is_better() for our idea of what makes one OR connection - * better than another. + * flag based on the rules in connection_or_group_set_badness() (or just + * always set it if force is true). */ void connection_or_set_bad_connections(const char *digest, int force) From a58610a87e27e446b347f49e847da1cd460ffa81 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Tue, 28 Sep 2010 23:50:56 -0400 Subject: [PATCH 8/8] even more comment --- src/or/or.h | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/or/or.h b/src/or/or.h index a48df38cdb..62985ca94a 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1047,7 +1047,10 @@ typedef struct or_connection_t { * NETINFO cell listed the address we're connected to as recognized. */ unsigned int is_canonical:1; /** True iff this connection shouldn't get any new circs attached to it, - * because the connection is too old, or because there's a better one, etc. + * because the connection is too old, or because there's a better one. + * More generally, this flag is used to note an unhealthy connection; + * for example, if a bad connection fails we shouldn't assume that the + * router itself has a problem. */ unsigned int is_bad_for_new_circs:1; uint8_t link_proto; /**< What protocol version are we using? 0 for