mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
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:
+1
-25
@@ -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);
|
||||
|
||||
@@ -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
@@ -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.",
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user