aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2004-06-01 18:19:01 +0000
committerNick Mathewson <nickm@torproject.org>2004-06-01 18:19:01 +0000
commit94782444f80f483bafebf537b059f2d8a8e0cdd2 (patch)
treed7e0c5af0a66f2b9176b2366d18eec2deeb26f5d
parent74f611581ef992e8657c989883956d5a352b8965 (diff)
downloadtor-94782444f80f483bafebf537b059f2d8a8e0cdd2.tar
tor-94782444f80f483bafebf537b059f2d8a8e0cdd2.tar.gz
Check recommended-software string *early*, before actually parsing the directory.
svn:r1930
-rw-r--r--doc/TODO2
-rw-r--r--src/or/or.h3
-rw-r--r--src/or/routerlist.c36
-rw-r--r--src/or/routerparse.c83
-rw-r--r--src/or/test.c4
5 files changed, 90 insertions, 38 deletions
diff --git a/doc/TODO b/doc/TODO
index b14f8cbf0..287207be6 100644
--- 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.
diff --git a/src/or/or.h b/src/or/or.h
index 6c4c5eff7..eb9ee85a5 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -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
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 98cd402b1..b2cc910fc 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -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;
}
diff --git a/src/or/routerparse.c b/src/or/routerparse.c
index 6b227fcdd..c239a613e 100644
--- a/src/or/routerparse.c
+++ b/src/or/routerparse.c
@@ -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.
diff --git a/src/or/test.c b/src/or/test.c
index 864645b5d..70b0b5554 100644
--- a/src/or/test.c
+++ b/src/or/test.c
@@ -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()