瀏覽代碼

r11700@catbus: nickm | 2007-02-08 02:03:50 -0500
Fix several bugs in computing recommended versions. 1) refactor is-this-version-good handling and which-vesions-are-good handling to be in the same place. 2) a version is recommended if more than half of the versioning authorities like it, not >= half. 3) "NEW_IN_SERIES" should mean, "I don't know of an 0.1.1.x this recent, and there are some 0.1.2.x versions out", not "I don't know of an 0.1.1.x this recent, but I know some older ones." This should resolve bug 383.


svn:r9523

Nick Mathewson 18 年之前
父節點
當前提交
1e2d5f30ff
共有 5 個文件被更改,包括 77 次插入50 次删除
  1. 3 0
      ChangeLog
  2. 2 1
      doc/spec/path-spec.txt
  3. 2 1
      src/or/or.h
  4. 69 47
      src/or/routerlist.c
  5. 1 1
      src/or/routerparse.c

+ 3 - 0
ChangeLog

@@ -11,6 +11,9 @@ Changes in version 0.1.2.8-alpha - 2007-??-??
     - Report events where a resolve succeeded or where we got a socks
     - Report events where a resolve succeeded or where we got a socks
       protocol error correctly, rather than calling both of them "INTERNAL".
       protocol error correctly, rather than calling both of them "INTERNAL".
 
 
+  o Minor bugfixes (other)
+    - Display correct results when reporting which versions are recommended,
+      and how recommended they are.  (Resolves bug 383.)
 
 
 Changes in version 0.1.2.7-alpha - 2007-02-06
 Changes in version 0.1.2.7-alpha - 2007-02-06
   o Major bugfixes (rate limiting):
   o Major bugfixes (rate limiting):

+ 2 - 1
doc/spec/path-spec.txt

@@ -124,7 +124,8 @@ of their choices.
 
 
    Tor servers test reachability of their ORPort on start and whenever
    Tor servers test reachability of their ORPort on start and whenever
    their IP address changes.
    their IP address changes.
-   XXXX
+
+   [XXXX arma: write this.] 
 
 
 2.1.4. Hidden-service circuits
 2.1.4. Hidden-service circuits
 
 

+ 2 - 1
src/or/or.h

@@ -2984,7 +2984,8 @@ typedef enum version_status_t {
   VS_OLD=1, /**< This version is older than any recommended version. */
   VS_OLD=1, /**< This version is older than any recommended version. */
   VS_NEW=2, /**< This version is newer than any recommended version. */
   VS_NEW=2, /**< This version is newer than any recommended version. */
   VS_NEW_IN_SERIES=3, /**< This version is newer than any recommended version
   VS_NEW_IN_SERIES=3, /**< This version is newer than any recommended version
-                       * in its series, and such recommended versions exist. */
+                       * in its series, but later recommended versions exist.
+                       */
   VS_UNRECOMMENDED=4 /**< This version is not recommended (general case) */
   VS_UNRECOMMENDED=4 /**< This version is not recommended (general case) */
 } version_status_t;
 } version_status_t;
 
 

+ 69 - 47
src/or/routerlist.c

@@ -3029,27 +3029,48 @@ networkstatus_get_by_digest(const char *digest)
  * our server is broken, invalid, obsolete, etc. */
  * our server is broken, invalid, obsolete, etc. */
 #define SELF_OPINION_INTERVAL (90*60)
 #define SELF_OPINION_INTERVAL (90*60)
 
 
+/** Result of checking whether a version is recommended. */
+typedef struct combined_version_status_t {
+  /** How many networkstatuses claim to know about versions? */
+  int n_versioning;
+  /** What do the majority of networkstatuses believe about this version? */
+  version_status_t consensus;
+  /** How many networkstatuses constitute the majority? */
+  int n_concurring;
+} combined_version_status_t;
+
 /** Return a string naming the versions of Tor recommended by
 /** Return a string naming the versions of Tor recommended by
  * more than half the versioning networkstatuses. */
  * more than half the versioning networkstatuses. */
 static char *
 static char *
