mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 04:13:28 +01:00
Add and document router-status line using new unified liveness/verifiedness format; continue to generate running-routers; continue to parse running-routers when no router-status line is found
svn:r2592
This commit is contained in:
parent
26f3cb8652
commit
b90b2bb848
@ -706,7 +706,7 @@ line, they must appear in the "ports" lines.
|
||||
|
||||
A Directory begins with a "signed-directory" item, followed by one each of
|
||||
the following, in any order: "recommended-software", "published",
|
||||
"running-routers". It may include any number of "opt" items. After these
|
||||
"router-status". It may include any number of "opt" items. After these
|
||||
items, a directory includes any number of router descriptors, and a single
|
||||
"directory-signature" item.
|
||||
|
||||
@ -723,7 +723,7 @@ items, a directory includes any number of router descriptors, and a single
|
||||
A list of which versions of which implementations are currently
|
||||
believed to be secure and compatible with the network.
|
||||
|
||||
"running-routers" comma-separated-list
|
||||
"running-routers" space-separated-list
|
||||
|
||||
A description of which routers are currently believed to be up or
|
||||
down. Every entry consists of an optional "!", followed by either an
|
||||
@ -733,8 +733,30 @@ items, a directory includes any number of router descriptors, and a single
|
||||
If a router's nickname is given, exactly one router of that nickname
|
||||
will appear in the directory, and that router is "approved" by the
|
||||
directory server. If a hashed identity key is given, that OR is not
|
||||
"approved".
|
||||
"approved". [XXXX The 'running-routers' line is only provided for
|
||||
backward compatibility. New code should parse 'router-status'
|
||||
instead.]
|
||||
|
||||
"router-status" space-separated-list
|
||||
|
||||
A description of which routers are currently believed to be up or
|
||||
down, and which are verified or unverified. Contains one entry for
|
||||
every router that the directory server knows. Each entry is of the
|
||||
format:
|
||||
|
||||
!name=$digest [Verified router, currently not live.]
|
||||
name=$digest [Verified router, currently live.]
|
||||
!$digest [Unverified router, currently not live.]
|
||||
or $digest [Unverified router, currently live.]
|
||||
|
||||
(where 'name' is the router's nickname and 'digest' is a hexadecimal
|
||||
encoding of the hash of the routers' identity key).
|
||||
|
||||
When parsing this line, clients should only mark a router as
|
||||
'verified' if its nickname AND digest match the one provided.
|
||||
[XXXX 'router-status' was added in 0.0.9pre5; older directory code
|
||||
uses 'running-routers' instead.]
|
||||
|
||||
"directory-signature" nickname-of-dirserver NL Signature
|
||||
|
||||
Note: The router descriptor for the directory server MUST appear first.
|
||||
@ -763,7 +785,7 @@ entries.
|
||||
|
||||
(see 7.2 above)
|
||||
|
||||
"running-routers" list
|
||||
"router-status" list
|
||||
|
||||
(see 7.2 above)
|
||||
|
||||
|
151
src/or/dirserv.c
151
src/or/dirserv.c
@ -20,7 +20,8 @@ extern or_options_t options; /**< command-line and config-file options */
|
||||
static int the_directory_is_dirty = 1;
|
||||
static int runningrouters_is_dirty = 1;
|
||||
|
||||
static int list_running_servers(char **nicknames_out);
|
||||
static int list_server_status(char **running_routers_out,
|
||||
char **router_status_out);
|
||||
static void directory_remove_unrecognized(void);
|
||||
static int dirserv_regenerate_directory(void);
|
||||
|
||||
@ -456,71 +457,80 @@ dirserv_load_from_directory_string(const char *dir)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/** Set *<b>nicknames_out</b> to a comma-separated list of all the ORs that we
|
||||
* believe are currently running (because we have open connections to
|
||||
* them). Return 0 on success; -1 on error.
|
||||
/**
|
||||
* Allocate and return a description of the status of the server <b>desc</b>,
|
||||
* for use in a running-routers line (if <b>rr_format</b> is true), or in a
|
||||
* router-status line (if <b>rr_format</b> is false. The server is listed
|
||||
* as running iff <b>is_live</b> is true.
|
||||
*/
|
||||
static char *
|
||||
list_single_server_status(descriptor_entry_t *desc, int is_live,
|
||||
int rr_format)
|
||||
{
|
||||
char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
|
||||
char *cp;
|
||||
|
||||
tor_assert(desc);
|
||||
tor_assert(desc->router);
|
||||
|
||||
cp = buf;
|
||||
if (!is_live) {
|
||||
*cp++ = '!';
|
||||
}
|
||||
if (desc->verified) {
|
||||
strcpy(cp, desc->nickname);
|
||||
cp += strlen(cp);
|
||||
if (!rr_format)
|
||||
*cp++ = '=';
|
||||
}
|
||||
if (!desc->verified || !rr_format) {
|
||||
*cp++ = '$';
|
||||
base16_encode(cp, HEX_DIGEST_LEN+1, desc->router->identity_digest,
|
||||
DIGEST_LEN);
|
||||
}
|
||||
return tor_strdup(buf);
|
||||
}
|
||||
|
||||
/** Allocate the contents of a running-routers line and a router-status line,
|
||||
* and store them in *<b>running_routers_out</b> and *<b>router_status_out</b>
|
||||
* respectively. Return 0 on success, -1 on failure.
|
||||
*/
|
||||
static int
|
||||
list_running_servers(char **nicknames_out)
|
||||
list_server_status(char **running_routers_out, char **router_status_out)
|
||||
{
|
||||
connection_t **connection_array;
|
||||
int n_conns;
|
||||
connection_t *conn;
|
||||
char *cp;
|
||||
int i;
|
||||
size_t length;
|
||||
smartlist_t *nicknames_up, *nicknames_down;
|
||||
char *name;
|
||||
const char *s;
|
||||
/* List of entries in running-routers style: An optional !, then either
|
||||
* a nickname or a dollar-prefixed hexdigest. */
|
||||
smartlist_t *rr_entries;
|
||||
/* List of entries in a router-status style: An optional !, then an optional
|
||||
* equals-suffixed nickname, then a dollar-prefixed hexdigest. */
|
||||
smartlist_t *rs_entries;
|
||||
|
||||
*nicknames_out = NULL;
|
||||
nicknames_up = smartlist_create();
|
||||
nicknames_down = smartlist_create();
|
||||
smartlist_add(nicknames_up, tor_strdup(options.Nickname));
|
||||
tor_assert(running_routers_out || router_status_out);
|
||||
|
||||
get_connection_array(&connection_array, &n_conns);
|
||||
for (i = 0; i<n_conns; ++i) {
|
||||
conn = connection_array[i];
|
||||
if (conn->type != CONN_TYPE_OR || !conn->nickname)
|
||||
continue; /* only list connections to ORs with certificates. */
|
||||
s = dirserv_get_nickname_by_digest(conn->identity_digest);
|
||||
if (s) {
|
||||
name = tor_strdup(s);
|
||||
} else {
|
||||
name = tor_malloc(HEX_DIGEST_LEN+2);
|
||||
*name = '$';
|
||||
base16_encode(name+1, HEX_DIGEST_LEN+1, conn->identity_digest, DIGEST_LEN);
|
||||
}
|
||||
rr_entries = smartlist_create();
|
||||
rs_entries = smartlist_create();
|
||||
|
||||
SMARTLIST_FOREACH(descriptor_list, descriptor_entry_t *, d,
|
||||
{
|
||||
int is_live;
|
||||
tor_assert(d->router);
|
||||
connection_t *conn = connection_get_by_identity_digest(
|
||||
d->router->identity_digest, CONN_TYPE_OR);
|
||||
is_live = (conn && conn->state == OR_CONN_STATE_OPEN);
|
||||
smartlist_add(rr_entries, list_single_server_status(d, is_live, 1));
|
||||
smartlist_add(rs_entries, list_single_server_status(d, is_live, 0));
|
||||
});
|
||||
|
||||
if (running_routers_out)
|
||||
*running_routers_out = smartlist_join_strings(rr_entries, " ", 0);
|
||||
if (router_status_out)
|
||||
*router_status_out = smartlist_join_strings(rs_entries, " ", 0);
|
||||
|
||||
SMARTLIST_FOREACH(rr_entries, char *, cp, tor_free(cp));
|
||||
SMARTLIST_FOREACH(rs_entries, char *, cp, tor_free(cp));
|
||||
smartlist_free(rr_entries);
|
||||
smartlist_free(rs_entries);
|
||||
|
||||
if(conn->state == OR_CONN_STATE_OPEN)
|
||||
smartlist_add(nicknames_up, name);
|
||||
else
|
||||
smartlist_add(nicknames_down, name);
|
||||
}
|
||||
length = smartlist_len(nicknames_up) +
|
||||
2*smartlist_len(nicknames_down) + 1;
|
||||
/* spaces + EOS + !'s + 1. */
|
||||
SMARTLIST_FOREACH(nicknames_up, char *, c, length += strlen(c));
|
||||
SMARTLIST_FOREACH(nicknames_down, char *, c, length += strlen(c));
|
||||
*nicknames_out = tor_malloc_zero(length);
|
||||
cp = *nicknames_out;
|
||||
for (i = 0; i<smartlist_len(nicknames_up); ++i) {
|
||||
if (i)
|
||||
strcat(cp, " ");
|
||||
strcat(cp, (char*)smartlist_get(nicknames_up,i)); /* can't overflow */
|
||||
while (*cp)
|
||||
++cp;
|
||||
}
|
||||
for (i = 0; i<smartlist_len(nicknames_down); ++i) {
|
||||
strcat(cp, " !");
|
||||
strcat(cp, (char*)smartlist_get(nicknames_down,i)); /* can't overflow */
|
||||
while (*cp)
|
||||
++cp;
|
||||
}
|
||||
SMARTLIST_FOREACH(nicknames_up, char *, victim, tor_free(victim));
|
||||
SMARTLIST_FOREACH(nicknames_down, char *, victim, tor_free(victim));
|
||||
smartlist_free(nicknames_up);
|
||||
smartlist_free(nicknames_down);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -557,7 +567,8 @@ int
|
||||
dirserv_dump_directory_to_string(char *s, size_t maxlen,
|
||||
crypto_pk_env_t *private_key)
|
||||
{
|
||||
char *cp, *eos;
|
||||
char *eos, *cp;
|
||||
char *running_routers, *router_status;
|
||||
char *identity_pkey; /* Identity key, DER64-encoded. */
|
||||
char *recommended_versions;
|
||||
char digest[20];
|
||||
@ -570,7 +581,7 @@ dirserv_dump_directory_to_string(char *s, size_t maxlen,
|
||||
if (!descriptor_list)
|
||||
descriptor_list = smartlist_create();
|
||||
|
||||
if (list_running_servers(&cp))
|
||||
if (list_server_status(&running_routers, &router_status))
|
||||
return -1;
|
||||
|
||||
/* ASN.1-encode the public key. This is a temporary measure; once
|
||||
@ -612,10 +623,13 @@ dirserv_dump_directory_to_string(char *s, size_t maxlen,
|
||||
"published %s\n"
|
||||
"recommended-software %s\n"
|
||||
"running-routers %s\n"
|
||||
"opt router-status %s\n"
|
||||
"opt dir-signing-key %s\n\n",
|
||||
published, recommended_versions, cp, identity_pkey);
|
||||
published, recommended_versions, running_routers, router_status,
|
||||
identity_pkey);
|
||||
|
||||
tor_free(cp);
|
||||
tor_free(running_routers);
|
||||
tor_free(router_status);
|
||||
tor_free(identity_pkey);
|
||||
i = strlen(s);
|
||||
cp = s+i;
|
||||
@ -788,6 +802,7 @@ static size_t runningrouters_len=0;
|
||||
static int generate_runningrouters(crypto_pk_env_t *private_key)
|
||||
{
|
||||
char *s, *cp;
|
||||
char *router_status;
|
||||
char digest[DIGEST_LEN];
|
||||
char signature[PK_BYTES];
|
||||
int i;
|
||||
@ -798,7 +813,7 @@ static int generate_runningrouters(crypto_pk_env_t *private_key)
|
||||
|
||||
len = 1024+(MAX_HEX_NICKNAME_LEN+2)*smartlist_len(descriptor_list);
|
||||
s = tor_malloc_zero(len);
|
||||
if (list_running_servers(&cp))
|
||||
if (list_server_status(NULL, &router_status))
|
||||
return -1;
|
||||
/* ASN.1-encode the public key. This is a temporary measure; once
|
||||
* everyone is running 0.0.9pre3 or later, we can shift to using a
|
||||
@ -822,12 +837,12 @@ static int generate_runningrouters(crypto_pk_env_t *private_key)
|
||||
format_iso_time(published, published_on);
|
||||
sprintf(s, "network-status\n"
|
||||
"published %s\n"
|
||||
"running-routers %s\n"
|
||||
"router-status %s\n"
|
||||
"opt dir-signing-key %s\n"
|
||||
"directory-signature %s\n"
|
||||
"-----BEGIN SIGNATURE-----\n",
|
||||
published, cp, identity_pkey, options.Nickname);
|
||||
tor_free(cp);
|
||||
published, router_status, identity_pkey, options.Nickname);
|
||||
tor_free(router_status);
|
||||
tor_free(identity_pkey);
|
||||
if (router_get_runningrouters_hash(s,digest)) {
|
||||
log_fn(LOG_WARN,"couldn't compute digest");
|
||||
|
@ -621,6 +621,7 @@ typedef struct running_routers_t {
|
||||
time_t published_on; /**< When was the list marked as published? */
|
||||
/** Which ORs are on the list? Entries may be prefixed with ! and $. */
|
||||
smartlist_t *running_routers;
|
||||
int is_running_routers_format; /**< Are we using the old entry format? */
|
||||
} running_routers_t;
|
||||
|
||||
/** Holds accounting information for a single step in the layered encryption
|
||||
@ -1469,9 +1470,14 @@ int router_exit_policy_rejects_all(routerinfo_t *router);
|
||||
void running_routers_free(running_routers_t *rr);
|
||||
void routerlist_update_from_runningrouters(routerlist_t *list,
|
||||
running_routers_t *rr);
|
||||
int routers_update_status_from_entry(smartlist_t *routers,
|
||||
time_t list_time,
|
||||
const char *s,
|
||||
int rr_format);
|
||||
int router_update_status_from_smartlist(routerinfo_t *r,
|
||||
time_t list_time,
|
||||
smartlist_t *running_list);
|
||||
smartlist_t *running_list,
|
||||
int rr_format);
|
||||
void add_trusted_dir_server(const char *addr, uint16_t port,const char *digest);
|
||||
void clear_trusted_dir_servers(void);
|
||||
|
||||
@ -1493,6 +1499,7 @@ int router_get_runningrouters_hash(const char *s, char *digest);
|
||||
int router_parse_list_from_string(const char **s,
|
||||
routerlist_t **dest,
|
||||
smartlist_t *good_nickname_list,
|
||||
int rr_format,
|
||||
time_t published);
|
||||
int router_parse_routerlist_from_directory(const char *s,
|
||||
routerlist_t **dest,
|
||||
|
@ -1018,8 +1018,8 @@ void running_routers_free(running_routers_t *rr)
|
||||
void routerlist_update_from_runningrouters(routerlist_t *list,
|
||||
running_routers_t *rr)
|
||||
{
|
||||
int n_routers, i;
|
||||
routerinfo_t *router, *me = router_get_my_routerinfo();
|
||||
routerinfo_t *me = router_get_my_routerinfo();
|
||||
smartlist_t *all_routers;
|
||||
if (!list)
|
||||
return;
|
||||
if (list->published_on >= rr->published_on)
|
||||
@ -1027,18 +1027,15 @@ void routerlist_update_from_runningrouters(routerlist_t *list,
|
||||
if (list->running_routers_updated_on >= rr->published_on)
|
||||
return;
|
||||
|
||||
if(me) { /* learn if the dirservers think I'm verified */
|
||||
router_update_status_from_smartlist(me,
|
||||
rr->published_on,
|
||||
rr->running_routers);
|
||||
}
|
||||
n_routers = smartlist_len(list->routers);
|
||||
for (i=0; i<n_routers; ++i) {
|
||||
router = smartlist_get(list->routers, i);
|
||||
router_update_status_from_smartlist(router,
|
||||
rr->published_on,
|
||||
rr->running_routers);
|
||||
}
|
||||
all_routers = smartlist_create();
|
||||
if(me) /* learn if the dirservers think I'm verified */
|
||||
smartlist_add(all_routers, me);
|
||||
|
||||
smartlist_add_all(all_routers,list->routers);
|
||||
SMARTLIST_FOREACH(rr->running_routers, const char *, cp,
|
||||
routers_update_status_from_entry(all_routers, rr->published_on,
|
||||
cp, rr->is_running_routers_format));
|
||||
smartlist_free(all_routers);
|
||||
list->running_routers_updated_on = rr->published_on;
|
||||
}
|
||||
|
||||
@ -1046,6 +1043,14 @@ void routerlist_update_from_runningrouters(routerlist_t *list,
|
||||
* based in its status in the list of strings stored in <b>running_list</b>.
|
||||
* All entries in <b>running_list</b> follow one of these formats:
|
||||
* <ol><li> <b>nickname</b> -- router is running and verified.
|
||||
* (running-routers format)
|
||||
* <li> !<b>nickname</b> -- router is not-running and verified.
|
||||
* (running-routers format)
|
||||
* <li> <b>nickname</b>=$<b>hexdigest</b> -- router is running and
|
||||
* verified. (router-status format)
|
||||
* (router-status format)
|
||||
* <li> !<b>nickname</b>=$<b>hexdigest</b> -- router is running and
|
||||
* verified. (router-status format)
|
||||
* <li> !<b>nickname</b> -- router is not-running and verified.
|
||||
* <li> $<b>hexdigest</b> -- router is running and unverified.
|
||||
* <li> !$<b>hexdigest</b> -- router is not-running and unverified.
|
||||
@ -1053,57 +1058,115 @@ void routerlist_update_from_runningrouters(routerlist_t *list,
|
||||
*
|
||||
* Return 1 if we found router in running_list, else return 0.
|
||||
*/
|
||||
int router_update_status_from_smartlist(routerinfo_t *router,
|
||||
time_t list_time,
|
||||
smartlist_t *running_list)
|
||||
int routers_update_status_from_entry(smartlist_t *routers,
|
||||
time_t list_time,
|
||||
const char *s,
|
||||
int rr_format)
|
||||
{
|
||||
int n_names, i, running, approved;
|
||||
const char *name;
|
||||
#if 1
|
||||
char *cp;
|
||||
size_t n;
|
||||
n = 0;
|
||||
for (i=0; i<smartlist_len(running_list); ++i) {
|
||||
name = smartlist_get(running_list, i);
|
||||
n += strlen(name) + 1;
|
||||
}
|
||||
cp = tor_malloc(n+2);
|
||||
cp[0] = '\0';
|
||||
for (i=0; i<smartlist_len(running_list); ++i) {
|
||||
name = smartlist_get(running_list, i);
|
||||
strlcat(cp, name, n);
|
||||
strlcat(cp, " ", n);
|
||||
}
|
||||
log_fn(LOG_DEBUG, "Updating status of %s from list \"%s\"",
|
||||
router->nickname, cp);
|
||||
tor_free(cp);
|
||||
#endif
|
||||
int is_running = 1;
|
||||
int is_verified = 0;
|
||||
int hex_digest_set = 0;
|
||||
char nickname[MAX_NICKNAME_LEN+1];
|
||||
char hexdigest[HEX_DIGEST_LEN+1];
|
||||
char digest[DIGEST_LEN];
|
||||
const char *cp, *end;
|
||||
|
||||
running = approved = 0;
|
||||
n_names = smartlist_len(running_list);
|
||||
for (i=0; i<n_names; ++i) {
|
||||
name = smartlist_get(running_list, i);
|
||||
if (*name != '!') {
|
||||
if (router_nickname_matches(router, name)) {
|
||||
if (router->status_set_at < list_time) {
|
||||
router->status_set_at = list_time;
|
||||
router->is_running = 1;
|
||||
}
|
||||
router->is_verified = (name[0] != '$');
|
||||
return 1;
|
||||
}
|
||||
} else { /* *name == '!' */
|
||||
name++;
|
||||
if (router_nickname_matches(router, name)) {
|
||||
if (router->status_set_at < list_time) {
|
||||
router->status_set_at = list_time;
|
||||
router->is_running = 0;
|
||||
}
|
||||
router->is_verified = (name[0] != '$');
|
||||
return 1;
|
||||
}
|
||||
/* First, parse the entry. */
|
||||
cp = s;
|
||||
if (*cp == '!') {
|
||||
is_running = 0;
|
||||
++cp;
|
||||
}
|
||||
|
||||
if (*cp != '$') {
|
||||
/* It starts with a non-dollar character; that's a nickname. The nickname
|
||||
* entry will either extend to a NUL (old running-routers format) or to an
|
||||
* equals sign (new router-status format). */
|
||||
is_verified = 1;
|
||||
end = strchr(cp, '=');
|
||||
if (!end)
|
||||
end = strchr(cp,'\0');
|
||||
tor_assert(end);
|
||||
/* 'end' now points on character beyond the end of the nickname */
|
||||
if (end == cp || end-cp > MAX_NICKNAME_LEN) {
|
||||
log_fn(LOG_WARN, "Bad nickname length (%d) in router status entry (%s)",
|
||||
end-cp, s);
|
||||
return -1;
|
||||
}
|
||||
memcpy(nickname, cp, end-cp);
|
||||
nickname[end-cp]='\0';
|
||||
if (!is_legal_nickname(nickname)) {
|
||||
log_fn(LOG_WARN, "Bad nickname (%s) in router status entry (%s)",
|
||||
nickname, s);
|
||||
return -1;
|
||||
}
|
||||
cp = end;
|
||||
if (*cp == '=')
|
||||
++cp;
|
||||
}
|
||||
/* 'end' now points to the start of a hex digest, or EOS. */
|
||||
|
||||
/* Parse the hexdigest portion of the status. */
|
||||
if (*cp == '$') {
|
||||
hex_digest_set = 1;
|
||||
++cp;
|
||||
if (strlen(cp) != HEX_DIGEST_LEN) {
|
||||
log_fn(LOG_WARN, "Bad length (%d) on digest in router status entry (%s)",
|
||||
strlen(cp), s);
|
||||
return -1;
|
||||
}
|
||||
strcpy(hexdigest, cp);
|
||||
if (base16_decode(digest, DIGEST_LEN, hexdigest, HEX_DIGEST_LEN)<0) {
|
||||
log_fn(LOG_WARN, "Invalid digest in router status entry (%s)", s);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Make sure that the entry was in the right format. */
|
||||
if (rr_format) {
|
||||
if (is_verified == hex_digest_set) {
|
||||
log_fn(LOG_WARN, "Invalid syntax for running-routers member (%s)", s);
|
||||
return -1;
|
||||
}
|
||||
} else {
|
||||
if (!hex_digest_set) {
|
||||
log_fn(LOG_WARN, "Invalid syntax for router-status member (%s)", s);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Okay, we're done parsing. For all routers that match, update their status.
|
||||
*/
|
||||
SMARTLIST_FOREACH(routers, routerinfo_t *, r,
|
||||
{
|
||||
int nickname_matches = is_verified && !strcasecmp(r->nickname, nickname);
|
||||
int digest_matches = !memcmp(digest, r->identity_digest, DIGEST_LEN);
|
||||
if (nickname_matches && (digest_matches||rr_format))
|
||||
r->is_verified = 1;
|
||||
else if (digest_matches)
|
||||
r->is_verified = 0;
|
||||
if (digest_matches || (nickname_matches&&rr_format))
|
||||
if (r->status_set_at < list_time) {
|
||||
r->is_running = is_running;
|
||||
r->status_set_at = time(NULL);
|
||||
}
|
||||
});
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int router_update_status_from_smartlist(routerinfo_t *router,
|
||||
time_t list_time,
|
||||
smartlist_t *running_list,
|
||||
int rr_format)
|
||||
{
|
||||
smartlist_t *rl;
|
||||
rl = smartlist_create();
|
||||
smartlist_add(rl,router);
|
||||
SMARTLIST_FOREACH(running_list, const char *, cp,
|
||||
routers_update_status_from_entry(rl,list_time,cp,rr_format));
|
||||
|
||||
smartlist_free(rl);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -32,6 +32,7 @@ typedef enum {
|
||||
K_ROUTER_SIGNATURE,
|
||||
K_PUBLISHED,
|
||||
K_RUNNING_ROUTERS,
|
||||
K_ROUTER_STATUS,
|
||||
K_PLATFORM,
|
||||
K_OPT,
|
||||
K_BANDWIDTH,
|
||||
@ -106,6 +107,7 @@ static struct {
|
||||
{ "onion-key", K_ONION_KEY, NO_ARGS, NEED_KEY,RTR_ONLY },
|
||||
{ "router-signature", K_ROUTER_SIGNATURE, NO_ARGS, NEED_OBJ,RTR_ONLY },
|
||||
{ "running-routers", K_RUNNING_ROUTERS, ARGS, NO_OBJ, DIR_ONLY },
|
||||
{ "router-status", K_ROUTER_STATUS, ARGS, NO_OBJ, DIR_ONLY },
|
||||
{ "ports", K_PORTS, ARGS, NO_OBJ, RTR_ONLY },
|
||||
{ "bandwidth", K_BANDWIDTH, ARGS, NO_OBJ, RTR_ONLY },
|
||||
{ "platform", K_PLATFORM, CONCAT_ARGS, NO_OBJ, RTR_ONLY },
|
||||
@ -393,9 +395,13 @@ router_parse_routerlist_from_directory(const char *str,
|
||||
}
|
||||
versions = tok->n_args ? tor_strdup(tok->args[0]) : tor_strdup("");
|
||||
|
||||
if (!(tok = find_first_by_keyword(tokens, K_RUNNING_ROUTERS))) {
|
||||
log_fn(LOG_WARN, "Missing running-routers line from directory.");
|
||||
goto err;
|
||||
/* Prefer router-status, then running-routers. */
|
||||
if (!(tok = find_first_by_keyword(tokens, K_ROUTER_STATUS))) {
|
||||
if (!(tok = find_first_by_keyword(tokens, K_RUNNING_ROUTERS))) {
|
||||
log_fn(LOG_WARN,
|
||||
"Missing running-routers/router-status line from directory.");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
good_nickname_list = smartlist_create();
|
||||
@ -408,11 +414,28 @@ router_parse_routerlist_from_directory(const char *str,
|
||||
* router. */
|
||||
str = end;
|
||||
if (router_parse_list_from_string(&str, &new_dir,
|
||||
good_nickname_list, published_on)) {
|
||||
good_nickname_list,
|
||||
tok->tp==K_RUNNING_ROUTERS,
|
||||
published_on)) {
|
||||
log_fn(LOG_WARN, "Error reading routers from directory");
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Determine if my routerinfo is considered verified. */
|
||||
{
|
||||
static int have_warned_about_unverified_status = 0;
|
||||
routerinfo_t *me = router_get_my_routerinfo();
|
||||
if(me) {
|
||||
if(router_update_status_from_smartlist(me, published_on,
|
||||
good_nickname_list,
|
||||
tok->tp==K_RUNNING_ROUTERS)==1 &&
|
||||
me->is_verified == 0 && !have_warned_about_unverified_status) {
|
||||
log_fn(LOG_WARN,"Dirserver %s lists your server as unverified. Please consider sending your identity fingerprint to the tor-ops.", dirnickname);
|
||||
have_warned_about_unverified_status = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
new_dir->software_versions = versions; versions = NULL;
|
||||
new_dir->published_on = published_on;
|
||||
|
||||
@ -420,20 +443,6 @@ router_parse_routerlist_from_directory(const char *str,
|
||||
smartlist_free(tokens);
|
||||
tokens = NULL;
|
||||
|
||||
/* Determine if my routerinfo is considered verified. */
|
||||
{
|
||||
static int have_warned_about_unverified_status = 0;
|
||||
routerinfo_t *me = router_get_my_routerinfo();
|
||||
if(me) {
|
||||
if(router_update_status_from_smartlist(me, published_on,
|
||||
good_nickname_list)==1 &&
|
||||
me->is_verified == 0 && !have_warned_about_unverified_status) {
|
||||
log_fn(LOG_WARN,"Dirserver %s lists your server as unverified. Please consider sending your identity fingerprint to the tor-ops.", dirnickname);
|
||||
have_warned_about_unverified_status = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (*dest)
|
||||
routerlist_free(*dest);
|
||||
*dest = new_dir;
|
||||
@ -497,14 +506,18 @@ router_parse_runningrouters(const char *str)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!(tok = find_first_by_keyword(tokens, K_RUNNING_ROUTERS))) {
|
||||
log_fn(LOG_WARN, "Missing running-routers line from directory.");
|
||||
goto err;
|
||||
if (!(tok = find_first_by_keyword(tokens, K_ROUTER_STATUS))) {
|
||||
if (!(tok = find_first_by_keyword(tokens, K_RUNNING_ROUTERS))) {
|
||||
log_fn(LOG_WARN,
|
||||
"Missing running-routers/router-status line from directory.");
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
new_list = tor_malloc_zero(sizeof(running_routers_t));
|
||||
new_list->published_on = published_on;
|
||||
new_list->running_routers = smartlist_create();
|
||||
new_list->is_running_routers_format = (tok->tp == K_RUNNING_ROUTERS);
|
||||
for (i=0;i<tok->n_args;++i) {
|
||||
smartlist_add(new_list->running_routers, tok->args[i]);
|
||||
}
|
||||
@ -661,7 +674,7 @@ static int check_directory_signature(const char *digest,
|
||||
int
|
||||
router_parse_list_from_string(const char **s, routerlist_t **dest,
|
||||
smartlist_t *good_nickname_list,
|
||||
time_t published_on)
|
||||
int rr_format, time_t published_on)
|
||||
{
|
||||
routerinfo_t *router;
|
||||
smartlist_t *routers;
|
||||
@ -692,10 +705,7 @@ router_parse_list_from_string(const char **s, routerlist_t **dest,
|
||||
continue;
|
||||
}
|
||||
|
||||
if (good_nickname_list) {
|
||||
router_update_status_from_smartlist(router, published_on,
|
||||
good_nickname_list);
|
||||
} else {
|
||||
if (!good_nickname_list) {
|
||||
router->is_running = 1; /* start out assuming all dirservers are up */
|
||||
router->is_verified = 1;
|
||||
router->status_set_at = time(NULL);
|
||||
@ -704,6 +714,12 @@ router_parse_list_from_string(const char **s, routerlist_t **dest,
|
||||
log_fn(LOG_DEBUG,"just added router #%d.",smartlist_len(routers));
|
||||
}
|
||||
|
||||
if (good_nickname_list) {
|
||||
SMARTLIST_FOREACH(good_nickname_list, const char *, cp,
|
||||
routers_update_status_from_entry(routers, published_on,
|
||||
cp, rr_format));
|
||||
}
|
||||
|
||||
if (*dest)
|
||||
routerlist_free(*dest);
|
||||
*dest = tor_malloc_zero(sizeof(routerlist_t));
|
||||
|
Loading…
Reference in New Issue
Block a user