aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/or/circuitbuild.c37
-rw-r--r--src/or/circuituse.c23
-rw-r--r--src/or/or.h2
3 files changed, 47 insertions, 15 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index 83f4a50a1..58879674c 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -294,7 +294,7 @@ origin_circuit_init(uint8_t purpose, int onehop_tunnel,
return circ;
}
-/** Build a new circuit for <b>purpose</b>. If <b>info</b>
+/** Build a new circuit for <b>purpose</b>. If <b>exit</b>
* is defined, then use that as your exit router, else choose a suitable
* exit node.
*
@@ -2860,17 +2860,19 @@ learned_bridge_descriptor(routerinfo_t *ri)
int
any_bridge_descriptors_known(void)
{
+ tor_assert(get_options()->UseBridges);
return choose_random_entry(NULL)!=NULL ? 1 : 0;
}
-#if 0
/** Return 1 if we have at least one descriptor for a bridge and
- * all descriptors we know are down. Else return 0. */
-int
-all_bridges_down(void)
+ * all descriptors we know are down. Else return 0. If <b>act</b> is
+ * 1, then mark the down bridges up; else just observe and report. */
+static int
+bridges_retry_helper(int act)
{
routerinfo_t *ri;
int any_known = 0;
+ int any_running = 0;
if (!entry_guards)
entry_guards = smartlist_create();
SMARTLIST_FOREACH(entry_guards, entry_guard_t *, e,
@@ -2879,12 +2881,31 @@ all_bridges_down(void)
if (ri && ri->purpose == ROUTER_PURPOSE_BRIDGE) {
any_known = 1;
if (ri->is_running)
- return 0; /* some bridge is both known and running */
+ any_running = 1; /* some bridge is both known and running */
+ else if (act) { /* mark it for retry */
+ ri->is_running = 1;
+ e->can_retry = 1;
+ e->bad_since = 0;
+ }
}
});
- return any_known;
+ return any_known && !any_running;
+}
+
+/** Do we know any descriptors for our bridges, and are they all
+ * down? */
+int
+bridges_should_be_retried(void)
+{
+ return bridges_retry_helper(0);
+}
+
+/** Mark all down known bridges up. */
+void
+bridges_retry_all(void)
+{
+ bridges_retry_helper(1);
}
-#endif
/** Release all storage held by the list of entry guards and related
* memory structs. */
diff --git a/src/or/circuituse.c b/src/or/circuituse.c
index 6ae4adac1..5b866b9df 100644
--- a/src/or/circuituse.c
+++ b/src/or/circuituse.c
@@ -813,8 +813,9 @@ circuit_launch_by_router(uint8_t purpose, int onehop_tunnel,
return circ;
}
-/** Launch a new circuit with purpose <b>purpose</b> and exit node <b>info</b>
- * (or NULL to select a random exit node). If <b>need_uptime</b> is true,
+/** Launch a new circuit with purpose <b>purpose</b> and exit node
+ * <b>extend_info</b> (or NULL to select a random exit node).
+ * If <b>need_uptime</b> is true,
* choose among routers with high uptime. If <b>need_capacity</b> is true,
* choose among routers with high bandwidth. If <b>internal</b> is true, the
* last hop need not be an exit node. Return the newly allocated circuit on
@@ -942,6 +943,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
int check_exit_policy;
int need_uptime, need_internal;
int want_onehop;
+ or_options_t *options = get_options();
tor_assert(conn);
tor_assert(circp);
@@ -952,7 +954,7 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
want_onehop = conn->socks_request->command == SOCKS_COMMAND_CONNECT_DIR;
need_uptime = (conn->socks_request->command == SOCKS_COMMAND_CONNECT) &&
- smartlist_string_num_isin(get_options()->LongLivedPorts,
+ smartlist_string_num_isin(options->LongLivedPorts,
conn->socks_request->port);
need_internal = desired_circuit_purpose != CIRCUIT_PURPOSE_C_GENERAL;
@@ -966,10 +968,17 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
if (!want_onehop && !router_have_minimum_dir_info()) {
if (!connection_get_by_type(CONN_TYPE_DIR)) {
- log_notice(LD_APP|LD_DIR,
- "Application request when we're believed to be "
- "offline. Optimistically trying directory fetches again.");
- routerlist_retry_directory_downloads(time(NULL));
+ if (options->UseBridges && bridges_should_be_retried()) {
+ log_notice(LD_APP|LD_DIR,
+ "Application request when we're believed to be "
+ "offline. Optimistically trying known bridges again.");
+ bridges_retry_all();
+ } else if (!options->UseBridges || any_bridge_descriptors_known()) {
+ log_notice(LD_APP|LD_DIR,
+ "Application request when we're believed to be "
+ "offline. Optimistically trying directory fetches again.");
+ routerlist_retry_directory_downloads(time(NULL));
+ }
}
/* the stream will be dealt with when router_have_minimum_dir_info becomes
* 1, or when all directory attempts fail and directory_all_unreachable()
diff --git a/src/or/or.h b/src/or/or.h
index 039fa052e..9a487fbd9 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -2264,6 +2264,8 @@ void bridge_add_from_config(uint32_t addr, uint16_t port, char *digest);
void fetch_bridge_descriptors(time_t now);
void learned_bridge_descriptor(routerinfo_t *ri);
int any_bridge_descriptors_known(void);
+int bridges_should_be_retried(void);
+void bridges_retry_all(void);
void entry_guards_free_all(void);