浏览代码

If you're using bridges, generate "bootstrap problem" warnings
as soon as you run out of working bridges, rather than waiting
for ten failures -- which will never happen if you have less than
ten bridges.


svn:r15368

Roger Dingledine 17 年之前
父节点
当前提交
94dabd2c23
共有 6 个文件被更改,包括 45 次插入6 次删除
  1. 9 0
      ChangeLog
  2. 1 1
      doc/TODO
  3. 21 0
      src/or/circuitbuild.c
  4. 4 3
      src/or/connection.c
  5. 9 2
      src/or/control.c
  6. 1 0
      src/or/or.h

+ 9 - 0
ChangeLog

@@ -37,9 +37,18 @@ Changes in version 0.2.1.2-alpha - 2008-06-??
       from cannibalized circuits are completely ignored and not included in
       from cannibalized circuits are completely ignored and not included in
       rendezvous service descriptors. This might be another reason for delay
       rendezvous service descriptors. This might be another reason for delay
       in making a hidden service available. Bugfix on 0.2.0.14-alpha.
       in making a hidden service available. Bugfix on 0.2.0.14-alpha.
+
+  o Bootstrapping bugfixes:
     - Directory authorities shouldn't complain about bootstrapping
     - Directory authorities shouldn't complain about bootstrapping
       problems just because they do a lot of reachability testing and
       problems just because they do a lot of reachability testing and
       some of the connection attempts fail.
       some of the connection attempts fail.
+    - Start sending "count" and "recommendation" key/value pairs in
+      bootstrap problem status events, so the controller can hear about
+      problems even before Tor decides they're worth reporting for sure.
+    - If you're using bridges, generate "bootstrap problem" warnings
+      as soon as you run out of working bridges, rather than waiting
+      for ten failures -- which will never happen if you have less than
+      ten bridges.
 
 
 
 
 Changes in version 0.2.1.1-alpha - 2008-06-13
 Changes in version 0.2.1.1-alpha - 2008-06-13

+ 1 - 1
doc/TODO

@@ -340,7 +340,7 @@ R - investigate: it looks like if the bridge authority is unreachable,
   o directory authorities shouldn't complain about bootstrapping problems
   o directory authorities shouldn't complain about bootstrapping problems
     just because they do a lot of reachability testing and some of
     just because they do a lot of reachability testing and some of
     it fails.
     it fails.
-R * if your bridge is unreachable, it won't generate enough connection
+  o if your bridge is unreachable, it won't generate enough connection
     failures to generate a bootstrap problem event.
     failures to generate a bootstrap problem event.
 R - if "no running bridges known", an application request should make
 R - if "no running bridges known", an application request should make
     us retry all our bridges.
     us retry all our bridges.

+ 21 - 0
src/or/circuitbuild.c

@@ -3068,6 +3068,27 @@ any_bridge_descriptors_known(void)
   return choose_random_entry(NULL)!=NULL ? 1 : 0;
   return choose_random_entry(NULL)!=NULL ? 1 : 0;
 }
 }
 
 
+/** Return 1 if there are any directory conns fetching bridge descriptors
+ * that aren't marked for close. We use this to guess if we should tell
+ * the controller that we have a problem. */
+int
+any_pending_bridge_descriptor_fetches(void)
+{
+  smartlist_t *conns = get_connection_array();
+  SMARTLIST_FOREACH(conns, connection_t *, conn,
+  {
+    if (conn->type == CONN_TYPE_DIR &&
+        conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC &&
+        TO_DIR_CONN(conn)->router_purpose == ROUTER_PURPOSE_BRIDGE &&
+        !conn->marked_for_close &&
+        conn->linked && !conn->linked_conn->marked_for_close) {
+      log_debug(LD_DIR, "found one: %s", conn->address);
+      return 1;
+    }
+  });
+  return 0;
+}
+
 /** Return 1 if we have at least one descriptor for a bridge and
 /** Return 1 if we have at least one descriptor for a bridge and
  * all descriptors we know are down. Else return 0. If <b>act</b> is
  * 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. */
  * 1, then mark the down bridges up; else just observe and report. */

