[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]

[or-cvs] Move "sort list of versions" logic into routerparse.c; make...



Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv5119/src/or

Modified Files:
	dirserv.c or.h routerlist.c routerparse.c 
Log Message:
Move "sort list of versions" logic into routerparse.c; make version-checking code say which versions it would have accepted. (not tested.)

Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.295
retrieving revision 1.296
diff -u -p -d -r1.295 -r1.296
--- dirserv.c	5 Feb 2006 02:33:40 -0000	1.295
+++ dirserv.c	6 Feb 2006 05:04:27 -0000	1.296
@@ -761,30 +761,6 @@ list_server_status(smartlist_t *routers,
   return 0;
 }
 
-/** Helper: Given pointers to two strings describing tor versions, return -1
- * if _a precedes _b, 1 if _b preceeds _a, and 0 if they are equivalent.
- * Used to sort a list of versions. */
-static int
-_compare_tor_version_str_ptr(const void **_a, const void **_b)
-{
-  const char *a = *_a, *b = *_b;
-  int ca, cb;
-  tor_version_t va, vb;
-  ca = tor_version_parse(a, &va);
-  cb = tor_version_parse(b, &vb);
-  /* If they both parse, compare them. */
-  if (!ca && !cb)
-    return tor_version_compare(&va,&vb);
-  /* If one parses, it comes first. */
-  if (!ca && cb)
-    return -1;
-  if (ca && !cb)
-    return 1;
-  /* If neither parses, compare strings.  Also, the directory server admin
-  ** needs to be smacked upside the head.  But Tor is tolerant and gentle. */
-  return strcmp(a,b);
-}
-
 /* Given a (possibly empty) list of config_line_t, each line of which contains
  * a list of comma-separated version numbers surrounded by optional space,
  * allocate and return a new string containing the version numbers, in order,
@@ -800,7 +776,7 @@ format_versions_list(config_line_t *ln)
     smartlist_split_string(versions, ln->value, ",",
                            SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
   }
-  smartlist_sort(versions, _compare_tor_version_str_ptr);
+  sort_version_list(versions);
   result = smartlist_join_strings(versions,",",0,NULL);
   SMARTLIST_FOREACH(versions,char *,s,tor_free(s));
   smartlist_free(versions);

Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.786
retrieving revision 1.787
diff -u -p -d -r1.786 -r1.787
--- or.h	5 Feb 2006 01:57:27 -0000	1.786
+++ or.h	6 Feb 2006 05:04:27 -0000	1.787
@@ -2391,6 +2391,7 @@ version_status_t version_status_join(ver
 int tor_version_parse(const char *s, tor_version_t *out);
 int tor_version_as_new_as(const char *platform, const char *cutoff);
 int tor_version_compare(tor_version_t *a, tor_version_t *b);
+void sort_version_list(smartlist_t *lst);
 void assert_addr_policy_ok(addr_policy_t *t);
 
 networkstatus_t *networkstatus_parse_from_string(const char *s);

Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.439
retrieving revision 1.440
diff -u -p -d -r1.439 -r1.440
--- routerlist.c	5 Feb 2006 05:28:52 -0000	1.439
+++ routerlist.c	6 Feb 2006 05:04:27 -0000	1.440
@@ -2662,6 +2662,69 @@ networkstatus_get_by_digest(const char *
   return NULL;
 }
 
+/** We believe networkstatuses more recent than this when they tell us that
+ * our server is broken, invalid, obsolete, etc. */
+#define SELF_OPINION_INTERVAL 90*60
+
+/** Return a string naming the versions of Tor recommended by
+ * at least n_needed versioning networkstatuses */
+static char *
+compute_recommended_versions(time_t now, int client)
+{
+  int n_seen;
+  char *current;
+  smartlist_t *combined, *recommended;
+  int n_recent;
+  char *result;
+
+  if (!networkstatus_list)
+    return tor_strdup("<none>");
+
+  combined = smartlist_create();
+  n_recent = 0;
+  SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
+    {
+      const char *vers;
+      if (! ns->recommends_versions)
+        continue;
+      if (ns->received_on + SELF_OPINION_INTERVAL < now)
+        continue;
+      n_recent++;
+      vers = client ? ns->client_versions : ns->server_versions;
+      if (!vers)
+        continue;
+      smartlist_split_string(combined, vers, ",",
+                             SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
+    });
+
+  sort_version_list(combined);
+
+  current = NULL;
+  n_seen = 0;
+  recommended = smartlist_create();
+  SMARTLIST_FOREACH(combined, char *, cp,
+    {
+      if (current && !strcmp(cp, current)) {
+        ++n_seen;
+      } else {
+        if (n_seen >= n_recent/2 && current)
+          smartlist_add(recommended, current);
+        n_seen = 0;
+        current = cp;
+      }
+    });
+  if (n_seen >= n_recent/2 && current)
+    smartlist_add(recommended, current);
+
+  result = smartlist_join_strings(recommended, ", ", 0, NULL);
+
+  SMARTLIST_FOREACH(combined, char *, cp, tor_free(cp));
+  smartlist_free(combined);
+  smartlist_free(recommended);
+
+  return result;
+}
+
 /** If the network-status list has changed since the last time we called this
  * function, update the status of every routerinfo from the network-status
  * list.
@@ -2669,7 +2732,6 @@ networkstatus_get_by_digest(const char *
 void
 routers_update_all_from_networkstatus(void)
 {
-#define SELF_OPINION_INTERVAL 90*60
   routerinfo_t *me;
   time_t now;
   if (!routerlist || !networkstatus_list ||
@@ -2747,22 +2809,27 @@ routers_update_all_from_networkstatus(vo
     if (n_recent > 2 && n_recommended < n_recent/2) {
       if (consensus == VS_NEW || consensus == VS_NEW_IN_SERIES) {
         if (!have_warned_about_new_version) {
+          char *rec = compute_recommended_versions(now, !is_server);
           notice(LD_GENERAL, "This version of Tor (%s) is newer than any "
                  "recommended version%s, according to %d/%d recent network "
-                 "statuses.",
+                 "statuses.  Versions recommended by at least %d recent "
+                 "authorities are: %s",
                  VERSION,
                  consensus == VS_NEW_IN_SERIES ? " in its series" : "",
-                 n_recent-n_recommended, n_recent);
+                 n_recent-n_recommended, n_recent, n_recent/2, rec);
           have_warned_about_new_version = 1;
+          tor_free(rec);
         }
       } else {
+        char *rec = compute_recommended_versions(now, !is_server);
         warn(LD_GENERAL, "Please upgrade! "
              "This version of Tor (%s) is %s, according to "
-             "%d/%d recent network statuses.",
+             "%d/%d recent network statuses.  Versions recommended by "
+             "at least %d recent authorities are: %s",
              VERSION, consensus == VS_OLD ? "obsolete" : "not recommended",
-             n_recent-n_recommended, n_recent);
-        /* XXX011 we need to tell them what versions *are* recommended! */
+             n_recent-n_recommended, n_recent, n_recent/2, rec);
         have_warned_about_old_version = 1;
