mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 06:13:31 +01:00
Fix DOCDOC entries in routerlist.c. Make more functions use SMARTLIST_FOREACH instead of raw loops. Replace router_list_superseded implementation with one that has a prayer of working.
svn:r5027
This commit is contained in:
parent
d9bf9e48c0
commit
76351b8416
@ -16,15 +16,16 @@ const char routerlist_c_id[] = "$Id$";
|
|||||||
|
|
||||||
/****************************************************************************/
|
/****************************************************************************/
|
||||||
|
|
||||||
|
/** Global list of a trusted_dir_server_t object for each trusted directory
|
||||||
|
* server. */
|
||||||
static smartlist_t *trusted_dir_servers = NULL;
|
static smartlist_t *trusted_dir_servers = NULL;
|
||||||
|
|
||||||
/* static function prototypes */
|
/* static function prototypes */
|
||||||
static routerinfo_t *
|
static routerinfo_t *router_pick_directory_server_impl(int requireother,
|
||||||
router_pick_directory_server_impl(int requireother, int fascistfirewall,
|
int fascistfirewall,
|
||||||
int for_v2_directory);
|
int for_v2_directory);
|
||||||
static trusted_dir_server_t *
|
static trusted_dir_server_t *router_pick_trusteddirserver_impl(
|
||||||
router_pick_trusteddirserver_impl(int need_v1_support,
|
int need_v1_support, int requireother, int fascistfirewall);
|
||||||
int requireother, int fascistfirewall);
|
|
||||||
static void mark_all_trusteddirservers_up(void);
|
static void mark_all_trusteddirservers_up(void);
|
||||||
static int router_nickname_is_in_list(routerinfo_t *router, const char *list);
|
static int router_nickname_is_in_list(routerinfo_t *router, const char *list);
|
||||||
static int router_nickname_matches(routerinfo_t *router, const char *nickname);
|
static int router_nickname_matches(routerinfo_t *router, const char *nickname);
|
||||||
@ -44,7 +45,7 @@ static routerlist_t *routerlist = NULL;
|
|||||||
extern int has_fetched_directory; /**< from main.c */
|
extern int has_fetched_directory; /**< from main.c */
|
||||||
|
|
||||||
/** Global list of all of the current network_status documents that we know
|
/** Global list of all of the current network_status documents that we know
|
||||||
* about. */
|
* about. This list is kept sorted by published_on. */
|
||||||
static smartlist_t *networkstatus_list = NULL;
|
static smartlist_t *networkstatus_list = NULL;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -79,7 +80,8 @@ router_reload_router_list(void)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** DOCDOC */
|
/** Repopulate our list of network_status_t objects from the list cached on
|
||||||
|
* disk. Return 0 on success, -1 on failure. */
|
||||||
int
|
int
|
||||||
router_reload_networkstatus(void)
|
router_reload_networkstatus(void)
|
||||||
{
|
{
|
||||||
@ -292,8 +294,6 @@ router_get_trusteddirserver_by_digest(const char *digest)
|
|||||||
* trusted dirservers and <b>retry_if_no_servers</b> is non-zero,
|
* trusted dirservers and <b>retry_if_no_servers</b> is non-zero,
|
||||||
* set them all as running again, and try again.
|
* set them all as running again, and try again.
|
||||||
* Other args are as in router_pick_trusteddirserver_impl().
|
* Other args are as in router_pick_trusteddirserver_impl().
|
||||||
*
|
|
||||||
* DOCDOC need_v1_support
|
|
||||||
*/
|
*/
|
||||||
trusted_dir_server_t *
|
trusted_dir_server_t *
|
||||||
router_pick_trusteddirserver(int need_v1_support,
|
router_pick_trusteddirserver(int need_v1_support,
|
||||||
@ -318,16 +318,15 @@ router_pick_trusteddirserver(int need_v1_support,
|
|||||||
* routerlist.
|
* routerlist.
|
||||||
* If <b>fascistfirewall</b> and we're not using a proxy,
|
* If <b>fascistfirewall</b> and we're not using a proxy,
|
||||||
* make sure the port we pick is allowed by options-\>firewallports.
|
* make sure the port we pick is allowed by options-\>firewallports.
|
||||||
* If <b>requireother</b>, it cannot be us.
|
* If <b>requireother</b>, it cannot be us. If <b>for_v2_directory</b>,
|
||||||
*
|
* choose a directory server new enough to support the v2 directory
|
||||||
* DOCDOC need_v1_support, for_v2_directory
|
* functionality.
|
||||||
*/
|
*/
|
||||||
static routerinfo_t *
|
static routerinfo_t *
|
||||||
router_pick_directory_server_impl(int requireother, int fascistfirewall,
|
router_pick_directory_server_impl(int requireother, int fascistfirewall,
|
||||||
int for_v2_directory)
|
int for_v2_directory)
|
||||||
{
|
{
|
||||||
int i;
|
routerinfo_t *result;
|
||||||
routerinfo_t *router;
|
|
||||||
smartlist_t *sl;
|
smartlist_t *sl;
|
||||||
|
|
||||||
if (!routerlist)
|
if (!routerlist)
|
||||||
@ -338,8 +337,8 @@ router_pick_directory_server_impl(int requireother, int fascistfirewall,
|
|||||||
|
|
||||||
/* Find all the running dirservers we know about. */
|
/* Find all the running dirservers we know about. */
|
||||||
sl = smartlist_create();
|
sl = smartlist_create();
|
||||||
for (i=0;i < smartlist_len(routerlist->routers); i++) {
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
|
||||||
router = smartlist_get(routerlist->routers, i);
|
{
|
||||||
if (!router->is_running || !router->dir_port || !router->is_verified)
|
if (!router->is_running || !router->dir_port || !router->is_verified)
|
||||||
continue;
|
continue;
|
||||||
if (requireother && router_is_me(router))
|
if (requireother && router_is_me(router))
|
||||||
@ -354,17 +353,18 @@ router_pick_directory_server_impl(int requireother, int fascistfirewall,
|
|||||||
router_digest_is_trusted_dir(router->identity_digest)))
|
router_digest_is_trusted_dir(router->identity_digest)))
|
||||||
continue;
|
continue;
|
||||||
smartlist_add(sl, router);
|
smartlist_add(sl, router);
|
||||||
}
|
});
|
||||||
|
|
||||||
router = smartlist_choose(sl);
|
result = smartlist_choose(sl);
|
||||||
smartlist_free(sl);
|
smartlist_free(sl);
|
||||||
return router;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Choose randomly from among the trusted dirservers that are up.
|
/** Choose randomly from among the trusted dirservers that are up.
|
||||||
* If <b>fascistfirewall</b> and we're not using a proxy,
|
* If <b>fascistfirewall</b> and we're not using a proxy,
|
||||||
* make sure the port we pick is allowed by options-\>firewallports.
|
* make sure the port we pick is allowed by options-\>firewallports.
|
||||||
* If <b>requireother</b>, it cannot be us.
|
* If <b>requireother</b>, it cannot be us. If <b>need_v1_support</b>, choose
|
||||||
|
* a trusted authority for the v1 directory system.
|
||||||
*/
|
*/
|
||||||
static trusted_dir_server_t *
|
static trusted_dir_server_t *
|
||||||
router_pick_trusteddirserver_impl(int need_v1_support,
|
router_pick_trusteddirserver_impl(int need_v1_support,
|
||||||
@ -555,14 +555,11 @@ static void
|
|||||||
router_add_running_routers_to_smartlist(smartlist_t *sl, int allow_unverified,
|
router_add_running_routers_to_smartlist(smartlist_t *sl, int allow_unverified,
|
||||||
int need_uptime, int need_capacity)
|
int need_uptime, int need_capacity)
|
||||||
{
|
{
|
||||||
routerinfo_t *router;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!routerlist)
|
if (!routerlist)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
for (i=0;i<smartlist_len(routerlist->routers);i++) {
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
|
||||||
router = smartlist_get(routerlist->routers, i);
|
{
|
||||||
if (router->is_running &&
|
if (router->is_running &&
|
||||||
(router->is_verified ||
|
(router->is_verified ||
|
||||||
(allow_unverified &&
|
(allow_unverified &&
|
||||||
@ -572,7 +569,7 @@ router_add_running_routers_to_smartlist(smartlist_t *sl, int allow_unverified,
|
|||||||
*/
|
*/
|
||||||
smartlist_add(sl, router);
|
smartlist_add(sl, router);
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Look through the routerlist until we find a router that has my key.
|
/** Look through the routerlist until we find a router that has my key.
|
||||||
@ -580,17 +577,14 @@ router_add_running_routers_to_smartlist(smartlist_t *sl, int allow_unverified,
|
|||||||
routerinfo_t *
|
routerinfo_t *
|
||||||
routerlist_find_my_routerinfo(void)
|
routerlist_find_my_routerinfo(void)
|
||||||
{
|
{
|
||||||
routerinfo_t *router;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
if (!routerlist)
|
if (!routerlist)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i=0;i<smartlist_len(routerlist->routers);i++) {
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
|
||||||
router = smartlist_get(routerlist->routers, i);
|
{
|
||||||
if (router_is_me(router))
|
if (router_is_me(router))
|
||||||
return router;
|
return router;
|
||||||
}
|
});
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -599,9 +593,8 @@ routerlist_find_my_routerinfo(void)
|
|||||||
* isn't a good one.
|
* isn't a good one.
|
||||||
*/
|
*/
|
||||||
routerinfo_t *
|
routerinfo_t *
|
||||||
router_find_exact_exit_enclave(const char *address, uint16_t port) {
|
router_find_exact_exit_enclave(const char *address, uint16_t port)
|
||||||
int i;
|
{
|
||||||
routerinfo_t *router;
|
|
||||||
uint32_t addr;
|
uint32_t addr;
|
||||||
struct in_addr in;
|
struct in_addr in;
|
||||||
|
|
||||||
@ -609,8 +602,8 @@ router_find_exact_exit_enclave(const char *address, uint16_t port) {
|
|||||||
return NULL; /* it's not an IP already */
|
return NULL; /* it's not an IP already */
|
||||||
addr = ntohl(in.s_addr);
|
addr = ntohl(in.s_addr);
|
||||||
|
|
||||||
for (i=0;i < smartlist_len(routerlist->routers); i++) {
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
|
||||||
router = smartlist_get(routerlist->routers, i);
|
{
|
||||||
log_fn(LOG_DEBUG,"Considering %s: %d, %u==%u, %d.",
|
log_fn(LOG_DEBUG,"Considering %s: %d, %u==%u, %d.",
|
||||||
router->nickname,
|
router->nickname,
|
||||||
router->is_running,
|
router->is_running,
|
||||||
@ -621,7 +614,7 @@ router_find_exact_exit_enclave(const char *address, uint16_t port) {
|
|||||||
router_compare_addr_to_addr_policy(addr, port, router->exit_policy) ==
|
router_compare_addr_to_addr_policy(addr, port, router->exit_policy) ==
|
||||||
ADDR_POLICY_ACCEPTED)
|
ADDR_POLICY_ACCEPTED)
|
||||||
return router;
|
return router;
|
||||||
}
|
});
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -800,8 +793,7 @@ router_nickname_matches(routerinfo_t *router, const char *nickname)
|
|||||||
routerinfo_t *
|
routerinfo_t *
|
||||||
router_get_by_nickname(const char *nickname)
|
router_get_by_nickname(const char *nickname)
|
||||||
{
|
{
|
||||||
int i, maybedigest;
|
int maybedigest;
|
||||||
routerinfo_t *router;
|
|
||||||
char digest[DIGEST_LEN];
|
char digest[DIGEST_LEN];
|
||||||
|
|
||||||
tor_assert(nickname);
|
tor_assert(nickname);
|
||||||
@ -816,13 +808,13 @@ router_get_by_nickname(const char *nickname)
|
|||||||
maybedigest = (strlen(nickname) == HEX_DIGEST_LEN) &&
|
maybedigest = (strlen(nickname) == HEX_DIGEST_LEN) &&
|
||||||
(base16_decode(digest,DIGEST_LEN,nickname,HEX_DIGEST_LEN) == 0);
|
(base16_decode(digest,DIGEST_LEN,nickname,HEX_DIGEST_LEN) == 0);
|
||||||
|
|
||||||
for (i=0;i<smartlist_len(routerlist->routers);i++) {
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
|
||||||
router = smartlist_get(routerlist->routers, i);
|
{
|
||||||
if (0 == strcasecmp(router->nickname, nickname) ||
|
if (0 == strcasecmp(router->nickname, nickname) ||
|
||||||
(maybedigest && 0 == memcmp(digest, router->identity_digest,
|
(maybedigest && 0 == memcmp(digest, router->identity_digest,
|
||||||
DIGEST_LEN)))
|
DIGEST_LEN)))
|
||||||
return router;
|
return router;
|
||||||
}
|
});
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -863,18 +855,15 @@ router_get_by_hexdigest(const char *hexdigest)
|
|||||||
routerinfo_t *
|
routerinfo_t *
|
||||||
router_get_by_digest(const char *digest)
|
router_get_by_digest(const char *digest)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
routerinfo_t *router;
|
|
||||||
|
|
||||||
tor_assert(digest);
|
tor_assert(digest);
|
||||||
|
|
||||||
if (!routerlist) return NULL;
|
if (!routerlist) return NULL;
|
||||||
|
|
||||||
for (i=0;i<smartlist_len(routerlist->routers);i++) {
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t*, router,
|
||||||
router = smartlist_get(routerlist->routers, i);
|
{
|
||||||
if (0 == memcmp(router->identity_digest, digest, DIGEST_LEN))
|
if (0 == memcmp(router->identity_digest, digest, DIGEST_LEN))
|
||||||
return router;
|
return router;
|
||||||
}
|
});
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
@ -1297,7 +1286,8 @@ router_load_routerlist_from_directory(const char *s,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**DOCDOC */
|
/** Helper: return a newly allocated string containing the name of the filename
|
||||||
|
* where we plan to cache <b>ns</b>. */
|
||||||
static char *
|
static char *
|
||||||
networkstatus_get_cache_filename(const networkstatus_t *ns)
|
networkstatus_get_cache_filename(const networkstatus_t *ns)
|
||||||
{
|
{
|
||||||
@ -1310,7 +1300,9 @@ networkstatus_get_cache_filename(const networkstatus_t *ns)
|
|||||||
return fn;
|
return fn;
|
||||||
|
|
||||||
}
|
}
|
||||||
/** DOCDOC */
|
|
||||||
|
/** Helper for smartlist_sort: Compare two networkstatus objects by
|
||||||
|
* publication date. */
|
||||||
static int
|
static int
|
||||||
_compare_networkstatus_published_on(const void **_a, const void **_b)
|
_compare_networkstatus_published_on(const void **_a, const void **_b)
|
||||||
{
|
{
|
||||||
@ -1323,11 +1315,25 @@ _compare_networkstatus_published_on(const void **_a, const void **_b)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** How far in the future do we allow a network-status to get? (seconds) */
|
/** How far in the future do we allow a network-status to get before removing
|
||||||
|
* it? (seconds) */
|
||||||
#define NETWORKSTATUS_ALLOW_SKEW (48*60*60)
|
#define NETWORKSTATUS_ALLOW_SKEW (48*60*60)
|
||||||
/** DOCDOC returns 0 on no problems, -1 on problems.
|
/** Given a string <b>s</b> containing a network status that we received at
|
||||||
* requested fingerprints must be upcased.
|
* <b>arrived_at</b> from <b>source</b>, try to parse it, see if we want to
|
||||||
* removes and frees items from requested_fingerpritns
|
* store it, and put it into our cache is necessary.
|
||||||
|
*
|
||||||
|
* If <b>source</b> is NS_FROM_DIR or NS_FROM_CACHE, do not replace our
|
||||||
|
* own networkstatus_t (if we're a directory server).
|
||||||
|
*
|
||||||
|
* If <b>source</b> is NS_FROM_CACHE, do not write our networkstatus_t to the
|
||||||
|
* cache.
|
||||||
|
*
|
||||||
|
* If <b>requested_fingerprints</b> is provided, it must contain a list of
|
||||||
|
* uppercased identity fingerprints. Do not update any networkstatus whose
|
||||||
|
* fingerprint is not on the list; after updating a networkstatus, remove its
|
||||||
|
* fingerprint from the list.
|
||||||
|
*
|
||||||
|
* Return 0 on success, -1 on failure.
|
||||||
*/
|
*/
|
||||||
int
|
int
|
||||||
router_set_networkstatus(const char *s, time_t arrived_at,
|
router_set_networkstatus(const char *s, time_t arrived_at,
|
||||||
@ -1430,8 +1436,10 @@ router_set_networkstatus(const char *s, time_t arrived_at,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** How old do we allow a network-status to get before removing it completely? */
|
||||||
#define MAX_NETWORKSTATUS_AGE (10*24*60*60)
|
#define MAX_NETWORKSTATUS_AGE (10*24*60*60)
|
||||||
/** DOCDOC */
|
/** Remove all very-old network_status_t objects from memory and from the
|
||||||
|
* disk cache. */
|
||||||
void
|
void
|
||||||
networkstatus_list_clean(time_t now)
|
networkstatus_list_clean(time_t now)
|
||||||
{
|
{
|
||||||
@ -1483,7 +1491,11 @@ networkstatus_find_entry(networkstatus_t *ns, const char *digest)
|
|||||||
/* XXXX These should be configurable, perhaps? NM */
|
/* XXXX These should be configurable, perhaps? NM */
|
||||||
#define AUTHORITY_NS_CACHE_INTERVAL 10*60
|
#define AUTHORITY_NS_CACHE_INTERVAL 10*60
|
||||||
#define NONAUTHORITY_NS_CACHE_INTERVAL 15*60
|
#define NONAUTHORITY_NS_CACHE_INTERVAL 15*60
|
||||||
/* DOCDOC*/
|
/** We are a directory server, and so cache network_status documents.
|
||||||
|
* Initiate downloads as needed to update them. For authorities, this means
|
||||||
|
* asking each trusted directory for its network-status. For caches, this means
|
||||||
|
* asking a random authority for all network-statuses.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
update_networkstatus_cache_downloads(time_t now)
|
update_networkstatus_cache_downloads(time_t now)
|
||||||
{
|
{
|
||||||
@ -1492,6 +1504,7 @@ update_networkstatus_cache_downloads(time_t now)
|
|||||||
int interval =
|
int interval =
|
||||||
authority ? AUTHORITY_NS_CACHE_INTERVAL : NONAUTHORITY_NS_CACHE_INTERVAL;
|
authority ? AUTHORITY_NS_CACHE_INTERVAL : NONAUTHORITY_NS_CACHE_INTERVAL;
|
||||||
|
|
||||||
|
/*XXXXX NM we should retry on failure. */
|
||||||
if (last_downloaded + interval >= now)
|
if (last_downloaded + interval >= now)
|
||||||
return;
|
return;
|
||||||
if (!trusted_dir_servers)
|
if (!trusted_dir_servers)
|
||||||
@ -1508,8 +1521,10 @@ update_networkstatus_cache_downloads(time_t now)
|
|||||||
continue;
|
continue;
|
||||||
if (connection_get_by_type_addr_port_purpose(
|
if (connection_get_by_type_addr_port_purpose(
|
||||||
CONN_TYPE_DIR, ds->addr, ds->dir_port,
|
CONN_TYPE_DIR, ds->addr, ds->dir_port,
|
||||||
DIR_PURPOSE_FETCH_NETWORKSTATUS))
|
DIR_PURPOSE_FETCH_NETWORKSTATUS)) {
|
||||||
|
/* We are already fetching this one. */
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
strlcpy(resource, "fp/", sizeof(resource));
|
strlcpy(resource, "fp/", sizeof(resource));
|
||||||
base16_encode(resource+3, sizeof(resource)-3, ds->digest, DIGEST_LEN);
|
base16_encode(resource+3, sizeof(resource)-3, ds->digest, DIGEST_LEN);
|
||||||
strlcat(resource, ".z", sizeof(resource));
|
strlcat(resource, ".z", sizeof(resource));
|
||||||
@ -1517,6 +1532,7 @@ update_networkstatus_cache_downloads(time_t now)
|
|||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
/* A non-authority cache launches one connection to a random authority. */
|
/* A non-authority cache launches one connection to a random authority. */
|
||||||
|
/* (Check whether we're currently fetching network-status objects.) */
|
||||||
if (!connection_get_by_type_purpose(CONN_TYPE_DIR,
|
if (!connection_get_by_type_purpose(CONN_TYPE_DIR,
|
||||||
DIR_PURPOSE_FETCH_NETWORKSTATUS))
|
DIR_PURPOSE_FETCH_NETWORKSTATUS))
|
||||||
directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,"all.z",1);
|
directory_get_from_dirserver(DIR_PURPOSE_FETCH_NETWORKSTATUS,"all.z",1);
|
||||||
@ -1530,7 +1546,10 @@ update_networkstatus_cache_downloads(time_t now)
|
|||||||
* before downloading the next in sequence? */
|
* before downloading the next in sequence? */
|
||||||
#define NETWORKSTATUS_CLIENT_DL_INTERVAL (30*60)
|
#define NETWORKSTATUS_CLIENT_DL_INTERVAL (30*60)
|
||||||
|
|
||||||
/** DOCDOC */
|
/** We are not a directory cache or authority. Update our network-status list
|
||||||
|
* by launching a new directory fetch for enough network-status documents "as
|
||||||
|
* necessary". See function comments for implementation details.
|
||||||
|
*/
|
||||||
void
|
void
|
||||||
update_networkstatus_client_downloads(time_t now)
|
update_networkstatus_client_downloads(time_t now)
|
||||||
{
|
{
|
||||||
@ -1562,7 +1581,7 @@ update_networkstatus_client_downloads(time_t now)
|
|||||||
if (ns->published_on > now-NETWORKSTATUS_MAX_VALIDITY)
|
if (ns->published_on > now-NETWORKSTATUS_MAX_VALIDITY)
|
||||||
++n_live;
|
++n_live;
|
||||||
if (!most_recent || ns->received_on > most_recent_received) {
|
if (!most_recent || ns->received_on > most_recent_received) {
|
||||||
most_recent_idx = ds_sl_idx; /* magic variable from FOREACH*/
|
most_recent_idx = ds_sl_idx; /* magic variable from FOREACH */
|
||||||
most_recent = ds;
|
most_recent = ds;
|
||||||
most_recent_received = ns->received_on;
|
most_recent_received = ns->received_on;
|
||||||
}
|
}
|
||||||
@ -1710,20 +1729,18 @@ int
|
|||||||
router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port,
|
router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port,
|
||||||
int need_uptime)
|
int need_uptime)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
routerinfo_t *router;
|
|
||||||
addr_policy_result_t r;
|
addr_policy_result_t r;
|
||||||
if (!routerlist) return 1;
|
if (!routerlist) return 1;
|
||||||
|
|
||||||
for (i=0;i<smartlist_len(routerlist->routers);i++) {
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, router,
|
||||||
router = smartlist_get(routerlist->routers, i);
|
{
|
||||||
if (router->is_running &&
|
if (router->is_running &&
|
||||||
!router_is_unreliable(router, need_uptime, 0)) {
|
!router_is_unreliable(router, need_uptime, 0)) {
|
||||||
r = router_compare_addr_to_addr_policy(addr, port, router->exit_policy);
|
r = router_compare_addr_to_addr_policy(addr, port, router->exit_policy);
|
||||||
if (r != ADDR_POLICY_REJECTED && r != ADDR_POLICY_PROBABLY_REJECTED)
|
if (r != ADDR_POLICY_REJECTED && r != ADDR_POLICY_PROBABLY_REJECTED)
|
||||||
return 0; /* this one could be ok. good enough. */
|
return 0; /* this one could be ok. good enough. */
|
||||||
}
|
}
|
||||||
}
|
});
|
||||||
return 1; /* all will reject. */
|
return 1; /* all will reject. */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2038,7 +2055,7 @@ add_trusted_dir_server(const char *address, uint16_t port, const char *digest,
|
|||||||
a = ntohl(a);
|
a = ntohl(a);
|
||||||
}
|
}
|
||||||
|
|
||||||
ent = tor_malloc(sizeof(trusted_dir_server_t));
|
ent = tor_malloc_zero(sizeof(trusted_dir_server_t));
|
||||||
ent->address = hostname;
|
ent->address = hostname;
|
||||||
ent->addr = a;
|
ent->addr = a;
|
||||||
ent->dir_port = port;
|
ent->dir_port = port;
|
||||||
@ -2061,6 +2078,7 @@ clear_trusted_dir_servers(void)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the network status with a given identity digest. */
|
||||||
networkstatus_t *
|
networkstatus_t *
|
||||||
networkstatus_get_by_digest(const char *digest)
|
networkstatus_get_by_digest(const char *digest)
|
||||||
{
|
{
|
||||||
@ -2072,8 +2090,15 @@ networkstatus_get_by_digest(const char *digest)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Allow any network-status newer than this to influence our view of who's
|
||||||
|
* running. */
|
||||||
#define DEFAULT_RUNNING_INTERVAL 60*60
|
#define DEFAULT_RUNNING_INTERVAL 60*60
|
||||||
|
/** If possible, always allow at least this many network-statuses to influence
|
||||||
|
* our view of who's running. */
|
||||||
#define MIN_TO_INFLUENCE_RUNNING 3
|
#define MIN_TO_INFLUENCE_RUNNING 3
|
||||||
|
/** Given a list <b>routers</b> of routerinfo_t *, update each routers's
|
||||||
|
* is_named, is_verified, and is_running fields according to our current
|
||||||
|
* networkstatus_t documents. */
|
||||||
void
|
void
|
||||||
routers_update_status_from_networkstatus(smartlist_t *routers)
|
routers_update_status_from_networkstatus(smartlist_t *routers)
|
||||||
{
|
{
|
||||||
@ -2151,32 +2176,55 @@ routers_update_status_from_networkstatus(smartlist_t *routers)
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Return new list of ID digests for superseded routers.
|
/** Return new list of ID digests for superseded routers. A router is
|
||||||
* A router is superseded if any network-status has a router with a different
|
* superseded if any network-status has a router with a different digest
|
||||||
* digest published more recently.
|
* published more recently, or it it is listed in the network-status but not
|
||||||
|
* in the router list.
|
||||||
*/
|
*/
|
||||||
smartlist_t *
|
smartlist_t *
|
||||||
router_list_superseded(void)
|
router_list_superseded(void)
|
||||||
{
|
{
|
||||||
smartlist_t *superseded = smartlist_create();
|
smartlist_t *superseded = smartlist_create();
|
||||||
|
strmap_t *most_recent = NULL;
|
||||||
|
char fp[HEX_DIGEST_LEN+1];
|
||||||
|
routerstatus_t *rs_old;
|
||||||
|
|
||||||
if (!routerlist || !networkstatus_list)
|
if (!routerlist || !networkstatus_list)
|
||||||
return superseded;
|
return superseded;
|
||||||
|
|
||||||
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
|
/* Build a map from fingerprint to most recent routerstatus_t. If this
|
||||||
|
* becomes inefficient, we can build most_recent lazily when a new
|
||||||
|
* networkstatus_t shows up.*/
|
||||||
|
most_recent = strmap_new();
|
||||||
|
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
||||||
{
|
{
|
||||||
SMARTLIST_FOREACH(networkstatus_list, networkstatus_t *, ns,
|
SMARTLIST_FOREACH(ns->entries, routerstatus_t *, rs,
|
||||||
{
|
{
|
||||||
routerstatus_t *rs = networkstatus_find_entry(ns, ri->identity_digest);
|
base16_encode(fp, sizeof(fp), rs->identity_digest, DIGEST_LEN);
|
||||||
if (memcmp(ri->signed_descriptor_digest,rs->descriptor_digest,DIGEST_LEN)
|
rs_old = strmap_get(most_recent, fp);
|
||||||
&& rs->published_on > ri->published_on) {
|
if (!rs_old || rs_old->published_on < rs->published_on)
|
||||||
char *d = tor_malloc(DIGEST_LEN);
|
strmap_set(most_recent, fp, rs);
|
||||||
memcpy(d, ri->identity_digest, DIGEST_LEN);
|
|
||||||
smartlist_add(superseded, d);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
/* Compare each router to the most recent routerstatus. */
|
||||||
|
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
|
||||||
|
{
|
||||||
|
routerstatus_t *rs;
|
||||||
|
base16_encode(fp, sizeof(fp), ri->identity_digest, DIGEST_LEN);
|
||||||
|
rs = strmap_get(most_recent, fp);
|
||||||
|
if (!rs)
|
||||||
|
continue;
|
||||||
|
if (memcmp(ri->signed_descriptor_digest,rs->descriptor_digest,DIGEST_LEN)
|
||||||
|
&& rs->published_on > ri->published_on) {
|
||||||
|
char *d = tor_malloc(DIGEST_LEN);
|
||||||
|
memcpy(d, ri->identity_digest, DIGEST_LEN);
|
||||||
|
smartlist_add(superseded, d);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
strmap_free(most_recent, NULL);
|
||||||
|
|
||||||
return superseded;
|
return superseded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user