]> git.ipfire.org Git - thirdparty/tor.git/commitdiff
Check recommended-software string *early*, before actually parsing the directory.
authorNick Mathewson <nickm@torproject.org>
Tue, 1 Jun 2004 18:19:01 +0000 (18:19 +0000)
committerNick Mathewson <nickm@torproject.org>
Tue, 1 Jun 2004 18:19:01 +0000 (18:19 +0000)
svn:r1930

doc/TODO
src/or/or.h
src/or/routerlist.c
src/or/routerparse.c
src/or/test.c

index b14f8cbf03fa4c9857ca34e00110b0a0cd5bffdb..287207be6cdbda988049b36b5ddda3d50e2a50c7 100644 (file)
--- a/doc/TODO
+++ b/doc/TODO
@@ -23,7 +23,7 @@ For 0.0.7:
         D try to break apart the main clump of functions better.
         o rend_services_introduce should check if it's failed a lot
           recently, and not try for a while if so
-        - check tor version as soon as you get the recommended-versions
+        o check tor version as soon as you get the recommended-versions
           string, regardless of whether parsing the directory succeeded.
         - make all ORs serve the directory too.
 
index 6c4c5eff75abbbdba9fba9dedada4e65921bc4ef..eb9ee85a5ae87289f493c7abd8d80649baae0ea9 100644 (file)
@@ -1334,6 +1334,9 @@ int router_parse_routerlist_from_directory(const char *s,
 routerinfo_t *router_parse_entry_from_string(const char *s, const char *end);
 int router_add_exit_policy_from_string(routerinfo_t *router, const char *s);
 struct exit_policy_t *router_parse_exit_policy_from_string(const char *s);
+int check_software_version_against_directory(const char *directory,
+                                             int ignoreversion);
+
 
 #endif
 
index 98cd402b1c2c2cb3590b53a98d3c44a4af67f23f..b2cc910fc12e9396701021d6217a2e8470af1913 100644 (file)
@@ -445,34 +445,13 @@ int router_load_routerlist_from_string(const char *s, int trusted)
   return 0;
 }
 
-/** Return 1 if myversion is in versionlist. Else return 0.
- * (versionlist is a comma-separated list of versions.) */
-int is_recommended_version(const char *myversion,
-                           const char *versionlist) {
-  int len_myversion = strlen(myversion);
-  char *comma;
-  const char *end = versionlist + strlen(versionlist);
-
-  log_fn(LOG_DEBUG,"checking '%s' in '%s'.", myversion, versionlist);
-
-  for(;;) {
-    comma = strchr(versionlist, ',');
-    if( ((comma ? comma : end) - versionlist == len_myversion) &&
-       !strncmp(versionlist, myversion, len_myversion))
-      /* only do strncmp if the length matches */
-      return 1; /* success, it's there */
-    if(!comma)
-      return 0; /* nope */
-    versionlist = comma+1;
-  }
-}
-
 /** Add to the current routerlist each router stored in the
  * signed directory <b>s</b>.  If pkey is provided, make sure that <b>s</b> is
  * signed with pkey. */
 int router_load_routerlist_from_directory(const char *s, crypto_pk_env_t *pkey)
 {
   routerlist_t *new_list = NULL;
+  check_software_version_against_directory(s, options.IgnoreVersion);
   if (router_parse_routerlist_from_directory(s, &new_list, pkey)) {
     log_fn(LOG_WARN, "Couldn't parse directory.");
     return -1;
@@ -493,19 +472,6 @@ int router_load_routerlist_from_directory(const char *s, crypto_pk_env_t *pkey)
     log_fn(LOG_WARN, "Error resolving routerlist");
     return -1;
   }
-  if (!is_recommended_version(VERSION, routerlist->software_versions)) {
-    log(options.IgnoreVersion ? LOG_WARN : LOG_ERR,
-     "You are running Tor version %s, which will not work with this network.\n"
-     "Please use %s%s.",
-        VERSION, strchr(routerlist->software_versions,',') ? "one of " : "",
-        routerlist->software_versions);
-    if(options.IgnoreVersion) {
-      log(LOG_WARN, "IgnoreVersion is set. If it breaks, we told you so.");
-    } else {
-      fflush(0);
-      exit(0);
-    }
-  }
   return 0;
 }
 
