[Author Prev][Author Next][Thread Prev][Thread Next][Author Index][Thread Index]
[or-cvs] Remove descriptor_list and use routerlist instead. Make di...
Update of /home/or/cvsroot/tor/src/or
In directory moria:/tmp/cvs-serv32430/src/or
Modified Files:
dirserv.c main.c or.h routerlist.c
Log Message:
Remove descriptor_list and use routerlist instead. Make directories manage routerlist a little better.
Index: dirserv.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/dirserv.c,v
retrieving revision 1.187
retrieving revision 1.188
diff -u -d -r1.187 -r1.188
--- dirserv.c 26 Aug 2005 20:08:12 -0000 1.187
+++ dirserv.c 26 Aug 2005 20:59:04 -0000 1.188
@@ -235,22 +235,14 @@
* Descriptor list
*/
-/** List of routerinfo_t for all server descriptors that this dirserv
- * is holding.
- * XXXX This should eventually get coalesced into routerlist.c
- */
-static smartlist_t *descriptor_list = NULL;
-
-/** Release all storage that the dirserv is holding for server
- * descriptors. */
-void
-dirserv_free_descriptors()
+static smartlist_t *
+get_descriptor_list(void)
{
- if (!descriptor_list)
- return;
- SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
- routerinfo_free(ri));
- smartlist_clear(descriptor_list);
+ routerlist_t *routerlist;
+ router_get_routerlist(&routerlist);
+ if (!routerlist)
+ return NULL;
+ return routerlist->routers;
}
/** Return -1 if <b>ri</b> has a private or otherwise bad address,
@@ -274,64 +266,18 @@
return 0;
}
-/** Parse the server descriptor at *desc and maybe insert it into the
- * list of server descriptors, and (if the descriptor is well-formed)
- * advance *desc immediately past the descriptor's end. Set msg to a
- * message that should be passed back to the origin of this descriptor, or
- * to NULL.
- *
- * Return 1 if descriptor is well-formed and accepted;
- * 0 if well-formed and server is unapproved but accepted;
- * -1 if it looks vaguely like a router descriptor but rejected;
- * -2 if we can't find a router descriptor in *desc.
- */
int
-dirserv_add_descriptor(const char **desc, const char **msg)
+dirserv_wants_to_reject_router(routerinfo_t *ri, int *verified,
+ const char **msg)
{
- routerinfo_t *ri = NULL, *ri_old=NULL;
- int i, r, found=-1;
- char *start, *end;
- char *desc_tmp = NULL;
- size_t desc_len;
- time_t now;
- int verified=1; /* whether we knew its fingerprint already */
- tor_assert(msg);
- *msg = NULL;
- if (!descriptor_list)
- descriptor_list = smartlist_create();
-
- start = strstr(*desc, "router ");
- if (!start) {
- log_fn(LOG_WARN, "no 'router' line found. This is not a descriptor.");
- return -2;
- }
- if ((end = strstr(start+6, "\nrouter "))) {
- ++end; /* Include NL. */
- } else if ((end = strstr(start+6, "\ndirectory-signature"))) {
- ++end;
- } else {
- end = start+strlen(start);
- }
- desc_len = end-start;
- desc_tmp = tor_strndup(start, desc_len); /* Is this strndup still needed???*/
-
- /* Check: is the descriptor syntactically valid? */
- ri = router_parse_entry_from_string(desc_tmp, NULL);
- tor_free(desc_tmp);
- if (!ri) {
- log(LOG_WARN, "Couldn't parse descriptor");
- *msg = "Rejected: Couldn't parse server descriptor.";
- return -1;
- }
/* Okay. Now check whether the fingerprint is recognized. */
- r = dirserv_router_fingerprint_is_known(ri);
+ int r = dirserv_router_fingerprint_is_known(ri);
+ time_t now;
if (r==-1) {
log_fn(LOG_WARN, "Known nickname '%s', wrong fingerprint. Not adding (ContactInfo '%s', platform '%s').",
ri->nickname, ri->contact_info ? ri->contact_info : "",
ri->platform ? ri->platform : "");
*msg = "Rejected: There is already a verified server with this nickname and a different fingerprint.";
- routerinfo_free(ri);
- *desc = end;
return -1;
} else if (r==0) {
char fp[FINGERPRINT_LEN+1];
@@ -342,7 +288,9 @@
} else {
log_fn(LOG_INFO, "Fingerprint line: %s %s", ri->nickname, fp);
}
- verified = 0;
+ *verified = 0;
+ } else {
+ *verified = 1;
}
/* Is there too much clock skew? */
now = time(NULL);
@@ -352,8 +300,6 @@
ri->contact_info ? ri->contact_info : "",
ri->platform ? ri->platform : "");
*msg = "Rejected: Your clock is set too far in the future, or your timezone is not correct.";
- routerinfo_free(ri);
- *desc = end;
return -1;
}
if (ri->published_on < now-ROUTER_MAX_AGE) {
@@ -362,8 +308,6 @@
ri->contact_info ? ri->contact_info : "",
ri->platform ? ri->platform : "");
*msg = "Rejected: Server is expired, or your clock is too far in the past, or your timezone is not correct.";
- routerinfo_free(ri);
- *desc = end;
return -1;
}
if (dirserv_router_has_valid_address(ri) < 0) {
@@ -372,55 +316,63 @@
ri->contact_info ? ri->contact_info : "",
ri->platform ? ri->platform : "");
*msg = "Rejected: Address is not an IP, or IP is a private address.";
- routerinfo_free(ri);
- *desc = end;
return -1;
}
- /* Do we already have an entry for this router? */
- for (i = 0; i < smartlist_len(descriptor_list); ++i) {
- ri_old = smartlist_get(descriptor_list, i);
- if (!memcmp(ri->identity_digest, ri_old->identity_digest, DIGEST_LEN)) {
- found = i;
- break;
- }
+ return 0;
+}
+
+
+
+/** Parse the server descriptor at *desc and maybe insert it into the
+ * list of server descriptors, and (if the descriptor is well-formed)
+ * advance *desc immediately past the descriptor's end. Set msg to a
+ * message that should be passed back to the origin of this descriptor, or
+ * to NULL.
+ *
+ * Return 1 if descriptor is well-formed and accepted;
+ * 0 if well-formed and server is unapproved but accepted;
+ * -1 if it looks vaguely like a router descriptor but rejected;
+ * -2 if we can't find a router descriptor in *desc.
+ */
+int
+dirserv_add_descriptor(const char **desc, const char **msg)
+{
+ routerinfo_t *ri = NULL;
+ char *start, *end;
+ char *desc_tmp = NULL;
+ size_t desc_len;
+ tor_assert(msg);
+ *msg = NULL;
+
+ start = strstr(*desc, "router ");
+ if (!start) {
+ log_fn(LOG_WARN, "no 'router' line found. This is not a descriptor.");
+ return -2;
}
- if (found >= 0) {
- char hex_digest[HEX_DIGEST_LEN+1];
- base16_encode(hex_digest, HEX_DIGEST_LEN+1, ri->identity_digest,DIGEST_LEN);
- /* if so, decide whether to update it. */
- if (ri_old->published_on >= ri->published_on) {
- /* We already have a newer or equal-time descriptor */
- log_fn(LOG_INFO,"We already have a new enough desc for server %s (nickname '%s'). Not adding.",hex_digest,ri->nickname);
- *msg = "We already have a newer descriptor.";
- /* This isn't really an error; return success. */
- routerinfo_free(ri);
- *desc = end;
- return verified;
- }
- /* We don't already have a newer one; we'll update this one. */
- log_fn(LOG_INFO,"Dirserv updating desc for server %s (nickname '%s')",hex_digest,ri->nickname);
- if (ri->addr == ri_old->addr && ri->or_port == ri_old->or_port) {
- ri->last_reachable = ri_old->last_reachable; /* these carry over */
- ri->testing_since = ri_old->testing_since;
- }
- *msg = verified?"Verified server updated":"Unverified server updated. (Have you sent us your key fingerprint?)";
- routerinfo_free(ri_old);
- smartlist_del_keeporder(descriptor_list, found);
+ if ((end = strstr(start+6, "\nrouter "))) {
+ ++end; /* Include NL. */
+ } else if ((end = strstr(start+6, "\ndirectory-signature"))) {
+ ++end;
} else {
- /* Add at the end. */
- log_fn(LOG_INFO,"Dirserv adding desc for nickname '%s'",ri->nickname);
- *msg = verified?"Verified server added":"Unverified server added. (Have you sent us your key fingerprint?)";
+ end = start+strlen(start);
}
+ desc_len = end-start;
+ desc_tmp = tor_strndup(start, desc_len); /* Is this strndup still needed???*/
- ri->is_verified = verified ||
- tor_version_as_new_as(ri->platform,"0.1.0.2-rc");
- smartlist_add(descriptor_list, ri);
-
- *desc = end;
- directory_set_dirty();
-
- return verified;
+ /* Check: is the descriptor syntactically valid? */
+ ri = router_parse_entry_from_string(desc_tmp, NULL);
+ tor_free(desc_tmp);
+ if (!ri) {
+ log(LOG_WARN, "Couldn't parse descriptor");
+ *msg = "Rejected: Couldn't parse server descriptor.";
+ return -1;
+ }
+ if (router_add_to_routerlist(ri, msg)) {
+ return -1;
+ } else {
+ return ri->is_verified ? 1 : 0;
+ }
}
/** Remove all descriptors whose nicknames or fingerprints no longer
@@ -431,27 +383,33 @@
directory_remove_invalid(void)
{
int i;
- int r;
- routerinfo_t *ent;
+ int changed = 0;
+ smartlist_t *descriptor_list = get_descriptor_list();
+
if (!descriptor_list)
- descriptor_list = smartlist_create();
+ return;
for (i = 0; i < smartlist_len(descriptor_list); ++i) {
- ent = smartlist_get(descriptor_list, i);
- r = dirserv_router_fingerprint_is_known(ent);
+ routerinfo_t *ent = smartlist_get(descriptor_list, i);
+ int r = dirserv_router_fingerprint_is_known(ent);
if (r<0) {
log(LOG_INFO, "Router '%s' is now verified with a key; removing old router with same name and different key.",
ent->nickname);
routerinfo_free(ent);
smartlist_del(descriptor_list, i--);
+ changed = 1;
} else if (r>0 && !ent->is_verified) {
log(LOG_INFO, "Router '%s' is now approved.", ent->nickname);
ent->is_verified = 1;
+ changed = 1;
} else if (r==0 && ent->is_verified) {
log(LOG_INFO, "Router '%s' is no longer approved.", ent->nickname);
ent->is_verified = 0;
+ changed = 1;
}
}
+ if (changed)
+ directory_set_dirty();
}
/** Write a list of unregistered descriptors into a newly allocated
@@ -467,6 +425,7 @@
char *answer;
routerinfo_t *ent;
int min_bw = atoi(question);
+ smartlist_t *descriptor_list = get_descriptor_list();
if (!descriptor_list)
return tor_strdup("");
@@ -608,7 +567,11 @@
* been found unreachable for the past several testing periods.
*/
void
-dirserv_log_unreachable_servers(time_t now) {
+dirserv_log_unreachable_servers(time_t now)
+{
+ smartlist_t *descriptor_list = get_descriptor_list();
+ if (!descriptor_list)
+ return;
SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
{
@@ -631,7 +594,9 @@
* (This function can go away when we merge descriptor-list and router-list.)
*/
void
-dirserv_router_has_begun_reachability_testing(char *digest, time_t now) {
+dirserv_router_has_begun_reachability_testing(char *digest, time_t now)
+{
+ smartlist_t *descriptor_list = get_descriptor_list();
if (!descriptor_list)
return;
SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
@@ -642,30 +607,6 @@
});
}
-/** Remove any descriptors from the directory that are more than <b>age</b>
- * seconds old.
- */
-void
-dirserv_remove_old_servers(int age)
-{
- int i;
- time_t cutoff;
- routerinfo_t *ent;
- if (!descriptor_list)
- descriptor_list = smartlist_create();
-
- cutoff = time(NULL) - age;
- for (i = 0; i < smartlist_len(descriptor_list); ++i) {
- ent = smartlist_get(descriptor_list, i);
- if (ent->published_on <= cutoff) {
- /* descriptor_list[i] is too old. Remove it. */
- routerinfo_free(ent);
- smartlist_del(descriptor_list, i--);
- directory_set_dirty();
- }
- }
-}
-
/* 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,
@@ -704,12 +645,13 @@
char *buf = NULL;
size_t buf_len;
size_t identity_pkey_len;
+ smartlist_t *descriptor_list = get_descriptor_list();
tor_assert(dir_out);
*dir_out = NULL;
if (!descriptor_list)
- descriptor_list = smartlist_create();
+ return -1;
if (list_server_status(descriptor_list, &router_status))
return -1;
@@ -722,14 +664,13 @@
recommended_versions = format_versions_list(get_options()->RecommendedVersions);
- dirserv_remove_old_servers(ROUTER_MAX_AGE);
published_on = time(NULL);
format_iso_time(published, published_on);
buf_len = 2048+strlen(recommended_versions)+
strlen(router_status);
SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
- buf_len += strlen(ri->signed_descriptor));
+ buf_len += ri->signed_descriptor_len);
buf = tor_malloc(buf_len);
/* We'll be comparing against buf_len throughout the rest of the
function, though strictly speaking we shouldn't be able to exceed
@@ -997,9 +938,7 @@
crypto_pk_env_t *private_key = get_identity_key();
char *identity_pkey; /* Identity key, DER64-encoded. */
size_t identity_pkey_len;
-
- if (!descriptor_list)
- descriptor_list = smartlist_create();
+ smartlist_t *descriptor_list = get_descriptor_list();
if (list_server_status(descriptor_list, &router_status)) {
goto err;
@@ -1113,6 +1052,12 @@
struct in_addr in;
uint32_t addr;
crypto_pk_env_t *private_key = get_identity_key();
+ smartlist_t *descriptor_list = get_descriptor_list();
+
+ if (!descriptor_list) {
+ log_fn(LOG_WARN, "Couldn't get router list.");
+ goto done;
+ }
if (resolve_my_address(options, &addr, &hostname)<0) {
log_fn(LOG_WARN, "Couldn't resolve my hostname");
@@ -1285,22 +1230,12 @@
void
dirserv_get_routerdescs(smartlist_t *descs_out, const char *key)
{
- smartlist_t *complete_list;
-
- /* This is annoying. Can we unify these? */
- if (descriptor_list)
- complete_list = descriptor_list;
- else {
- routerlist_t *rlst;
- router_get_routerlist(&rlst);
- complete_list = rlst->routers;
- }
-
+ smartlist_t *complete_list = get_descriptor_list();
if (!complete_list)
return;
if (!strcmp(key, "/tor/server/all")) {
- smartlist_add_all(descs_out, descriptor_list);
+ smartlist_add_all(descs_out, complete_list);
} else if (!strcmp(key, "/tor/server/authority")) {
routerinfo_t *ri = router_get_my_routerinfo();
if (ri)
@@ -1323,7 +1258,7 @@
smartlist_free(hexdigests);
/* XXXX should always return own descriptor. or special-case it. or
* something. */
- SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
+ SMARTLIST_FOREACH(complete_list, routerinfo_t *, ri,
SMARTLIST_FOREACH(digests, const char *, d,
if (!memcmp(d,ri->identity_digest,DIGEST_LEN)) {
smartlist_add(descs_out,ri);
@@ -1352,6 +1287,7 @@
int as_advertised)
{
int i;
+ smartlist_t *descriptor_list = get_descriptor_list();
tor_assert(address);
tor_assert(digest_rcvd);
tor_assert(nickname_rcvd);
@@ -1359,6 +1295,8 @@
if (!descriptor_list)
return;
+ // XXXXNM We should really have a better solution here than dropping
+ // XXXXNM whole routers; otherwise, they come back way too easily.
for (i = 0; i < smartlist_len(descriptor_list); ++i) {
routerinfo_t *ri = smartlist_get(descriptor_list, i);
int drop = 0;
@@ -1399,12 +1337,6 @@
smartlist_free(fingerprint_list);
fingerprint_list = NULL;
}
- if (descriptor_list) {
- SMARTLIST_FOREACH(descriptor_list, routerinfo_t *, ri,
- routerinfo_free(ri));
- smartlist_free(descriptor_list);
- descriptor_list = NULL;
- }
clear_cached_dir(&the_directory);
clear_cached_dir(&the_runningrouters);
clear_cached_dir(&cached_directory);
Index: main.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/main.c,v
retrieving revision 1.543
retrieving revision 1.544
diff -u -d -r1.543 -r1.544
--- main.c 26 Aug 2005 18:44:26 -0000 1.543
+++ main.c 26 Aug 2005 20:59:04 -0000 1.544
@@ -692,8 +692,6 @@
routerlist_remove_old_routers(ROUTER_MAX_AGE);
if (authdir_mode(options)) {
- /* Dump any old descriptors. */
- dirserv_remove_old_servers(ROUTER_MAX_AGE);
dirserv_log_unreachable_servers(now);
if (!we_are_hibernating()) { /* try to determine reachability */
router_retry_connections(1);
Index: or.h
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/or.h,v
retrieving revision 1.655
retrieving revision 1.656
diff -u -d -r1.655 -r1.656
--- or.h 26 Aug 2005 20:22:32 -0000 1.655
+++ or.h 26 Aug 2005 20:59:04 -0000 1.656
@@ -736,16 +736,17 @@
addr_policy_t *exit_policy; /**< What streams will this OR permit
* to exit? */
long uptime; /**< How many seconds the router claims to have been up */
- /* local info */
- int is_running; /**< As far as we know, is this OR currently running? */
- time_t status_set_at; /**< When did we last update is_running? */
- int is_verified; /**< Has a trusted dirserver validated this OR? */
-
smartlist_t *declared_family; /**< Nicknames of router which this router
* claims are its family. */
-
char *contact_info; /**< Declared contact info for this router. */
+ /* local info */
+ int is_running; /**< As far as we know, is this OR currently running? */
+ time_t status_set_at; /**< When did we last update is_running? */
+ int is_verified; /**< Has a trusted dirserver validated this OR?
+ * (For Authdir: Have we validated this OR?)
+ */
+
/* The below items are used only by authdirservers right now for
* reachability testing. */
time_t last_reachable; /**< When was the last time we could reach this OR? */
@@ -1636,7 +1637,6 @@
int list_server_status(smartlist_t *routers, char **router_status_out);
void dirserv_log_unreachable_servers(time_t now);
void dirserv_router_has_begun_reachability_testing(char *digest, time_t now);
-void dirserv_remove_old_servers(int age);
int dirserv_dump_directory_to_string(char **dir_out,
crypto_pk_env_t *private_key);
void directory_set_dirty(void);
@@ -1654,6 +1654,8 @@
const char *digest_rcvd,
const char *nickname,
int as_advertised);
+int dirserv_wants_to_reject_router(routerinfo_t *ri, int *verified,
+ const char **msg);
void dirserv_free_all(void);
/********************************* dns.c ***************************/
@@ -1991,6 +1993,7 @@
routerinfo_t *routerinfo_copy(const routerinfo_t *router);
void router_mark_as_down(const char *digest);
void routerlist_remove_old_routers(int age);
+int router_add_to_routerlist(routerinfo_t *router, const char **msg);
int router_load_single_router(const char *s, const char **msg);
int router_load_routerlist_from_directory(const char *s,crypto_pk_env_t *pkey,
int dir_is_recent, int dir_is_cached);
Index: routerlist.c
===================================================================
RCS file: /home/or/cvsroot/tor/src/or/routerlist.c,v
retrieving revision 1.254
retrieving revision 1.255
diff -u -d -r1.254 -r1.255
--- routerlist.c 26 Aug 2005 19:31:51 -0000 1.254
+++ routerlist.c 26 Aug 2005 20:59:04 -0000 1.255
@@ -861,40 +861,59 @@
* *<b>msg</b> a static string describing the reason for refusing the
* routerinfo.
*/
-static int
+int
router_add_to_routerlist(routerinfo_t *router, const char **msg)
{
int i;
- routerinfo_t *r;
char id_digest[DIGEST_LEN];
+ int authdir = get_options()->AuthoritativeDir;
+ int authdir_verified = 0;
tor_assert(routerlist);
crypto_pk_get_digest(router->identity_pkey, id_digest);
+ if (authdir) {
+ if (dirserv_wants_to_reject_router(router, &authdir_verified, msg))
+ return -1;
+ router->is_verified = authdir_verified;
+ if (tor_version_as_new_as(router->platform,"0.1.0.2-rc"))
+ router->is_verified = 1;
+ }
+
/* If we have a router with this name, and the identity key is the same,
* choose the newer one. If the identity key has changed, drop the router.
*/
for (i = 0; i < smartlist_len(routerlist->routers); ++i) {
- r = smartlist_get(routerlist->routers, i);
-
- if (!crypto_pk_cmp_keys(router->identity_pkey, r->identity_pkey)) {
- if (router->published_on > r->published_on) {
- log_fn(LOG_DEBUG, "Replacing entry for router '%s/%s' [%s]",
- router->nickname, r->nickname, hex_str(id_digest,DIGEST_LEN));
-//XXXRD /* Remember whether we trust this router as a dirserver. */
- routerinfo_free(r);
- smartlist_set(routerlist->routers, i, router);
- return 0;
- } else {
+ routerinfo_t *old_router = smartlist_get(routerlist->routers, i);
+ if (!crypto_pk_cmp_keys(router->identity_pkey,old_router->identity_pkey)) {
+ if (router->published_on <= old_router->published_on) {
log_fn(LOG_DEBUG, "Skipping not-new descriptor for router '%s'",
router->nickname);
- /* Update the is_running status to whatever we were told. */
- r->is_running = router->is_running;
+ if (!authdir)
+ /* Update the is_running status to whatever we were told. */
+ old_router->is_running = router->is_running;
routerinfo_free(router);
if (msg) *msg = "Router descriptor was not new.";
return -1;
+ } else {
+ log_fn(LOG_DEBUG, "Replacing entry for router '%s/%s' [%s]",
+ router->nickname, old_router->nickname,
+ hex_str(id_digest,DIGEST_LEN));
+ if (router->addr == old_router->addr &&
+ router->or_port == old_router->or_port) {
+ /* these carry over when the address and orport are unchanged.*/
+ router->last_reachable = old_router->last_reachable;
+ router->testing_since = old_router->testing_since;
+ }
+ if (msg)
+ *msg = authdir_verified ? "Verified server updated":
+ "Unverified server updated. (Have you sent us your key finerprint?)";
+ routerinfo_free(old_router);
+ smartlist_set(routerlist->routers, i, router);
+ directory_set_dirty();
+ return 0;
}
- } else if (!strcasecmp(router->nickname, r->nickname)) {
+ } else if (!strcasecmp(router->nickname, old_router->nickname)) {
/* nicknames match, keys don't. */
if (router->is_verified) {
/* The new verified router replaces the old one; remove the
@@ -905,14 +924,15 @@
* make new ones with the new key.
*/
connection_t *conn;
- while ((conn = connection_get_by_identity_digest(r->identity_digest,
- CONN_TYPE_OR))) {
- log_fn(LOG_INFO,"Closing conn to obsolete router '%s'", r->nickname);
+ while ((conn = connection_get_by_identity_digest(
+ old_router->identity_digest, CONN_TYPE_OR))) {
+ log_fn(LOG_INFO,"Closing conn to obsolete router '%s'",
+ old_router->nickname);
connection_mark_for_close(conn);
}
- routerinfo_free(r);
+ routerinfo_free(old_router);
smartlist_del_keeporder(routerlist->routers, i--);
- } else if (r->is_verified) {
+ } else if (old_router->is_verified) {
/* Can't replace a verified router with an unverified one. */
log_fn(LOG_DEBUG, "Skipping unverified entry for verified router '%s'",
router->nickname);
@@ -925,16 +945,13 @@
/* We haven't seen a router with this name before. Add it to the end of
* the list. */
smartlist_add(routerlist->routers, router);
+ directory_set_dirty();
return 0;
}
/** Remove any routers from the routerlist that are more than <b>age</b>
* seconds old.
- *
- * (This function is just like dirserv_remove_old_servers. One day we should
- * merge them.)
*/
-//XXXRD
void
routerlist_remove_old_routers(int age)
{
@@ -956,7 +973,7 @@
}
}
-/*
+/**
* Code to parse a single router descriptor and insert it into the
* routerlist. Return -1 if the descriptor was ill-formed; 0 if the
* descriptor was well-formed but could not be added; and 1 if the
@@ -965,6 +982,8 @@
* If we don't add it and <b>msg</b> is not NULL, then assign to
* *<b>msg</b> a static string describing the reason for refusing the
* descriptor.
+ *
+ * This is used only by the controller.
*/
int
router_load_single_router(const char *s, const char **msg)
@@ -1350,6 +1369,7 @@
time_t list_time,
const char *s)
{
+ int authdir = get_options()->AuthoritativeDir;
int is_running = 1;
int is_verified = 0;
int hex_digest_set = 0;
@@ -1421,13 +1441,22 @@
{
int nickname_matches = is_verified && !strcasecmp(r->nickname, nickname);
int digest_matches = !memcmp(digest, r->identity_digest, DIGEST_LEN);
- if (nickname_matches && digest_matches)
- r->is_verified = 1;
- else if (digest_matches)
- r->is_verified = 0;
+ if (!authdir) {
+ /* If we're not an authoritative directory, update verified status.
+ */
+ if (nickname_matches && digest_matches)
+ r->is_verified = 1;
+ else if (digest_matches)
+ r->is_verified = 0;
+ }
if (digest_matches)
if (r->status_set_at < list_time) {
- r->is_running = is_running;
+ if (!authdir || is_running)
+ /* If we're an authoritative directory, only believe that servers
+ * are down when we hear it ourselves. Otherwise, believe
+ * what we're told.
+ */
+ r->is_running = is_running;
r->status_set_at = time(NULL);
}
});