mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-12-06 19:41:15 +01:00
Merge branch 'tickets_5529_5534_5974_6406'
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
o Code refactoring:
|
||||
- Move last_reachable and testing_since from routerinfo_t to
|
||||
node_t. Implements enhancement 5529.
|
||||
@@ -0,0 +1,4 @@
|
||||
o Major features (IPv6):
|
||||
Add support for bridge authorities to accept IPv6 bridge addresses
|
||||
and include them in network status documents. Implements
|
||||
enhancement 5534.
|
||||
@@ -0,0 +1,4 @@
|
||||
o Minor features:
|
||||
|
||||
- Add new configure option AuthDirHasIPv6Connectivity. Implements
|
||||
feature #5974.
|
||||
@@ -0,0 +1,4 @@
|
||||
o Minor features:
|
||||
|
||||
- Add new configure option AuthDirPublishIPv6. Implements
|
||||
enhancement #6406.
|
||||
@@ -1728,6 +1728,20 @@ DIRECTORY AUTHORITY SERVER OPTIONS
|
||||
votes on whether to accept relays as hidden service directories.
|
||||
(Default: 1)
|
||||
|
||||
**AuthDirHasIPv6Connectivity** **0**|**1**|**auto**::
|
||||
|
||||
Authoritative directories only. When set to 0, OR ports with an
|
||||
IPv6 address are being accepted without reachability testing.
|
||||
When set to 1, IPv6 OR ports are being tested just like IPv4 OR
|
||||
ports. When set to auto, Tor tries to find out if the authority
|
||||
relay has IPv6 connectivity or not. (Default: auto)
|
||||
|
||||
**AuthDirPublishIPv6** **0**|**1**::
|
||||
|
||||
Authoritative directories only. When set to 0, Tor will not
|
||||
include IPv6 OR ports in votes. When set to 1, Tor will vote for
|
||||
IPv6 OR ports. (Default: 0).
|
||||
|
||||
HIDDEN SERVICE OPTIONS
|
||||
----------------------
|
||||
|
||||
|
||||
@@ -201,6 +201,8 @@ static config_var_t _option_vars[] = {
|
||||
V(AuthDirListBadExits, BOOL, "0"),
|
||||
V(AuthDirMaxServersPerAddr, UINT, "2"),
|
||||
V(AuthDirMaxServersPerAuthAddr,UINT, "5"),
|
||||
V(AuthDirHasIPv6Connectivity, AUTOBOOL, "auto"),
|
||||
V(AuthDirPublishIPv6, BOOL, "0"),
|
||||
VAR("AuthoritativeDirectory", BOOL, AuthoritativeDir, "0"),
|
||||
V(AutomapHostsOnResolve, BOOL, "0"),
|
||||
V(AutomapHostsSuffixes, CSV, ".onion,.exit"),
|
||||
|
||||
@@ -1540,7 +1540,7 @@ connection_or_client_learned_peer_id(or_connection_t *conn,
|
||||
return -1;
|
||||
}
|
||||
if (authdir_mode_tests_reachability(options)) {
|
||||
dirserv_orconn_tls_done(conn->_base.address, conn->_base.port,
|
||||
dirserv_orconn_tls_done(&conn->_base.addr, conn->_base.port,
|
||||
(const char*)peer_id);
|
||||
}
|
||||
|
||||
|
||||
+74
-23
@@ -988,7 +988,7 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
|
||||
answer = ! we_are_hibernating();
|
||||
} else if (router->is_hibernating &&
|
||||
(router->cache_info.published_on +
|
||||
HIBERNATION_PUBLICATION_SKEW) > router->last_reachable) {
|
||||
HIBERNATION_PUBLICATION_SKEW) > node->last_reachable) {
|
||||
/* A hibernating router is down unless we (somehow) had contact with it
|
||||
* since it declared itself to be hibernating. */
|
||||
answer = 0;
|
||||
@@ -998,7 +998,7 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
|
||||
} else {
|
||||
/* Otherwise, a router counts as up if we found it reachable in the last
|
||||
REACHABLE_TIMEOUT seconds. */
|
||||
answer = (now < router->last_reachable + REACHABLE_TIMEOUT);
|
||||
answer = (now < node->last_reachable + REACHABLE_TIMEOUT);
|
||||
}
|
||||
|
||||
if (!answer && running_long_enough_to_decide_unreachable()) {
|
||||
@@ -1010,9 +1010,9 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
|
||||
it.
|
||||
*/
|
||||
time_t when = now;
|
||||
if (router->last_reachable &&
|
||||
router->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD < now)
|
||||
when = router->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD;
|
||||
if (node->last_reachable &&
|
||||
node->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD < now)
|
||||
when = node->last_reachable + REACHABILITY_TEST_CYCLE_PERIOD;
|
||||
rep_hist_note_router_unreachable(router->cache_info.identity_digest, when);
|
||||
}
|
||||
|
||||
@@ -2088,6 +2088,21 @@ routerstatus_format_entry(char *buf, size_t buf_len,
|
||||
return 0;
|
||||
|
||||
cp = buf + strlen(buf);
|
||||
|
||||
/* Possible "a" line, not included in consensus for now. */
|
||||
if (!tor_addr_is_null(&rs->ipv6_addr)) {
|
||||
const char *addr_str = fmt_and_decorate_addr(&rs->ipv6_addr);
|
||||
r = tor_snprintf(cp, buf_len - (cp-buf),
|
||||
"a %s:%d\n",
|
||||
addr_str,
|
||||
(int)rs->ipv6_orport);
|
||||
if (r<0) {
|
||||
log_warn(LD_BUG, "Not enough space in buffer.");
|
||||
return -1;
|
||||
}
|
||||
cp += strlen(cp);
|
||||
}
|
||||
|
||||
/* NOTE: Whenever this list expands, be sure to increase MAX_FLAG_LINE_LEN*/
|
||||
r = tor_snprintf(cp, buf_len - (cp-buf),
|
||||
"s%s%s%s%s%s%s%s%s%s%s%s%s%s\n",
|
||||
@@ -2453,6 +2468,16 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
|
||||
strlcpy(rs->nickname, ri->nickname, sizeof(rs->nickname));
|
||||
rs->or_port = ri->or_port;
|
||||
rs->dir_port = ri->dir_port;
|
||||
if (options->AuthDirPublishIPv6 == 1 &&
|
||||
!tor_addr_is_null(&ri->ipv6_addr) &&
|
||||
(options->AuthDirHasIPv6Connectivity == 0 ||
|
||||
node->last_reachable6 >= now - REACHABLE_TIMEOUT)) {
|
||||
/* We're configured for publishing IPv6 OR ports. There's an IPv6
|
||||
OR port and it's reachable (or we know that we're not on IPv6)
|
||||
so copy it to the routerstatus. */
|
||||
tor_addr_copy(&rs->ipv6_addr, &ri->ipv6_addr);
|
||||
rs->ipv6_orport = ri->ipv6_orport;
|
||||
}
|
||||
}
|
||||
|
||||
/** Routerstatus <b>rs</b> is part of a group of routers that are on
|
||||
@@ -3273,36 +3298,42 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
|
||||
* Inform the reachability checker that we could get to this guy.
|
||||
*/
|
||||
void
|
||||
dirserv_orconn_tls_done(const char *address,
|
||||
dirserv_orconn_tls_done(const tor_addr_t *addr,
|
||||
uint16_t or_port,
|
||||
const char *digest_rcvd)
|
||||
{
|
||||
routerinfo_t *ri;
|
||||
node_t *node = NULL;
|
||||
tor_addr_port_t orport;
|
||||
routerinfo_t *ri = NULL;
|
||||
time_t now = time(NULL);
|
||||
tor_assert(address);
|
||||
tor_assert(addr);
|
||||
tor_assert(digest_rcvd);
|
||||
|
||||
ri = router_get_mutable_by_digest(digest_rcvd);
|
||||
|
||||
if (ri == NULL)
|
||||
node = node_get_mutable_by_id(digest_rcvd);
|
||||
if (node == NULL || node->ri == NULL)
|
||||
return;
|
||||
ri = node->ri;
|
||||
|
||||
if (!strcasecmp(address, ri->address) && or_port == ri->or_port) {
|
||||
tor_addr_copy(&orport.addr, addr);
|
||||
orport.port = or_port;
|
||||
if (router_has_orport(ri, &orport)) {
|
||||
/* Found the right router. */
|
||||
if (!authdir_mode_bridge(get_options()) ||
|
||||
ri->purpose == ROUTER_PURPOSE_BRIDGE) {
|
||||
char addrstr[TOR_ADDR_BUF_LEN];
|
||||
/* This is a bridge or we're not a bridge authorititative --
|
||||
mark it as reachable. */
|
||||
tor_addr_t addr, *addrp=NULL;
|
||||
log_info(LD_DIRSERV, "Found router %s to be reachable at %s:%d. Yay.",
|
||||
router_describe(ri),
|
||||
address, ri->or_port);
|
||||
if (tor_addr_parse(&addr, ri->address) != -1)
|
||||
addrp = &addr;
|
||||
else
|
||||
log_warn(LD_BUG, "Couldn't parse IP address \"%s\"", ri->address);
|
||||
rep_hist_note_router_reachable(digest_rcvd, addrp, or_port, now);
|
||||
ri->last_reachable = now;
|
||||
tor_addr_to_str(addrstr, addr, sizeof(addrstr), 1),
|
||||
ri->or_port);
|
||||
if (tor_addr_family(addr) == AF_INET) {
|
||||
rep_hist_note_router_reachable(digest_rcvd, addr, or_port, now);
|
||||
node->last_reachable = now;
|
||||
} else if (tor_addr_family(addr) == AF_INET6) {
|
||||
/* No rephist for IPv6. */
|
||||
node->last_reachable6 = now;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3325,7 +3356,7 @@ dirserv_should_launch_reachability_test(const routerinfo_t *ri,
|
||||
/* It just came out of hibernation; launch a reachability test */
|
||||
return 1;
|
||||
}
|
||||
if (! routers_have_same_or_addr(ri, ri_old)) {
|
||||
if (! routers_have_same_or_addrs(ri, ri_old)) {
|
||||
/* Address or port changed; launch a reachability test */
|
||||
return 1;
|
||||
}
|
||||
@@ -3338,15 +3369,35 @@ dirserv_should_launch_reachability_test(const routerinfo_t *ri,
|
||||
void
|
||||
dirserv_single_reachability_test(time_t now, routerinfo_t *router)
|
||||
{
|
||||
node_t *node = NULL;
|
||||
tor_addr_t router_addr;
|
||||
|
||||
tor_assert(router);
|
||||
node = node_get_mutable_by_id(router->cache_info.identity_digest);
|
||||
tor_assert(node);
|
||||
|
||||
/* IPv4. */
|
||||
log_debug(LD_OR,"Testing reachability of %s at %s:%u.",
|
||||
router->nickname, router->address, router->or_port);
|
||||
/* Remember when we started trying to determine reachability */
|
||||
if (!router->testing_since)
|
||||
router->testing_since = now;
|
||||
if (!node->testing_since)
|
||||
node->testing_since = now;
|
||||
tor_addr_from_ipv4h(&router_addr, router->addr);
|
||||
connection_or_connect(&router_addr, router->or_port,
|
||||
router->cache_info.identity_digest);
|
||||
|
||||
/* Possible IPv6. */
|
||||
if (!tor_addr_is_null(&router->ipv6_addr)) {
|
||||
char addrstr[TOR_ADDR_BUF_LEN];
|
||||
log_debug(LD_OR, "Testing reachability of %s at %s:%u.",
|
||||
router->nickname,
|
||||
tor_addr_to_str(addrstr, &router->ipv6_addr, sizeof(addrstr), 1),
|
||||
router->ipv6_orport);
|
||||
if (!node->testing_since6)
|
||||
node->testing_since6 = now;
|
||||
connection_or_connect(&router->ipv6_addr, router->ipv6_orport,
|
||||
router->cache_info.identity_digest);
|
||||
}
|
||||
}
|
||||
|
||||
/** Auth dir server only: load balance such that we only
|
||||
|
||||
+1
-1
@@ -107,7 +107,7 @@ int dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
|
||||
int is_extrainfo);
|
||||
int dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
|
||||
const char **msg);
|
||||
void dirserv_orconn_tls_done(const char *address,
|
||||
void dirserv_orconn_tls_done(const tor_addr_t *addr,
|
||||
uint16_t or_port,
|
||||
const char *digest_rcvd);
|
||||
int dirserv_should_launch_reachability_test(const routerinfo_t *ri,
|
||||
|
||||
+33
-4
@@ -115,19 +115,48 @@ node_get_or_create(const char *identity_digest)
|
||||
return node;
|
||||
}
|
||||
|
||||
/** Add <b>ri</b> to the nodelist. */
|
||||
/** Called when a node's address changes. */
|
||||
static void
|
||||
node_addrs_changed(node_t *node)
|
||||
{
|
||||
node->last_reachable = node->last_reachable6 = 0;
|
||||
node->testing_since = node->testing_since6 = 0;
|
||||
node->country = -1;
|
||||
}
|
||||
|
||||
/** Add <b>ri</b> to an appropriate node in the nodelist. If we replace an
|
||||
* old routerinfo, and <b>ri_old_out</b> is not NULL, set *<b>ri_old_out</b>
|
||||
* to the previous routerinfo.
|
||||
*/
|
||||
node_t *
|
||||
nodelist_add_routerinfo(routerinfo_t *ri)
|
||||
nodelist_set_routerinfo(routerinfo_t *ri, routerinfo_t **ri_old_out)
|
||||
{
|
||||
node_t *node;
|
||||
const char *id_digest;
|
||||
int had_router = 0;
|
||||
tor_assert(ri);
|
||||
|
||||
init_nodelist();
|
||||
node = node_get_or_create(ri->cache_info.identity_digest);
|
||||
id_digest = ri->cache_info.identity_digest;
|
||||
node = node_get_or_create(id_digest);
|
||||
|
||||
if (node->ri) {
|
||||
if (!routers_have_same_or_addrs(node->ri, ri)) {
|
||||
node_addrs_changed(node);
|
||||
}
|
||||
had_router = 1;
|
||||
if (ri_old_out)
|
||||
*ri_old_out = node->ri;
|
||||
} else {
|
||||
if (ri_old_out)
|
||||
*ri_old_out = NULL;
|
||||
}
|
||||
node->ri = ri;
|
||||
|
||||
if (node->country == -1)
|
||||
node_set_country(node);
|
||||
|
||||
if (authdir_mode(get_options())) {
|
||||
if (authdir_mode(get_options()) && !had_router) {
|
||||
const char *discard=NULL;
|
||||
uint32_t status = dirserv_router_get_status(ri, &discard);
|
||||
dirserv_set_node_flags_from_authoritative_status(node, status);
|
||||
|
||||
+1
-1
@@ -15,7 +15,7 @@
|
||||
node_t *node_get_mutable_by_id(const char *identity_digest);
|
||||
const node_t *node_get_by_id(const char *identity_digest);
|
||||
const node_t *node_get_by_hex_id(const char *identity_digest);
|
||||
node_t *nodelist_add_routerinfo(routerinfo_t *ri);
|
||||
node_t *nodelist_set_routerinfo(routerinfo_t *ri, routerinfo_t **ri_old_out);
|
||||
node_t *nodelist_add_microdesc(microdesc_t *md);
|
||||
void nodelist_set_consensus(networkstatus_t *ns);
|
||||
|
||||
|
||||
+19
-12
@@ -1793,15 +1793,6 @@ typedef struct {
|
||||
* things; see notes on ROUTER_PURPOSE_* macros above.
|
||||
*/
|
||||
uint8_t purpose;
|
||||
|
||||
/* The below items are used only by authdirservers for
|
||||
* reachability testing. */
|
||||
|
||||
/** When was the last time we could reach this OR? */
|
||||
time_t last_reachable;
|
||||
/** When did we start testing reachability for this OR? */
|
||||
time_t testing_since;
|
||||
|
||||
} routerinfo_t;
|
||||
|
||||
/** Information needed to keep and cache a signed extra-info document. */
|
||||
@@ -1833,6 +1824,8 @@ typedef struct routerstatus_t {
|
||||
uint32_t addr; /**< IPv4 address for this router. */
|
||||
uint16_t or_port; /**< OR port for this router. */
|
||||
uint16_t dir_port; /**< Directory port for this router. */
|
||||
tor_addr_t ipv6_addr; /**< IPv6 address for this router. */
|
||||
uint16_t ipv6_orport; /**<IPV6 OR port for this router. */
|
||||
unsigned int is_authority:1; /**< True iff this router is an authority. */
|
||||
unsigned int is_exit:1; /**< True iff this router is a good exit. */
|
||||
unsigned int is_stable:1; /**< True iff this router stays up a long time. */
|
||||
@@ -2006,13 +1999,13 @@ typedef struct node_t {
|
||||
routerstatus_t *rs;
|
||||
|
||||
/* local info: copied from routerstatus, then possibly frobbed based
|
||||
* on experience. Authorities set this stuff directly. */
|
||||
* on experience. Authorities set this stuff directly. Note that
|
||||
* these reflect knowledge of the primary (IPv4) OR port only. */
|
||||
|
||||
unsigned int is_running:1; /**< As far as we know, is this OR currently
|
||||
* running? */
|
||||
unsigned int is_valid:1; /**< Has a trusted dirserver validated this OR?
|
||||
* (For Authdir: Have we validated this OR?)
|
||||
*/
|
||||
* (For Authdir: Have we validated this OR?) */
|
||||
unsigned int is_fast:1; /** Do we think this is a fast OR? */
|
||||
unsigned int is_stable:1; /** Do we think this is a stable OR? */
|
||||
unsigned int is_possible_guard:1; /**< Do we think this is an OK guard? */
|
||||
@@ -2036,7 +2029,19 @@ typedef struct node_t {
|
||||
/* Local info: derived. */
|
||||
|
||||
/** According to the geoip db what country is this router in? */
|
||||
/* XXXprop186 what is this suppose to mean with multiple OR ports? */
|
||||
country_t country;
|
||||
|
||||
/* The below items are used only by authdirservers for
|
||||
* reachability testing. */
|
||||
|
||||
/** When was the last time we could reach this OR? */
|
||||
time_t last_reachable; /* IPv4. */
|
||||
time_t last_reachable6; /* IPv6. */
|
||||
|
||||
/** When did we start testing reachability for this OR? */
|
||||
time_t testing_since; /* IPv4. */
|
||||
time_t testing_since6; /* IPv6. */
|
||||
} node_t;
|
||||
|
||||
/** How many times will we try to download a router's descriptor before giving
|
||||
@@ -3268,6 +3273,8 @@ typedef struct {
|
||||
int AuthDirMaxServersPerAuthAddr; /**< Do not permit more than this
|
||||
* number of servers per IP address shared
|
||||
* with an authority. */
|
||||
int AuthDirHasIPv6Connectivity; /**< Autoboolean: are we on IPv6? */
|
||||
int AuthDirPublishIPv6; /**< Boolean: should we list IPv6 OR ports? */
|
||||
|
||||
/** If non-zero, always vote the Fast flag for any relay advertising
|
||||
* this amount of capacity or more. */
|
||||
|
||||
@@ -2230,6 +2230,26 @@ router_get_pref_ipv6_orport(const routerinfo_t *router,
|
||||
ap_out->port = router->ipv6_orport;
|
||||
}
|
||||
|
||||
/** Return 1 if any of <b>router</b>'s addresses are <b>addr</b>.
|
||||
* Otherwise return 0. */
|
||||
int
|
||||
router_has_addr(const routerinfo_t *router, const tor_addr_t *addr)
|
||||
{
|
||||
return
|
||||
tor_addr_eq_ipv4h(addr, router->addr) ||
|
||||
tor_addr_eq(&router->ipv6_addr, addr);
|
||||
}
|
||||
|
||||
int
|
||||
router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport)
|
||||
{
|
||||
return
|
||||
(tor_addr_eq_ipv4h(&orport->addr, router->addr) &&
|
||||
orport->port == router->or_port) ||
|
||||
(tor_addr_eq(&orport->addr, &router->ipv6_addr) &&
|
||||
orport->port == router->ipv6_orport);
|
||||
}
|
||||
|
||||
/** Load the contents of <b>filename</b>, find the last line starting with
|
||||
* <b>end_line</b>, ensure that its timestamp is not more than 25 hours in
|
||||
* the past or more than 1 hour in the future with respect to <b>now</b>,
|
||||
|
||||
@@ -93,6 +93,8 @@ void router_get_pref_orport(const routerinfo_t *router,
|
||||
void router_get_pref_ipv6_orport(const routerinfo_t *router,
|
||||
tor_addr_port_t *addr_port_out);
|
||||
int router_ipv6_preferred(const routerinfo_t *router);
|
||||
int router_has_addr(const routerinfo_t *router, const tor_addr_t *addr);
|
||||
int router_has_orport(const routerinfo_t *router, const tor_addr_port_t *orport);
|
||||
int extrainfo_dump_to_string(char **s, extrainfo_t *extrainfo,
|
||||
crypto_pk_t *ident_key);
|
||||
int is_legal_nickname(const char *s);
|
||||
|
||||
+10
-10
@@ -1343,9 +1343,11 @@ mark_all_trusteddirservers_up(void)
|
||||
|
||||
/** Return true iff r1 and r2 have the same address and OR port. */
|
||||
int
|
||||
routers_have_same_or_addr(const routerinfo_t *r1, const routerinfo_t *r2)
|
||||
routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2)
|
||||
{
|
||||
return r1->addr == r2->addr && r1->or_port == r2->or_port;
|
||||
return r1->addr == r2->addr && r1->or_port == r2->or_port &&
|
||||
tor_addr_eq(&r1->ipv6_addr, &r2->ipv6_addr) &&
|
||||
r1->ipv6_orport == r2->ipv6_orport;
|
||||
}
|
||||
|
||||
/** Reset all internal variables used to count failed downloads of network
|
||||
@@ -2875,7 +2877,7 @@ routerlist_insert(routerlist_t *rl, routerinfo_t *ri)
|
||||
&ri->cache_info);
|
||||
smartlist_add(rl->routers, ri);
|
||||
ri->cache_info.routerlist_index = smartlist_len(rl->routers) - 1;
|
||||
nodelist_add_routerinfo(ri);
|
||||
nodelist_set_routerinfo(ri, NULL);
|
||||
router_dir_info_changed();
|
||||
#ifdef DEBUG_ROUTERLIST
|
||||
routerlist_assert_ok(rl);
|
||||
@@ -3104,8 +3106,11 @@ routerlist_replace(routerlist_t *rl, routerinfo_t *ri_old,
|
||||
tor_assert(0 <= idx && idx < smartlist_len(rl->routers));
|
||||
tor_assert(smartlist_get(rl->routers, idx) == ri_old);
|
||||
|
||||
nodelist_remove_routerinfo(ri_old);
|
||||
nodelist_add_routerinfo(ri_new);
|
||||
{
|
||||
routerinfo_t *ri_old_tmp=NULL;
|
||||
nodelist_set_routerinfo(ri_new, &ri_old_tmp);
|
||||
tor_assert(ri_old == ri_old_tmp);
|
||||
}
|
||||
|
||||
router_dir_info_changed();
|
||||
if (idx >= 0) {
|
||||
@@ -3442,11 +3447,6 @@ router_add_to_routerlist(routerinfo_t *router, const char **msg,
|
||||
/* Same key, and either new, or listed in the consensus. */
|
||||
log_debug(LD_DIR, "Replacing entry for router %s",
|
||||
router_describe(router));
|
||||
if (routers_have_same_or_addr(router, old_router)) {
|
||||
/* these carry over when the address and orport are unchanged. */
|
||||
router->last_reachable = old_router->last_reachable;
|
||||
router->testing_since = old_router->testing_since;
|
||||
}
|
||||
routerlist_replace(routerlist, old_router, router);
|
||||
if (!from_cache) {
|
||||
signed_desc_append_to_journal(&router->cache_info,
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ const routerstatus_t *router_pick_trusteddirserver(dirinfo_type_t type,
|
||||
int router_get_my_share_of_directory_requests(double *v2_share_out,
|
||||
double *v3_share_out);
|
||||
void router_reset_status_download_failures(void);
|
||||
int routers_have_same_or_addr(const routerinfo_t *r1, const routerinfo_t *r2);
|
||||
int routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2);
|
||||
int router_nickname_is_in_list(const routerinfo_t *router, const char *list);
|
||||
const routerinfo_t *routerlist_find_my_routerinfo(void);
|
||||
const node_t *router_find_exact_exit_enclave(const char *address,
|
||||
|
||||
Reference in New Issue
Block a user