diff options
author | Nick Mathewson <nickm@torproject.org> | 2006-02-06 05:04:27 +0000 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2006-02-06 05:04:27 +0000 |
commit | e5a574ce2e80e4fc202f2ea35b5bb6c986aab025 (patch) | |
tree | 2481609cd213a93b887cf80599f74b353045fff0 | |
parent | 2bb4fd24de054685ba005177e7359ad1eb087804 (diff) | |
download | tor-e5a574ce2e80e4fc202f2ea35b5bb6c986aab025.tar.gz tor-e5a574ce2e80e4fc202f2ea35b5bb6c986aab025.zip |
Move "sort list of versions" logic into routerparse.c; make version-checking code say which versions it would have accepted. (not tested.)
svn:r5927
-rw-r--r-- | src/or/dirserv.c | 26 | ||||
-rw-r--r-- | src/or/or.h | 1 | ||||
-rw-r--r-- | src/or/routerlist.c | 79 | ||||
-rw-r--r-- | src/or/routerparse.c | 31 |
4 files changed, 106 insertions, 31 deletions
diff --git a/src/or/dirserv.c b/src/or/dirserv.c index 6fffe6c257..a9c542a7b4 100644 --- a/src/or/dirserv.c +++ b/src/or/dirserv.c @@ -761,30 +761,6 @@ list_server_status(smartlist_t *routers, char **router_status_out) 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); diff --git a/src/or/or.h b/src/or/or.h index f48507fc66..75642a0639 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2391,6 +2391,7 @@ version_status_t version_status_join(version_status_t a, version_status_t b); 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); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index 935dc91b13..61ff58f871 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -2662,6 +2662,69 @@ networkstatus_get_by_digest(const char *digest) 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 *digest) 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(void) 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.", diff --git a/src/or/routerparse.c b/src/or/routerparse.c index 99fb7defb5..61de43fcae 100644 --- a/src/or/routerparse.c +++ b/src/or/routerparse.c @@ -1835,3 +1835,34 @@ tor_version_same_series(tor_version_t *a, tor_version_t *b) (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); +} + |