+        tor_free(rec);
       }
     } else {
       info(LD_GENERAL, "%d/%d recent directories think my version is ok.",

Index: routerparse.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerparse.c,v
retrieving revision 1.171
retrieving revision 1.172
diff -u -p -d -r1.171 -r1.172
--- routerparse.c	5 Feb 2006 01:57:27 -0000	1.171
+++ routerparse.c	6 Feb 2006 05:04:27 -0000	1.172
@@ -1835,3 +1835,34 @@ tor_version_same_series(tor_version_t *a
           (a->micro == b->micro));
 }
 
+/** Helper: Given pointers to two strings describing tor versions, return -1
+ * if _a precedes _b, 1 if _b preceeds _a, and 0 if they are equivalent.
+ * Used to sort a list of versions. */
+static int
+_compare_tor_version_str_ptr(const void **_a, const void **_b)
+{
+  const char *a = *_a, *b = *_b;
+  int ca, cb;
+  tor_version_t va, vb;
+  ca = tor_version_parse(a, &va);
+  cb = tor_version_parse(b, &vb);
+  /* If they both parse, compare them. */
+  if (!ca && !cb)
+    return tor_version_compare(&va,&vb);
+  /* If one parses, it comes first. */
+  if (!ca && cb)
+    return -1;
+  if (ca && !cb)
+    return 1;
+  /* If neither parses, compare strings.  Also, the directory server admin
+  ** needs to be smacked upside the head.  But Tor is tolerant and gentle. */
+  return strcmp(a,b);
+}
+
+/** Sort a list of string-representations of versions in ascending order. */
+void
+sort_version_list(smartlist_t *versions)
+{
+  smartlist_sort(versions, _compare_tor_version_str_ptr);
+}
+