From f468ff04eaebba7c761f62b2b96b03a3add95454 Mon Sep 17 00:00:00 2001 From: Roger Dingledine Date: Fri, 7 Jan 2005 15:57:57 +0000 Subject: [PATCH] when we haven't fetched a directory yet, or the last time we tried they were all unreachable, assume we are not connected to the network. when an application request comes in during this state, be optimistic and assume we just reconnected. fetch a new directory and if it works, begin making circuits. svn:r3327 --- src/or/circuituse.c | 12 ++++++++++++ src/or/directory.c | 3 ++- src/or/main.c | 19 +++++++++++++++++++ src/or/or.h | 2 ++ 4 files changed, 35 insertions(+), 1 deletion(-) diff --git a/src/or/circuituse.c b/src/or/circuituse.c index dcd92af8b7..2e7169b7cb 100644 --- a/src/or/circuituse.c +++ b/src/or/circuituse.c @@ -717,6 +717,18 @@ circuit_get_open_circ_or_launch(connection_t *conn, return 1; /* we're happy */ } + if (!has_fetched_directory) { + if (!connection_get_by_type(CONN_TYPE_DIR)) { + log_fn(LOG_NOTICE,"Application request when we're believed to be offline. Optimistically trying again."); + directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR, NULL, 1); + } + /* the stream will be dealt with when has_fetched_directory becomes + * 1, or when all directory attempts fail and directory_all_unreachable() + * kills it. + */ + return 0; + } + /* Do we need to check exit policy? */ if (!is_resolve && !connection_edge_is_rendezvous_stream(conn)) { addr = client_dns_lookup_entry(conn->socks_request->address); diff --git a/src/or/directory.c b/src/or/directory.c index 696e113486..c6ec9a58b9 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -184,7 +184,8 @@ directory_get_from_dirserver(uint8_t purpose, const char *resource, else if (ds) directory_initiate_command_trusted_dir(ds, purpose, resource, NULL, 0); else { - log_fn(LOG_WARN,"No running dirservers known. Not trying. (purpose %d)", purpose); + log_fn(LOG_NOTICE,"No running dirservers known. Not trying. (purpose %d)", purpose); + directory_all_unreachable(time(NULL)); /* remember we tried them all and failed. */ } } diff --git a/src/or/main.c b/src/or/main.c index 2b9c67234f..fffa039fa4 100644 --- a/src/or/main.c +++ b/src/or/main.c @@ -402,6 +402,25 @@ static void conn_close_if_marked(int i) { } } +/** We've just tried every dirserver we know about, and none of + * them were reachable. Assume the network is down. Change state + * so next time an application connection arrives we'll delay it + * and try another directory fetch. Kill off all the circuit_wait + * streams that are waiting now, since they will all timeout anyway. + */ +void directory_all_unreachable(time_t now) { + connection_t *conn; + + has_fetched_directory=0; + + while ((conn = connection_get_by_type_state(CONN_TYPE_AP, + AP_CONN_STATE_CIRCUIT_WAIT))) { + conn->has_sent_end = 1; /* it's not connected anywhere, so no need to end */ + log_fn(LOG_NOTICE,"Network down? Failing connection to '%s'.", conn->address); + connection_mark_for_close(conn); + } +} + /** This function is called whenever we successfully pull down a directory */ void directory_has_arrived(time_t now) { or_options_t *options = get_options(); diff --git a/src/or/or.h b/src/or/or.h index 0535a7e4ef..e5fe36966d 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1382,7 +1382,9 @@ int connection_is_writing(connection_t *conn); void connection_stop_writing(connection_t *conn); void connection_start_writing(connection_t *conn); +void directory_all_unreachable(time_t now); void directory_has_arrived(time_t now); + int authdir_mode(or_options_t *options); int clique_mode(or_options_t *options); int server_mode(or_options_t *options);