Move "sort list of versions" logic into routerparse.c; make version-checking code say which versions it would have accepted. (not tested.)

svn:r5927
This commit is contained in:
Nick Mathewson
2006-02-06 05:04:27 +00:00
parent 2bb4fd24de
commit e5a574ce2e
4 changed files with 106 additions and 31 deletions
+1 -25
View File
@@ -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);
+1
View File
@@ -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);
+73 -6
View File
@@ -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.",
+31
View File
@@ -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);
}