mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-14 07:03:44 +01:00
Implement new version handling code.
svn:r5100
This commit is contained in:
parent
892e173e01
commit
20b9111266
@ -191,6 +191,8 @@ static config_var_t _option_vars[] = {
|
|||||||
VAR("UseHelperNodes", BOOL, UseHelperNodes, "0"),
|
VAR("UseHelperNodes", BOOL, UseHelperNodes, "0"),
|
||||||
VAR("User", STRING, User, NULL),
|
VAR("User", STRING, User, NULL),
|
||||||
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
VAR("V1AuthoritativeDirectory",BOOL, V1AuthoritativeDir, "0"),
|
||||||
|
/* XXXX 011 change this default on 0.1.1.x */
|
||||||
|
VAR("VersioningAuthoritativeDirectory",BOOL,VersioningAuthoritativeDir, "1"),
|
||||||
VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"),
|
VAR("__LeaveStreamsUnattached", BOOL,LeaveStreamsUnattached, "0"),
|
||||||
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL, NULL }
|
{ NULL, CONFIG_TYPE_OBSOLETE, 0, NULL, NULL }
|
||||||
};
|
};
|
||||||
|
@ -1149,6 +1149,7 @@ generate_v2_networkstatus(void)
|
|||||||
smartlist_t *descriptor_list = get_descriptor_list();
|
smartlist_t *descriptor_list = get_descriptor_list();
|
||||||
time_t now = time(NULL);
|
time_t now = time(NULL);
|
||||||
int naming = options->NamingAuthoritativeDir;
|
int naming = options->NamingAuthoritativeDir;
|
||||||
|
int versioning = options->VersioningAuthoritativeDir;
|
||||||
const char *contact;
|
const char *contact;
|
||||||
|
|
||||||
if (!descriptor_list) {
|
if (!descriptor_list) {
|
||||||
@ -1193,7 +1194,7 @@ generate_v2_networkstatus(void)
|
|||||||
"fingerprint %s\n"
|
"fingerprint %s\n"
|
||||||
"contact %s\n"
|
"contact %s\n"
|
||||||
"published %s\n"
|
"published %s\n"
|
||||||
"dir-options%s\n"
|
"dir-options%s%s\n"
|
||||||
"client-versions %s\n"
|
"client-versions %s\n"
|
||||||
"server-versions %s\n"
|
"server-versions %s\n"
|
||||||
"dir-signing-key\n%s\n",
|
"dir-signing-key\n%s\n",
|
||||||
@ -1202,6 +1203,7 @@ generate_v2_networkstatus(void)
|
|||||||
contact,
|
contact,
|
||||||
published,
|
published,
|
||||||
naming ? " Names" : "",
|
naming ? " Names" : "",
|
||||||
|
versioning ? " Versions" : "",
|
||||||
client_versions,
|
client_versions,
|
||||||
server_versions,
|
server_versions,
|
||||||
identity_pkey);
|
identity_pkey);
|
||||||
|
22
src/or/or.h
22
src/or/or.h
@ -816,7 +816,8 @@ typedef struct networkstatus_t {
|
|||||||
/** What was the digest of the document? */
|
/** What was the digest of the document? */
|
||||||
char networkstatus_digest[DIGEST_LEN];
|
char networkstatus_digest[DIGEST_LEN];
|
||||||
|
|
||||||
int is_recent; /** Is this recent enough to influence running status? */
|
unsigned int is_recent; /**< Is this recent enough to influence running
|
||||||
|
* status? */
|
||||||
|
|
||||||
/* These fields come from the actual network-status document.*/
|
/* These fields come from the actual network-status document.*/
|
||||||
time_t published_on; /**< Declared publication date. */
|
time_t published_on; /**< Declared publication date. */
|
||||||
@ -833,7 +834,10 @@ typedef struct networkstatus_t {
|
|||||||
char *server_versions; /**< comma-separated list of recommended server
|
char *server_versions; /**< comma-separated list of recommended server
|
||||||
* versions. */
|
* versions. */
|
||||||
|
|
||||||
int binds_names:1; /**< True iff this directory server binds names. */
|
unsigned int binds_names:1; /**< True iff this directory server binds names. */
|
||||||
|
unsigned int recommends_versions:1; /**< True iff this directory server
|
||||||
|
* recommends client and server software
|
||||||
|
* versions. */
|
||||||
|
|
||||||
smartlist_t *entries; /**< List of router_status_t*. This list is kept
|
smartlist_t *entries; /**< List of router_status_t*. This list is kept
|
||||||
* sorted by identity_digest. */
|
* sorted by identity_digest. */
|
||||||
@ -1175,6 +1179,8 @@ typedef struct {
|
|||||||
* for version 1 directories? */
|
* for version 1 directories? */
|
||||||
int NamingAuthoritativeDir; /**< Boolean: is this an authoritative directory
|
int NamingAuthoritativeDir; /**< Boolean: is this an authoritative directory
|
||||||
* that's willing to bind names? */
|
* that's willing to bind names? */
|
||||||
|
int VersioningAuthoritativeDir; /**< Boolean: is this an authoritative directory
|
||||||
|
* that's willing to recommend versions? */
|
||||||
int ClientOnly; /**< Boolean: should we never evolve into a server role? */
|
int ClientOnly; /**< Boolean: should we never evolve into a server role? */
|
||||||
int NoPublish; /**< Boolean: should we never publish a descriptor? */
|
int NoPublish; /**< Boolean: should we never publish a descriptor? */
|
||||||
int ConnLimit; /**< Requested maximum number of simultaneous connections. */
|
int ConnLimit; /**< Requested maximum number of simultaneous connections. */
|
||||||
@ -2143,6 +2149,15 @@ typedef struct tor_version_t {
|
|||||||
char status_tag[MAX_STATUS_TAG_LEN];
|
char status_tag[MAX_STATUS_TAG_LEN];
|
||||||
} tor_version_t;
|
} tor_version_t;
|
||||||
|
|
||||||
|
typedef enum version_status_t {
|
||||||
|
VS_RECOMMENDED=0, /**< This version is listed as recommended. */
|
||||||
|
VS_OLD=1, /**< This version is older than any recommended version. */
|
||||||
|
VS_NEW=2, /**< This version is newer than any recommended version. */
|
||||||
|
VS_NEW_IN_SERIES=3, /**< This version is newer than any recommended version
|
||||||
|
* in its series, and such recommended versions exist. */
|
||||||
|
VS_UNRECOMMENDED=4 /**< This version is not recommended (general case) */
|
||||||
|
} version_status_t;
|
||||||
|
|
||||||
int router_get_router_hash(const char *s, char *digest);
|
int router_get_router_hash(const char *s, char *digest);
|
||||||
int router_get_dir_hash(const char *s, char *digest);
|
int router_get_dir_hash(const char *s, char *digest);
|
||||||
int router_get_runningrouters_hash(const char *s, char *digest);
|
int router_get_runningrouters_hash(const char *s, char *digest);
|
||||||
@ -2162,6 +2177,9 @@ 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);
|
int router_add_exit_policy_from_string(routerinfo_t *router, const char *s);
|
||||||
addr_policy_t *router_parse_addr_policy_from_string(const char *s,
|
addr_policy_t *router_parse_addr_policy_from_string(const char *s,
|
||||||
int assume_action);
|
int assume_action);
|
||||||
|
version_status_t tor_version_is_obsolete(const char *myversion,
|
||||||
|
const char *versionlist);
|
||||||
|
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_parse(const char *s, tor_version_t *out);
|
||||||
int tor_version_as_new_as(const char *platform, const char *cutoff);
|
int tor_version_as_new_as(const char *platform, const char *cutoff);
|
||||||
int tor_version_compare(tor_version_t *a, tor_version_t *b);
|
int tor_version_compare(tor_version_t *a, tor_version_t *b);
|
||||||
|
@ -1983,7 +1983,10 @@ networkstatus_get_by_digest(const char *digest)
|
|||||||
void
|
void
|
||||||
routers_update_all_from_networkstatus(void)
|
routers_update_all_from_networkstatus(void)
|
||||||
{
|
{
|
||||||
|
#define SELF_OPINION_INTERVAL 90*60
|
||||||
static int have_warned_about_unverified_status = 0;
|
static int have_warned_about_unverified_status = 0;
|
||||||
|
static int have_warned_about_old_version = 0;
|
||||||
|
static int have_warned_about_new_version = 0;
|
||||||
routerinfo_t *me;
|
routerinfo_t *me;
|
||||||
time_t now;
|
time_t now;
|
||||||
if (!routerlist || !networkstatus_list ||
|
if (!routerlist || !networkstatus_list ||
|
||||||
@ -1997,18 +2000,33 @@ routers_update_all_from_networkstatus(void)
|
|||||||
routers_update_status_from_networkstatus(routerlist->routers, 0);
|
routers_update_status_from_networkstatus(routerlist->routers, 0);
|
||||||
|
|
||||||
me = router_get_my_routerinfo();
|
me = router_get_my_routerinfo();
|
||||||
if (me) {
|
if (me && !have_warned_about_unverified_status) {
|
||||||
/* We could be more sophisticated about this whole business. How many
|
int n_recent = 0, n_listing = 0, n_valid = 0, n_named = 0;
|
||||||
* dirservers list us as named, valid, etc. */
|
routerstatus_t *rs;
|
||||||
smartlist_t *lst = smartlist_create();
|
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
||||||
smartlist_add(lst, me);
|
{
|
||||||
routers_update_status_from_networkstatus(lst, 1);
|
if (ns->received_on + SELF_OPINION_INTERVAL < now)
|
||||||
if (me->is_verified == 0) {
|
continue;
|
||||||
log_fn(LOG_WARN, "Many directory servers list us as unverified. Please consider sending your identity fingerprint to the tor-ops.");
|
++n_recent;
|
||||||
have_warned_about_unverified_status = 1;
|
if (!(rs = networkstatus_find_entry(ns, me->identity_digest)))
|
||||||
} else if (me->is_named == 0) {
|
continue;
|
||||||
log_fn(LOG_WARN, "Many directory servers list us as unnamed. Please consider sending your identity fingerprint to the tor-ops.");
|
++n_listing;
|
||||||
have_warned_about_unverified_status = 1;
|
if (rs->is_valid)
|
||||||
|
++n_valid;
|
||||||
|
if (rs->is_named)
|
||||||
|
++n_named;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (n_recent >= 2 && n_listing >= 2) {
|
||||||
|
if (n_valid <= n_recent/2) {
|
||||||
|
log_fn(LOG_WARN, "%d/%d recent directory servers list us as invalid. Please consider sending your identity fingerprint to the tor-ops.",
|
||||||
|
n_recent-n_valid, n_recent);
|
||||||
|
have_warned_about_unverified_status = 1;
|
||||||
|
} else if (n_named <= n_recent/2) {
|
||||||
|
log_fn(LOG_WARN, "%d/%d recent directory servers list us as unnamed. Please consider sending your identity fingerprint to the tor-ops.",
|
||||||
|
n_recent-n_valid, n_recent);
|
||||||
|
have_warned_about_unverified_status = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2016,6 +2034,47 @@ routers_update_all_from_networkstatus(void)
|
|||||||
|
|
||||||
update_router_descriptor_downloads(time(NULL));
|
update_router_descriptor_downloads(time(NULL));
|
||||||
|
|
||||||
|
if (!have_warned_about_old_version) {
|
||||||
|
int n_recent = 0;
|
||||||
|
int n_recommended = 0;
|
||||||
|
int is_server = server_mode(get_options());
|
||||||
|
version_status_t consensus = VS_RECOMMENDED;
|
||||||
|
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
||||||
|
{
|
||||||
|
version_status_t vs;
|
||||||
|
if (ns->received_on + SELF_OPINION_INTERVAL < now )
|
||||||
|
// XXXX NM enable this! || !ns->recommends_versions)
|
||||||
|
continue;
|
||||||
|
vs = tor_version_is_obsolete(
|
||||||
|
VERSION, is_server ? ns->server_versions : ns->client_versions);
|
||||||
|
if (vs == VS_RECOMMENDED)
|
||||||
|
++n_recommended;
|
||||||
|
if (n_recent++ == 0) {
|
||||||
|
consensus = vs;
|
||||||
|
} else if (consensus != vs) {
|
||||||
|
consensus = version_status_join(consensus, vs);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
if (n_recent > 2 && n_recommended < n_recent/2) {
|
||||||
|
if (consensus == VS_NEW || consensus == VS_NEW_IN_SERIES) {
|
||||||
|
if (!have_warned_about_new_version) {
|
||||||
|
log_fn(LOG_NOTICE, "This version of Tor (%s) is newer than any recommended version%s, according to %d/%d recent network statuses.",
|
||||||
|
VERSION, consensus == VS_NEW_IN_SERIES ? " in its series" : "",
|
||||||
|
n_recent-n_recommended, n_recent);
|
||||||
|
have_warned_about_new_version = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_fn(LOG_NOTICE, "This version of Tor (%s) is %s, according to %d/%d recent network statuses.",
|
||||||
|
VERSION, consensus == VS_OLD ? "obsolete" : "not recommended",
|
||||||
|
n_recent-n_recommended, n_recent);
|
||||||
|
have_warned_about_old_version = 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
log_fn(LOG_NOTICE, "%d/%d recent directories think my version is ok.",
|
||||||
|
n_recommended, n_recent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
routerstatus_list_has_changed = 0;
|
routerstatus_list_has_changed = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -166,8 +166,6 @@ static int check_directory_signature(const char *digest,
|
|||||||
crypto_pk_env_t *declared_key,
|
crypto_pk_env_t *declared_key,
|
||||||
int check_authority);
|
int check_authority);
|
||||||
static crypto_pk_env_t *find_dir_signing_key(const char *str);
|
static crypto_pk_env_t *find_dir_signing_key(const char *str);
|
||||||
/* static */ int is_obsolete_version(const char *myversion,
|
|
||||||
const char *versionlist);
|
|
||||||
static int tor_version_same_series(tor_version_t *a, tor_version_t *b);
|
static int tor_version_same_series(tor_version_t *a, tor_version_t *b);
|
||||||
|
|
||||||
/** Set <b>digest</b> to the SHA-1 digest of the hash of the directory in
|
/** Set <b>digest</b> to the SHA-1 digest of the hash of the directory in
|
||||||
@ -258,14 +256,17 @@ router_append_dirobj_signature(char *buf, size_t buf_len, const char *digest,
|
|||||||
* Otherwise return 0.
|
* Otherwise return 0.
|
||||||
* (versionlist is a comma-separated list of version strings,
|
* (versionlist is a comma-separated list of version strings,
|
||||||
* optionally prefixed with "Tor". Versions that can't be parsed are
|
* optionally prefixed with "Tor". Versions that can't be parsed are
|
||||||
* ignored.) */
|
* ignored.)
|
||||||
/* static */ int
|
*
|
||||||
is_obsolete_version(const char *myversion, const char *versionlist) {
|
* DOCDOC interface changed */
|
||||||
|
version_status_t
|
||||||
|
tor_version_is_obsolete(const char *myversion, const char *versionlist)
|
||||||
|
{
|
||||||
const char *vl;
|
const char *vl;
|
||||||
tor_version_t mine, other;
|
tor_version_t mine, other;
|
||||||
int found_newer = 0, found_newer_in_series = 0, found_any_in_series = 0,
|
int found_newer = 0, found_older = 0, found_newer_in_series = 0,
|
||||||
r, ret, same;
|
found_any_in_series = 0, r, same;
|
||||||
static int warned_too_new=0;
|
version_status_t ret = VS_UNRECOMMENDED;
|
||||||
smartlist_t *version_sl;
|
smartlist_t *version_sl;
|
||||||
|
|
||||||
vl = versionlist;
|
vl = versionlist;
|
||||||
@ -292,54 +293,28 @@ is_obsolete_version(const char *myversion, const char *versionlist) {
|
|||||||
found_any_in_series = 1;
|
found_any_in_series = 1;
|
||||||
r = tor_version_compare(&mine, &other);
|
r = tor_version_compare(&mine, &other);
|
||||||
if (r==0) {
|
if (r==0) {
|
||||||
ret = 0;
|
ret = VS_RECOMMENDED;
|
||||||
goto done;
|
goto done;
|
||||||
} else if (r<0) {
|
} else if (r<0) {
|
||||||
found_newer = 1;
|
found_newer = 1;
|
||||||
if (same)
|
if (same)
|
||||||
found_newer_in_series = 1;
|
found_newer_in_series = 1;
|
||||||
|
} else if (r>0) {
|
||||||
|
found_older = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
/* We didn't find the listed version. Is it new or old? */
|
/* We didn't find the listed version. Is it new or old? */
|
||||||
|
if (found_any_in_series && !found_newer_in_series) {
|
||||||
if (found_any_in_series) {
|
ret = VS_NEW_IN_SERIES;
|
||||||
if (!found_newer_in_series) {
|
} else if (found_newer && !found_older) {
|
||||||
/* We belong to a series with recommended members, and we are newer than
|
ret = VS_OLD;
|
||||||
* any recommended member. We're probably okay. */
|
} else if (found_older && !found_newer) {
|
||||||
if (!warned_too_new) {
|
ret = VS_NEW;
|
||||||
log(LOG_WARN, "This version of Tor (%s) is newer than any in the same series on the recommended list (%s).",
|
|
||||||
myversion, versionlist);
|
|
||||||
warned_too_new = 1;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
} else {
|
|
||||||
/* We found a newer one in the same series; we're obsolete. */
|
|
||||||
ret = 1;
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
if (found_newer) {
|
ret = VS_UNRECOMMENDED;
|
||||||
/* We belong to a series with no recommended members, and
|
|
||||||
* a newer series is recommended. We're obsolete. */
|
|
||||||
ret = 1;
|
|
||||||
} else {
|
|
||||||
/* We belong to a series with no recommended members, and it's
|
|
||||||
* newer than any recommended series. We're probably okay. */
|
|
||||||
if (!warned_too_new) {
|
|
||||||
log(LOG_WARN, "This version of Tor (%s) is newer than any on the recommended list (%s).",
|
|
||||||
myversion, versionlist);
|
|
||||||
warned_too_new = 1;
|
|
||||||
}
|
|
||||||
ret = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
log_fn(LOG_DEBUG,
|
|
||||||
"Decided that %s is %sobsolete relative to %s: %d, %d, %d\n",
|
|
||||||
myversion, ret?"":"not ", versionlist, found_newer,
|
|
||||||
found_any_in_series, found_newer_in_series);
|
|
||||||
*/
|
|
||||||
|
|
||||||
done:
|
done:
|
||||||
SMARTLIST_FOREACH(version_sl, char *, version, tor_free(version));
|
SMARTLIST_FOREACH(version_sl, char *, version, tor_free(version));
|
||||||
@ -347,29 +322,25 @@ is_obsolete_version(const char *myversion, const char *versionlist) {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
/** DOCDOC */
|
||||||
/* Return 0 if myversion is supported; else warn and return -1. */
|
version_status_t
|
||||||
int
|
version_status_join(version_status_t a, version_status_t b)
|
||||||
check_software_version_against_directory(const char *directory)
|
|
||||||
{
|
{
|
||||||
char *v;
|
if (a == b)
|
||||||
v = get_recommended_software_from_directory(directory);
|
return a;
|
||||||
if (!v) {
|
else if (a == VS_UNRECOMMENDED || b == VS_UNRECOMMENDED)
|
||||||
log_fn(LOG_WARN, "No recommended-versions string found in directory");
|
return VS_UNRECOMMENDED;
|
||||||
return -1;
|
else if (a == VS_RECOMMENDED)
|
||||||
}
|
return b;
|
||||||
if (!is_obsolete_version(VERSION, v)) {
|
else if (b == VS_RECOMMENDED)
|
||||||
tor_free(v);
|
return a;
|
||||||
return 0;
|
/* Okay. Neither is 'recommended' or 'unrecommended', and they differ. */
|
||||||
}
|
else if (a == VS_OLD || b == VS_OLD)
|
||||||
log(LOG_WARN,
|
return VS_UNRECOMMENDED;
|
||||||
"You are running Tor version %s, which will not work with this network.\n"
|
/* One is VS_NEW, the other is VS_NEW_IN_SERIES */
|
||||||
"Please use %s%s.",
|
else
|
||||||
VERSION, strchr(v,',') ? "one of " : "", v);
|
return VS_NEW_IN_SERIES;
|
||||||
tor_free(v);
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
/** Read a signed directory from <b>str</b>. If it's well-formed, return 0.
|
/** Read a signed directory from <b>str</b>. If it's well-formed, return 0.
|
||||||
* Otherwise, return -1. If we're a directory cache, cache it.
|
* Otherwise, return -1. If we're a directory cache, cache it.
|
||||||
@ -1164,25 +1135,31 @@ networkstatus_parse_from_string(const char *s)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(tok = find_first_by_keyword(tokens, K_CLIENT_VERSIONS)) || tok->n_args<1) {
|
if ((tok = find_first_by_keyword(tokens, K_DIR_OPTIONS))) {
|
||||||
log_fn(LOG_WARN, "Missing client-versions");
|
for (i=0; i < tok->n_args; ++i) {
|
||||||
goto err;
|
if (!strcmp(tok->args[i], "Names"))
|
||||||
|
ns->binds_names = 1;
|
||||||
|
if (!strcmp(tok->args[i], "Versions"))
|
||||||
|
ns->recommends_versions = 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ns->client_versions = tok->args[0];
|
|
||||||
|
|
||||||
if (!(tok = find_first_by_keyword(tokens, K_CLIENT_VERSIONS)) || tok->n_args<1) {
|
if (ns->recommends_versions || 1) { //XXXX NM re-enable conditional.
|
||||||
log_fn(LOG_WARN, "Missing client-versions");
|
if (!(tok = find_first_by_keyword(tokens, K_CLIENT_VERSIONS)) ||
|
||||||
goto err;
|
tok->n_args<1) {
|
||||||
}
|
log_fn(LOG_WARN, "Missing client-versions");
|
||||||
ns->client_versions = tok->args[0];
|
}
|
||||||
tok->args[0] = NULL;
|
ns->client_versions = tok->args[0];
|
||||||
|
tok->args[0] = NULL;
|
||||||
|
|
||||||
if (!(tok = find_first_by_keyword(tokens, K_SERVER_VERSIONS)) || tok->n_args<1) {
|
if (!(tok = find_first_by_keyword(tokens, K_SERVER_VERSIONS)) ||
|
||||||
log_fn(LOG_WARN, "Missing server-versions");
|
tok->n_args<1) {
|
||||||
goto err;
|
log_fn(LOG_WARN, "Missing server-versions on versioning directory");
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
|
ns->server_versions = tok->args[0];
|
||||||
|
tok->args[0] = NULL;
|
||||||
}
|
}
|
||||||
ns->server_versions = tok->args[0];
|
|
||||||
tok->args[0] = NULL;
|
|
||||||
|
|
||||||
if (!(tok = find_first_by_keyword(tokens, K_PUBLISHED))) {
|
if (!(tok = find_first_by_keyword(tokens, K_PUBLISHED))) {
|
||||||
log_fn(LOG_WARN, "Missing published time on directory.");
|
log_fn(LOG_WARN, "Missing published time on directory.");
|
||||||
@ -1193,13 +1170,6 @@ networkstatus_parse_from_string(const char *s)
|
|||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((tok = find_first_by_keyword(tokens, K_DIR_OPTIONS))) {
|
|
||||||
for (i=0; i < tok->n_args; ++i) {
|
|
||||||
if (!strcmp(tok->args[i], "Names"))
|
|
||||||
ns->binds_names = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ns->entries = smartlist_create();
|
ns->entries = smartlist_create();
|
||||||
s = eos;
|
s = eos;
|
||||||
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
|
SMARTLIST_FOREACH(tokens, directory_token_t *, t, token_free(t));
|
||||||
|
@ -32,7 +32,6 @@ int have_failed = 0;
|
|||||||
void add_fingerprint_to_dir(const char *nickname, const char *fp,
|
void add_fingerprint_to_dir(const char *nickname, const char *fp,
|
||||||
smartlist_t *list);
|
smartlist_t *list);
|
||||||
void get_platform_str(char *platform, size_t len);
|
void get_platform_str(char *platform, size_t len);
|
||||||
int is_obsolete_version(const char *myversion, const char *start);
|
|
||||||
size_t read_escaped_data(const char *data, size_t len, int translate_newlines,
|
size_t read_escaped_data(const char *data, size_t len, int translate_newlines,
|
||||||
char **out);
|
char **out);
|
||||||
or_options_t *options_new(void);
|
or_options_t *options_new(void);
|
||||||
@ -1368,28 +1367,35 @@ test_dir_format(void)
|
|||||||
test_eq(IS_NOT_CVS, ver1.cvs);
|
test_eq(IS_NOT_CVS, ver1.cvs);
|
||||||
test_streq("", ver1.status_tag);
|
test_streq("", ver1.status_tag);
|
||||||
|
|
||||||
/* make sure is_obsolete_version() works */
|
/* make sure tor_version_is_obsolete() works */
|
||||||
test_eq(1, is_obsolete_version("0.0.1", "Tor 0.0.2"));
|
test_eq(VS_OLD, tor_version_is_obsolete("0.0.1", "Tor 0.0.2"));
|
||||||
test_eq(1, is_obsolete_version("0.0.1", "0.0.2, Tor 0.0.3"));
|
test_eq(VS_OLD, tor_version_is_obsolete("0.0.1", "0.0.2, Tor 0.0.3"));
|
||||||
test_eq(1, is_obsolete_version("0.0.1", "0.0.2,Tor 0.0.3"));
|
test_eq(VS_OLD, tor_version_is_obsolete("0.0.1", "0.0.2,Tor 0.0.3"));
|
||||||
test_eq(1, is_obsolete_version("0.0.1", "0.0.3,BetterTor 0.0.1"));
|
test_eq(VS_OLD, tor_version_is_obsolete("0.0.1", "0.0.3,BetterTor 0.0.1"));
|
||||||
test_eq(0, is_obsolete_version("0.0.2", "Tor 0.0.2,Tor 0.0.3"));
|
test_eq(VS_RECOMMENDED,tor_version_is_obsolete("0.0.2", "Tor 0.0.2,Tor 0.0.3"));
|
||||||
test_eq(0, is_obsolete_version("0.0.2", "Tor 0.0.2pre1,Tor 0.0.3"));
|
test_eq(VS_NEW_IN_SERIES,
|
||||||
test_eq(1, is_obsolete_version("0.0.2", "Tor 0.0.2.1,Tor 0.0.3"));
|
tor_version_is_obsolete("0.0.2", "Tor 0.0.2pre1,Tor 0.0.3"));
|
||||||
test_eq(0, is_obsolete_version("0.1.0", "Tor 0.0.2,Tor 0.0.3"));
|
test_eq(VS_OLD, tor_version_is_obsolete("0.0.2", "Tor 0.0.2.1,Tor 0.0.3"));
|
||||||
test_eq(0, is_obsolete_version("0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8"));
|
test_eq(VS_NEW, tor_version_is_obsolete("0.1.0", "Tor 0.0.2,Tor 0.0.3"));
|
||||||
test_eq(0, is_obsolete_version("0.0.5", "0.0.5-cvs"));
|
test_eq(VS_RECOMMENDED,
|
||||||
test_eq(0, is_obsolete_version("0.0.5.1-cvs", "0.0.5"));
|
tor_version_is_obsolete("0.0.7rc2", "0.0.7,Tor 0.0.7rc2,Tor 0.0.8"));
|
||||||
|
test_eq(VS_OLD, tor_version_is_obsolete("0.0.5.0", "0.0.5.1-cvs"));
|
||||||
|
test_eq(VS_NEW_IN_SERIES, tor_version_is_obsolete("0.0.5.1-cvs", "0.0.5"));
|
||||||
/* Not on list, but newer than any in same series. */
|
/* Not on list, but newer than any in same series. */
|
||||||
test_eq(0, is_obsolete_version("0.1.0.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
test_eq(VS_NEW_IN_SERIES,
|
||||||
|
tor_version_is_obsolete("0.1.0.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
||||||
/* Series newer than any on list. */
|
/* Series newer than any on list. */
|
||||||
test_eq(0, is_obsolete_version("0.1.1.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
test_eq(VS_NEW,
|
||||||
|
tor_version_is_obsolete("0.1.2.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
||||||
/* Series older than any on list. */
|
/* Series older than any on list. */
|
||||||
test_eq(1, is_obsolete_version("0.0.1.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
test_eq(VS_OLD,
|
||||||
|
tor_version_is_obsolete("0.0.1.3", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
||||||
/* Not on list, not newer than any on same series. */
|
/* Not on list, not newer than any on same series. */
|
||||||
test_eq(1, is_obsolete_version("0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
test_eq(VS_UNRECOMMENDED,
|
||||||
|
tor_version_is_obsolete("0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
||||||
/* On list, not newer than any on same series. */
|
/* On list, not newer than any on same series. */
|
||||||
test_eq(1, is_obsolete_version("0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
test_eq(VS_UNRECOMMENDED,
|
||||||
|
tor_version_is_obsolete("0.1.0.1", "Tor 0.1.0.2,Tor 0.0.9.5,Tor 0.1.1.0"));
|
||||||
|
|
||||||
test_eq(0, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
|
test_eq(0, tor_version_as_new_as("Tor 0.0.5", "0.0.9pre1-cvs"));
|
||||||
test_eq(1, tor_version_as_new_as(
|
test_eq(1, tor_version_as_new_as(
|
||||||
|
Loading…
Reference in New Issue
Block a user