index 6b227fcddfea8c45ccfdf424261194d27153404f..c239a613e2278f8fa01c884a3d40f46ad00eaa44 100644 (file)
@@ -176,6 +176,89 @@ static int parse_time(const char *cp, time_t *t)
   return 0;
 }
 
+/**
+ * Find the first instance of "recommended-software ...\n" at the start of
+ * a line; return a newly allocated string containing the "..." portion.
+ * Return NULL if no such instance was found.
+ */
+static char *
+get_recommended_software_from_directory(const char *str)
+{
+#define REC "recommended-software "
+  const char *cp = str, *eol;
+  int len = strlen(REC);
+  cp = str;
+  if (strncmp(str, REC, len)==0) {
+    cp += len;
+  } else {
+    cp = strstr(str, "\n"REC);
+    if (!cp)
+      return NULL;
+    cp += len+1;
+  }
+  eol = strchr(cp, '\n');
+  if (!eol)
+    return NULL;
+  return tor_strndup(cp, eol-cp);
+#undef REC
+}
+
+/** Return 1 if myversion is in versionlist. Else return 0.
+ * (versionlist is a comma-separated list of versions.) */
+/* static */ int is_recommended_version(const char *myversion,
+                           const char *versionlist) {
+  int len_myversion = strlen(myversion);
+  char *comma;
+  const char *end = versionlist + strlen(versionlist);
+
+  log_fn(LOG_DEBUG,"checking '%s' in '%s'.", myversion, versionlist);
+
+  for(;;) {
+    comma = strchr(versionlist, ',');
+    if( ((comma ? comma : end) - versionlist == len_myversion) &&
+       !strncmp(versionlist, myversion, len_myversion))
+      /* only do strncmp if the length matches */
+      return 1; /* success, it's there */
+    if(!comma)
+      return 0; /* nope */
+    versionlist = comma+1;
+  }
+}
+
+/* Return 0 if myversion is supported; else log a message and return
+ * -1 (or exit if ignoreversions is false) */
+int check_software_version_against_directory(const char *directory,
+                                             int ignoreversion)
+{
+  char *v;
+  v = get_recommended_software_from_directory(directory);
+  if (!v) {
+    log_fn(LOG_WARN, "No recommended-versions string found in directory");
+    return -1;
+  }
+  /* Look for versions of the form "0.1.0" and of the form "Tor 0.1.0".
+   * Eventually, we should deprecate the first form.
+   */
+  if (is_recommended_version(VERSION, v) ||
+      is_recommended_version("Tor "VERSION, v)) {
+    tor_free(v);
+    return 0;
+  }
+  log(ignoreversion ? LOG_WARN : LOG_ERR,
+     "You are running Tor version %s, which will not work with this network.\n"
+     "Please use %s%s.",
+      VERSION, strchr(v,',') ? "one of " : "", v);
+  tor_free(v);
+
+  if(ignoreversion) {
+    log(LOG_WARN, "IgnoreVersion is set. If it breaks, we told you so.");
+    return -1;
+  } else {
+    fflush(0);
+    exit(0);
+    return -1; /* never reached */
+  }
+}
 
 /** Parse a directory from <b>s</b> and, when done, store the
  * resulting routerlist in *<b>dest</b>, freeing the old value if necessary.
index 864645b5d045d7f8280ec79d6a33858c937f2cd9..70b0b5554d6e018ed6a8403fc1418c9d5af9b942 100644 (file)
@@ -635,8 +635,8 @@ test_onion_handshake() {
   crypto_free_pk_env(pk);
 }
 
-/* from routers.c */
-int is_recommended_version(char *myversion, char *start);
+/* from routerparse.c */
+int is_recommended_version(const char *myversion, const char *start);
 
 void
 test_dir_format()