-compute_recommended_versions(time_t now, int client)
+compute_recommended_versions(time_t now, int client,
+                             const char *my_version,
+                             combined_version_status_t *status_out)
 {
 {
   int n_seen;
   int n_seen;
   char *current;
   char *current;
   smartlist_t *combined, *recommended;
   smartlist_t *combined, *recommended;
-  int n_versioning;
+  int n_versioning, n_recommending;
   char *result;
   char *result;
-  (void) now; /* right now, we consider *all* ors. */
+  /** holds the compromise status taken among all non-recommending
+   * authorities */
+  version_status_t consensus = VS_RECOMMENDED;
+  (void) now; /* right now, we consider *all* statuses, regardless of age. */
+
+  tor_assert(my_version);
+  tor_assert(status_out);
+
+  memset(status_out, 0, sizeof(combined_version_status_t));
 
 
   if (!networkstatus_list)
   if (!networkstatus_list)
     return tor_strdup("<none>");
     return tor_strdup("<none>");
 
 
   combined = smartlist_create();
   combined = smartlist_create();
-  n_versioning = 0;
+  n_versioning = n_recommending = 0;
   SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
   SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
     {
     {
       const char *vers;
       const char *vers;
       smartlist_t *versions;
       smartlist_t *versions;
+      version_status_t status;
       if (! ns->recommends_versions)
       if (! ns->recommends_versions)
         continue;
         continue;
       n_versioning++;
       n_versioning++;
@@ -3062,6 +3083,12 @@ compute_recommended_versions(time_t now, int client)
       sort_version_list(versions, 1);
       sort_version_list(versions, 1);
       smartlist_add_all(combined, versions);
       smartlist_add_all(combined, versions);
       smartlist_free(versions);
       smartlist_free(versions);
+
+      /* now, check _our_ version */
+      status = tor_version_is_obsolete(my_version, vers);
+      if (status == VS_RECOMMENDED)
+        n_recommending++;
+      consensus = version_status_join(status, consensus);
     });
     });
 
 
   sort_version_list(combined, 0);
   sort_version_list(combined, 0);
@@ -3074,13 +3101,13 @@ compute_recommended_versions(time_t now, int client)
       if (current && !strcmp(cp, current)) {
       if (current && !strcmp(cp, current)) {
         ++n_seen;
         ++n_seen;
       } else {
       } else {
-        if (n_seen >= n_versioning/2 && current)
+        if (n_seen > n_versioning/2 && current)
           smartlist_add(recommended, current);
           smartlist_add(recommended, current);
         n_seen = 0;
         n_seen = 0;
         current = cp;
         current = cp;
       }
       }
     });
     });
-  if (n_seen >= n_versioning/2 && current)
+  if (n_seen > n_versioning/2 && current)
     smartlist_add(recommended, current);
     smartlist_add(recommended, current);
 
 
   result = smartlist_join_strings(recommended, ", ", 0, NULL);
   result = smartlist_join_strings(recommended, ", ", 0, NULL);
@@ -3089,6 +3116,15 @@ compute_recommended_versions(time_t now, int client)
   smartlist_free(combined);
   smartlist_free(combined);
   smartlist_free(recommended);
   smartlist_free(recommended);
 
 
+  status_out->n_versioning = n_versioning;
+  if (n_recommending > n_versioning/2) {
+    status_out->consensus = VS_RECOMMENDED;
+    status_out->n_concurring = n_recommending;
+  } else {
+    status_out->consensus = consensus;
+    status_out->n_concurring = n_versioning - n_recommending;
+  }
+
   return result;
   return result;
 }
 }
 
 
