Forráskód Böngészése

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

Roger Dingledine 19 éve
szülő
commit
f468ff04ea
4 módosított fájl, 35 hozzáadás és 1 törlés
  1. 12 0
      src/or/circuituse.c
  2. 2 1
      src/or/directory.c
  3. 19 0
      src/or/main.c
  4. 2 0
      src/or/or.h

+ 12 - 0
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);

+ 2 - 1
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. */
   }
 }
 

+ 19 - 0
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();

+ 2 - 0
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);