+ 4 - 3
src/or/connection.c

@@ -494,6 +494,10 @@ connection_about_to_close_connection(connection_t *conn)
       or_conn = TO_OR_CONN(conn);
       or_conn = TO_OR_CONN(conn);
       /* Remember why we're closing this connection. */
       /* Remember why we're closing this connection. */
       if (conn->state != OR_CONN_STATE_OPEN) {
       if (conn->state != OR_CONN_STATE_OPEN) {
+        /* Inform any pending (not attached) circs that they should
+         * give up. */
+        circuit_n_conn_done(TO_OR_CONN(conn), 0);
+        /* now mark things down as needed */
         if (connection_or_nonopen_was_started_here(or_conn)) {
         if (connection_or_nonopen_was_started_here(or_conn)) {
           or_options_t *options = get_options();
           or_options_t *options = get_options();
           rep_hist_note_connect_failed(or_conn->identity_digest, now);
           rep_hist_note_connect_failed(or_conn->identity_digest, now);
@@ -517,9 +521,6 @@ connection_about_to_close_connection(connection_t *conn)
                 orconn_end_reason_to_control_string(reason), reason);
                 orconn_end_reason_to_control_string(reason), reason);
           }
           }
         }
         }
-        /* Inform any pending (not attached) circs that they should
-         * give up. */
-        circuit_n_conn_done(TO_OR_CONN(conn), 0);
       } else if (conn->hold_open_until_flushed) {
       } else if (conn->hold_open_until_flushed) {
         /* We only set hold_open_until_flushed when we're intentionally
         /* We only set hold_open_until_flushed when we're intentionally
          * closing a connection. */
          * closing a connection. */

+ 9 - 2
src/or/control.c

@@ -3868,12 +3868,19 @@ control_event_bootstrap_problem(const char *warn, int reason)
   if (bootstrap_problems >= BOOTSTRAP_PROBLEM_THRESHOLD)
   if (bootstrap_problems >= BOOTSTRAP_PROBLEM_THRESHOLD)
     recommendation = "warn";
     recommendation = "warn";
 
 
+  if (get_options()->UseBridges &&
+      !any_bridge_descriptors_known() &&
+      !any_pending_bridge_descriptor_fetches())
+    recommendation = "warn";
+
   while (status>=0 && bootstrap_status_to_string(status, &tag, &summary) < 0)
   while (status>=0 && bootstrap_status_to_string(status, &tag, &summary) < 0)
     status--; /* find a recognized status string based on current progress */
     status--; /* find a recognized status string based on current progress */
 
 
-  log_warn(LD_CONTROL, "Problem bootstrapping. Stuck at %d%%: %s. (%s; %s)",
+  log_warn(LD_CONTROL, "Problem bootstrapping. Stuck at %d%%: %s. (%s; %s; "
+           "count %d; recommendation %s)",
            status, summary, warn,
            status, summary, warn,
-           orconn_end_reason_to_control_string(reason));
+           orconn_end_reason_to_control_string(reason),
+           bootstrap_problems, recommendation);
   tor_snprintf(buf, sizeof(buf),
   tor_snprintf(buf, sizeof(buf),
       "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\" WARNING=\"%s\" REASON=%s "
       "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\" WARNING=\"%s\" REASON=%s "
       "COUNT=%d RECOMMENDATION=%s",
       "COUNT=%d RECOMMENDATION=%s",

+ 1 - 0
src/or/or.h

@@ -2600,6 +2600,7 @@ void retry_bridge_descriptor_fetch_directly(char *digest);
 void fetch_bridge_descriptors(time_t now);
 void fetch_bridge_descriptors(time_t now);
 void learned_bridge_descriptor(routerinfo_t *ri, int from_cache);
 void learned_bridge_descriptor(routerinfo_t *ri, int from_cache);
 int any_bridge_descriptors_known(void);
 int any_bridge_descriptors_known(void);
+int any_pending_bridge_descriptor_fetches(void);
 int bridges_known_but_down(void);
 int bridges_known_but_down(void);
 void bridges_retry_all(void);
 void bridges_retry_all(void);