@@ -3154,64 +3190,50 @@ routers_update_all_from_networkstatus(void)
   entry_guards_compute_status();
   entry_guards_compute_status();
 
 
   if (!have_warned_about_old_version &&
   if (!have_warned_about_old_version &&
-      have_tried_downloading_all_statuses(4)) {
-    int n_versioning = 0;
-    int n_recommended = 0;
+      have_tried_downloading_all_statuses(4)) { /*XXXX012This 4 is too magic.*/
+    combined_version_status_t st;
     int is_server = server_mode(get_options());
     int is_server = server_mode(get_options());
-    version_status_t consensus = VS_RECOMMENDED;
-    SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
-    {
-      version_status_t vs;
-      if (!ns->recommends_versions)
-        continue;
-      vs = tor_version_is_obsolete(
-              VERSION, is_server ? ns->server_versions : ns->client_versions);
-      if (vs == VS_RECOMMENDED)
-        ++n_recommended;
-      if (n_versioning++ == 0) {
-        consensus = vs;
-      } else if (consensus != vs) {
-        consensus = version_status_join(consensus, vs);
-      }
-    });
-    if (n_versioning && n_recommended <= n_versioning/2) {
-      if (consensus == VS_NEW || consensus == VS_NEW_IN_SERIES) {
+    char *recommended;
+
+    recommended = compute_recommended_versions(now, !is_server, VERSION, &st);
+
+    if (st.n_versioning) {
+      if (st.consensus == VS_RECOMMENDED) {
+        log_info(LD_GENERAL, "%d/%d statements from version-listing "
+                 "directory authorities say my version is ok.",
+                 st.n_concurring, st.n_versioning);
+      } else if (st.consensus == VS_NEW || st.consensus == VS_NEW_IN_SERIES) {
         if (!have_warned_about_new_version) {
         if (!have_warned_about_new_version) {
-          char *rec = compute_recommended_versions(now, !is_server);
           log_notice(LD_GENERAL, "This version of Tor (%s) is newer than any "
           log_notice(LD_GENERAL, "This version of Tor (%s) is newer than any "
-                 "recommended version%s, according to %d/%d network "
-                 "statuses. Versions recommended by more than %d "
+                 "recommended version%s, according to %d/%d version-listing "
+                 "network statuses. Versions recommended by more than %d "
                  "authorit%s are: %s",
                  "authorit%s are: %s",
                  VERSION,
                  VERSION,
-                 consensus == VS_NEW_IN_SERIES ? " in its series" : "",
-                 n_versioning-n_recommended, n_versioning, n_versioning/2,
-                 n_versioning/2 > 1 ? "ies" : "y", rec);
+                 st.consensus == VS_NEW_IN_SERIES ? " in its series" : "",
+                 st.n_concurring, st.n_versioning, st.n_versioning/2,
+                 st.n_versioning/2 > 1 ? "ies" : "y", recommended);
           have_warned_about_new_version = 1;
           have_warned_about_new_version = 1;
           control_event_general_status(LOG_WARN, "DANGEROUS_VERSION "
           control_event_general_status(LOG_WARN, "DANGEROUS_VERSION "
                  "CURRENT=%s REASON=%s RECOMMENDED=\"%s\"",
                  "CURRENT=%s REASON=%s RECOMMENDED=\"%s\"",
-                 VERSION, "NEW", rec);
-          tor_free(rec);
+                 VERSION, "NEW", recommended);
         }
         }
       } else {
       } else {
-        char *rec = compute_recommended_versions(now, !is_server);
         log_warn(LD_GENERAL, "Please upgrade! "
         log_warn(LD_GENERAL, "Please upgrade! "
-                 "This version of Tor (%s) is %s, according to "
-                 "%d/%d network statuses. Versions recommended by "
+                 "This version of Tor (%s) is %s, according to %d/%d version-"
+                 "listing network statuses. Versions recommended by "
                  "at least %d authorit%s are: %s",
                  "at least %d authorit%s are: %s",
-                 VERSION, consensus == VS_OLD ? "obsolete" : "not recommended",
-                 n_versioning-n_recommended, n_versioning, n_versioning/2,
-                 n_versioning/2 > 1 ? "ies" : "y", rec);
+                 VERSION,
+                 st.consensus == VS_OLD ? "obsolete" : "not recommended",
+                 st.n_concurring, st.n_versioning, st.n_versioning/2,
+                 st.n_versioning/2 > 1 ? "ies" : "y", recommended);
         have_warned_about_old_version = 1;
         have_warned_about_old_version = 1;
         control_event_general_status(LOG_WARN, "DANGEROUS_VERSION "
         control_event_general_status(LOG_WARN, "DANGEROUS_VERSION "
                  "CURRENT=%s REASON=%s RECOMMENDED=\"%s\"",
                  "CURRENT=%s REASON=%s RECOMMENDED=\"%s\"",
-                 VERSION, consensus == VS_OLD ? "OLD" : "UNRECOMMENDED", rec);
-        tor_free(rec);
+                 VERSION, st.consensus == VS_OLD ? "OLD" : "UNRECOMMENDED",
+                 recommended);
       }
       }
-    } else {
-      log_info(LD_GENERAL, "%d/%d statements from "
-               "directory authorities say my version is ok.",
-               n_recommended, n_versioning);
     }
     }
+    tor_free(recommended);
   }
   }
 
 
   routerstatus_list_has_changed = 0;
   routerstatus_list_has_changed = 0;

+ 1 - 1
src/or/routerparse.c

@@ -308,7 +308,7 @@ tor_version_is_obsolete(const char *myversion, const char *versionlist)
   });
   });
 
 
   /* We didn't find the listed version. Is it new or old? */
   /* We didn't find the listed version. Is it new or old? */
-  if (found_any_in_series && !found_newer_in_series) {
+  if (found_any_in_series && !found_newer_in_series && found_newer) {
     ret = VS_NEW_IN_SERIES;
     ret = VS_NEW_IN_SERIES;
   } else if (found_newer && !found_older) {
   } else if (found_newer && !found_older) {
     ret = VS_OLD;
     ret = VS_OLD;