Merge branch 'nodes'

This commit is contained in:
Nick Mathewson
2010-10-13 16:04:25 -04:00
46 changed files with 2550 additions and 1228 deletions
+10
View File
@@ -0,0 +1,10 @@
o Code refactorings
- Unified our node-listing and selecting logic. We had at least
two major ways to look at the question of "which Tor servers do
we know about": our list of router descriptors, and the current
consensus. We're adding a third in microdescriptors. Having
so many systems without an abstraction layer over them was
hurting the codebase. Now, we have a new "node_t" abstraction
that presents a consistent interface to a client's view of
a Tor node, and holds (nearly) all of the mutable state
formerly in routerinfo_t and routerstatus_t.
+4
View File
@@ -0,0 +1,4 @@
o Minor features
- The NodeFamily option -- which let you declare that you want to
consider nodes to be part of a family whether they list themselves
that way or not -- now allows IP address ranges and country codes.
+2 -1
View File
@@ -571,7 +571,8 @@ The following options are useful only for clients (that is, if
constitute a "family" of similar or co-administered servers, so never use
any two of them in the same circuit. Defining a NodeFamily is only needed
when a server doesn't list the family itself (with MyFamily). This option
can be used multiple times.
can be used multiple times. In addition to nodes, you can also list
IP address and ranges and country codes in {curly braces}.
**EnforceDistinctSubnets** **0**|**1**::
If 1, Tor will not put two servers whose IP addresses are "too close" on
+1 -1
View File
@@ -311,7 +311,7 @@ tor_addr_is_internal(const tor_addr_t *addr, int for_listening)
* brackets.
*/
const char *
tor_addr_to_str(char *dest, const tor_addr_t *addr, int len, int decorate)
tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len, int decorate)
{
const char *ptr;
tor_assert(addr && dest);
+1 -1
View File
@@ -144,7 +144,7 @@ int tor_addr_port_parse(const char *s, tor_addr_t *addr_out,
int tor_addr_parse_mask_ports(const char *s,
tor_addr_t *addr_out, maskbits_t *mask_out,
uint16_t *port_min_out, uint16_t *port_max_out);
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, int len,
const char * tor_addr_to_str(char *dest, const tor_addr_t *addr, size_t len,
int decorate);
int tor_addr_from_str(tor_addr_t *addr, const char *src);
void tor_addr_copy(tor_addr_t *dest, const tor_addr_t *src);
-1
View File
@@ -268,7 +268,6 @@ smartlist_subtract(smartlist_t *sl1, const smartlist_t *sl2)
/** Remove the <b>idx</b>th element of sl; if idx is not the last
* element, swap the last element of sl into the <b>idx</b>th space.
* Return the old value of the <b>idx</b>th element.
*/
void
smartlist_del(smartlist_t *sl, int idx)
+1 -1
View File
@@ -934,7 +934,7 @@ esc_for_log(const char *s)
char *result, *outp;
size_t len = 3;
if (!s) {
return tor_strdup("");
return tor_strdup("(null)");
}
for (cp = s; *cp; ++cp) {
+2 -1
View File
@@ -21,7 +21,7 @@ libtor_a_SOURCES = buffers.c circuitbuild.c circuitlist.c \
cpuworker.c directory.c dirserv.c dirvote.c \
dns.c dnsserv.c geoip.c hibernate.c main.c $(tor_platform_source) \
microdesc.c \
networkstatus.c onion.c policies.c \
networkstatus.c nodelist.c onion.c policies.c \
reasons.c relay.c rendcommon.c rendclient.c rendmid.c \
rendservice.c rephist.c router.c routerlist.c routerparse.c \
$(evdns_source) config_codedigest.c
@@ -56,6 +56,7 @@ noinst_HEADERS = buffers.h circuitbuild.h circuitlist.h circuituse.h \
command.h config.h connection_edge.h connection.h connection_or.h \
control.h cpuworker.h directory.h dirserv.h dirvote.h dns.h \
dnsserv.h geoip.h hibernate.h main.h microdesc.h networkstatus.h \
nodelist.h \
ntmain.h onion.h policies.h reasons.h relay.h rendclient.h \
rendcommon.h rendmid.h rendservice.h rephist.h router.h routerlist.h \
routerparse.h or.h eventdns.h eventdns_tor.h micro-revision.i
+254 -226
View File
File diff suppressed because it is too large Load Diff
+7 -6
View File
@@ -44,10 +44,11 @@ void onion_append_to_cpath(crypt_path_t **head_ptr, crypt_path_t *new_hop);
extend_info_t *extend_info_alloc(const char *nickname, const char *digest,
crypto_pk_env_t *onion_key,
const tor_addr_t *addr, uint16_t port);
extend_info_t *extend_info_from_router(routerinfo_t *r);
extend_info_t *extend_info_from_router(const routerinfo_t *r);
extend_info_t *extend_info_from_node(const node_t *node);
extend_info_t *extend_info_dup(extend_info_t *info);
void extend_info_free(extend_info_t *info);
routerinfo_t *build_state_get_exit_router(cpath_build_state_t *state);
const node_t *build_state_get_exit_node(cpath_build_state_t *state);
const char *build_state_get_exit_nickname(cpath_build_state_t *state);
void entry_guards_compute_status(or_options_t *options, time_t now);
@@ -55,7 +56,7 @@ int entry_guard_register_connect_status(const char *digest, int succeeded,
int mark_relay_status, time_t now);
void entry_nodes_should_be_added(void);
int entry_list_is_constrained(or_options_t *options);
routerinfo_t *choose_random_entry(cpath_build_state_t *state);
const node_t *choose_random_entry(cpath_build_state_t *state);
int entry_guards_parse_state(or_state_t *state, int set, char **msg);
void entry_guards_update_state(or_state_t *state);
int getinfo_helper_entry_guards(control_connection_t *conn,
@@ -63,9 +64,9 @@ int getinfo_helper_entry_guards(control_connection_t *conn,
const char **errmsg);
void clear_bridge_list(void);
int routerinfo_is_a_configured_bridge(routerinfo_t *ri);
void
learned_router_identity(tor_addr_t *addr, uint16_t port, const char *digest);
int routerinfo_is_a_configured_bridge(const routerinfo_t *ri);
void learned_router_identity(tor_addr_t *addr, uint16_t port,
const char *digest);
void bridge_add_from_config(const tor_addr_t *addr, uint16_t port,
char *digest);
void retry_bridge_descriptor_fetch_directly(const char *digest);
+5 -4
View File
@@ -19,6 +19,7 @@
#include "connection_or.h"
#include "control.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "onion.h"
#include "relay.h"
#include "rendclient.h"
@@ -946,15 +947,15 @@ circuit_find_to_cannibalize(uint8_t purpose, extend_info_t *info,
if (info) {
/* need to make sure we don't duplicate hops */
crypt_path_t *hop = circ->cpath;
routerinfo_t *ri1 = router_get_by_digest(info->identity_digest);
const node_t *ri1 = node_get_by_id(info->identity_digest);
do {
routerinfo_t *ri2;
const node_t *ri2;
if (!memcmp(hop->extend_info->identity_digest,
info->identity_digest, DIGEST_LEN))
goto next;
if (ri1 &&
(ri2 = router_get_by_digest(hop->extend_info->identity_digest))
&& routers_in_same_family(ri1, ri2))
(ri2 = node_get_by_id(hop->extend_info->identity_digest))
&& nodes_in_same_family(ri1, ri2))
goto next;
hop=hop->next;
} while (hop!=circ->cpath);
+30 -37
View File
@@ -17,6 +17,7 @@
#include "connection.h"
#include "connection_edge.h"
#include "control.h"
#include "nodelist.h"
#include "policies.h"
#include "rendclient.h"
#include "rendcommon.h"
@@ -43,7 +44,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
int need_uptime, int need_internal,
time_t now)
{
routerinfo_t *exitrouter;
const node_t *exitnode;
cpath_build_state_t *build_state;
tor_assert(circ);
tor_assert(conn);
@@ -85,7 +86,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
* of the one we meant to finish at.
*/
build_state = TO_ORIGIN_CIRCUIT(circ)->build_state;
exitrouter = build_state_get_exit_router(build_state);
exitnode = build_state_get_exit_node(build_state);
if (need_uptime && !build_state->need_uptime)
return 0;
@@ -93,7 +94,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
return 0;
if (purpose == CIRCUIT_PURPOSE_C_GENERAL) {
if (!exitrouter && !build_state->onehop_tunnel) {
if (!exitnode && !build_state->onehop_tunnel) {
log_debug(LD_CIRC,"Not considering circuit with unknown router.");
return 0; /* this circuit is screwed and doesn't know it yet,
* or is a rendezvous circuit. */
@@ -127,7 +128,7 @@ circuit_is_acceptable(circuit_t *circ, edge_connection_t *conn,
return 0;
}
}
if (exitrouter && !connection_ap_can_use_exit(conn, exitrouter, 0)) {
if (exitnode && !connection_ap_can_use_exit(conn, exitnode, 0)) {
/* can't exit from this router */
return 0;
}
@@ -473,7 +474,7 @@ circuit_stream_is_being_handled(edge_connection_t *conn,
uint16_t port, int min)
{
circuit_t *circ;
routerinfo_t *exitrouter;
const node_t *exitnode;
int num=0;
time_t now = time(NULL);
int need_uptime = smartlist_string_num_isin(get_options()->LongLivedPorts,
@@ -489,14 +490,14 @@ circuit_stream_is_being_handled(edge_connection_t *conn,
if (build_state->is_internal || build_state->onehop_tunnel)
continue;
exitrouter = build_state_get_exit_router(build_state);
if (exitrouter && (!need_uptime || build_state->need_uptime)) {
exitnode = build_state_get_exit_node(build_state);
if (exitnode && (!need_uptime || build_state->need_uptime)) {
int ok;
if (conn) {
ok = connection_ap_can_use_exit(conn, exitrouter, 0);
ok = connection_ap_can_use_exit(conn, exitnode, 0);
} else {
addr_policy_result_t r = compare_addr_to_addr_policy(
0, port, exitrouter->exit_policy);
addr_policy_result_t r;
r = compare_addr_to_node_policy(0, port, exitnode);
ok = r != ADDR_POLICY_REJECTED && r != ADDR_POLICY_PROBABLY_REJECTED;
}
if (ok) {
@@ -563,7 +564,7 @@ circuit_predict_and_launch_new(void)
log_info(LD_CIRC,
"Have %d clean circs (%d internal), need another exit circ.",
num, num_internal);
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, flags);
circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags);
return;
}
@@ -575,7 +576,7 @@ circuit_predict_and_launch_new(void)
"Have %d clean circs (%d internal), need another internal "
"circ for my hidden service.",
num, num_internal);
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, flags);
circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags);
return;
}
@@ -593,7 +594,7 @@ circuit_predict_and_launch_new(void)
"Have %d clean circs (%d uptime-internal, %d internal), need"
" another hidden service circ.",
num, num_uptime_internal, num_internal);
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, flags);
circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags);
return;
}
@@ -606,7 +607,7 @@ circuit_predict_and_launch_new(void)
flags = CIRCLAUNCH_NEED_CAPACITY;
log_info(LD_CIRC,
"Have %d clean circs need another buildtime test circ.", num);
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, flags);
circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, flags);
return;
}
}
@@ -644,7 +645,7 @@ circuit_build_needed_circs(time_t now)
circ &&
circ->timestamp_created + TESTING_CIRCUIT_INTERVAL < now) {
log_fn(LOG_INFO,"Creating a new testing circuit.");
circuit_launch_by_router(CIRCUIT_PURPOSE_C_GENERAL, NULL, 0);
circuit_launch(CIRCUIT_PURPOSE_C_GENERAL, 0);
}
#endif
}
@@ -1076,17 +1077,9 @@ static int did_circs_fail_last_period = 0;
/** Launch a new circuit; see circuit_launch_by_extend_info() for
* details on arguments. */
origin_circuit_t *
circuit_launch_by_router(uint8_t purpose,
routerinfo_t *exit, int flags)
circuit_launch(uint8_t purpose, int flags)
{
origin_circuit_t *circ;
extend_info_t *info = NULL;
if (exit)
info = extend_info_from_router(exit);
circ = circuit_launch_by_extend_info(purpose, info, flags);
extend_info_free(info);
return circ;
return circuit_launch_by_extend_info(purpose, NULL, flags);
}
/** Launch a new circuit with purpose <b>purpose</b> and exit node
@@ -1256,9 +1249,9 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
uint32_t addr = 0;
if (tor_inet_aton(conn->socks_request->address, &in))
addr = ntohl(in.s_addr);
if (router_exit_policy_all_routers_reject(addr,
conn->socks_request->port,
need_uptime)) {
if (router_exit_policy_all_nodes_reject(addr,
conn->socks_request->port,
need_uptime)) {
log_notice(LD_APP,
"No Tor server allows exit to %s:%d. Rejecting.",
safe_str_client(conn->socks_request->address),
@@ -1267,9 +1260,9 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
}
} else {
/* XXXX022 Duplicates checks in connection_ap_handshake_attach_circuit */
routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1);
const node_t *node = node_get_by_nickname(conn->chosen_exit_name, 1);
int opt = conn->chosen_exit_optional;
if (router && !connection_ap_can_use_exit(conn, router, 0)) {
if (node && !connection_ap_can_use_exit(conn, node, 0)) {
log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
"Requested exit point '%s' would refuse request. %s.",
conn->chosen_exit_name, opt ? "Trying others" : "Closing");
@@ -1317,11 +1310,11 @@ circuit_get_open_circ_or_launch(edge_connection_t *conn,
*/
if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_GENERAL) {
if (conn->chosen_exit_name) {
routerinfo_t *r;
const node_t *r;
int opt = conn->chosen_exit_optional;
r = router_get_by_nickname(conn->chosen_exit_name, 1);
if (r) {
extend_info = extend_info_from_router(r);
r = node_get_by_nickname(conn->chosen_exit_name, 1);
if (r && node_has_descriptor(r)) {
extend_info = extend_info_from_node(r);
} else {
log_debug(LD_DIR, "considering %d, %s",
want_onehop, conn->chosen_exit_name);
@@ -1571,9 +1564,9 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
origin_circuit_t *circ=NULL;
if (conn->chosen_exit_name) {
routerinfo_t *router = router_get_by_nickname(conn->chosen_exit_name, 1);
const node_t *node = node_get_by_nickname(conn->chosen_exit_name, 1);
int opt = conn->chosen_exit_optional;
if (!router && !want_onehop) {
if (!node && !want_onehop) {
/* We ran into this warning when trying to extend a circuit to a
* hidden service directory for which we didn't have a router
* descriptor. See flyspray task 767 for more details. We should
@@ -1589,7 +1582,7 @@ connection_ap_handshake_attach_circuit(edge_connection_t *conn)
}
return -1;
}
if (router && !connection_ap_can_use_exit(conn, router, 0)) {
if (node && !connection_ap_can_use_exit(conn, node, 0)) {
log_fn(opt ? LOG_INFO : LOG_WARN, LD_APP,
"Requested exit point '%s' would refuse request. %s.",
conn->chosen_exit_name, opt ? "Trying others" : "Closing");
+1 -2
View File
@@ -41,8 +41,7 @@ void circuit_build_failed(origin_circuit_t *circ);
origin_circuit_t *circuit_launch_by_extend_info(uint8_t purpose,
extend_info_t *info,
int flags);
origin_circuit_t *circuit_launch_by_router(uint8_t purpose,
routerinfo_t *exit, int flags);
origin_circuit_t *circuit_launch(uint8_t purpose, int flags);
void circuit_reset_failure_count(int timeout);
int connection_ap_handshake_attach_chosen_circuit(edge_connection_t *conn,
origin_circuit_t *circ,
+7 -3
View File
@@ -25,6 +25,7 @@
#include "control.h"
#include "cpuworker.h"
#include "hibernate.h"
#include "nodelist.h"
#include "onion.h"
#include "relay.h"
#include "router.h"
@@ -267,15 +268,18 @@ command_process_create_cell(cell_t *cell, or_connection_t *conn)
}
if (circuit_id_in_use_on_orconn(cell->circ_id, conn)) {
routerinfo_t *router = router_get_by_digest(conn->identity_digest);
const node_t *node = node_get_by_id(conn->identity_digest);
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Received CREATE cell (circID %d) for known circ. "
"Dropping (age %d).",
cell->circ_id, (int)(time(NULL) - conn->_base.timestamp_created));
if (router)
if (node) {
char *p = esc_for_log(node_get_platform(node));
log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
"Details: nickname \"%s\", platform %s.",
router->nickname, escaped(router->platform));
node_get_nickname(node), p);
tor_free(p);
}
return;
}
+22 -1
View File
@@ -691,6 +691,11 @@ or_options_free(or_options_t *options)
return;
routerset_free(options->_ExcludeExitNodesUnion);
if (options->NodeFamilySets) {
SMARTLIST_FOREACH(options->NodeFamilySets, routerset_t *,
rs, routerset_free(rs));
smartlist_free(options->NodeFamilySets);
}
config_free(&options_format, options);
}
@@ -3084,6 +3089,18 @@ options_validate(or_options_t *old_options, or_options_t *options,
routerset_union(options->_ExcludeExitNodesUnion,options->ExcludeNodes);
}
if (options->NodeFamilies) {
options->NodeFamilySets = smartlist_create();
for (cl = options->NodeFamilies; cl; cl = cl->next) {
routerset_t *rs = routerset_new();
if (routerset_parse(rs, cl->value, cl->key) == 0) {
smartlist_add(options->NodeFamilySets, rs);
} else {
routerset_free(rs);
}
}
}
if (options->ExcludeNodes && options->StrictNodes) {
COMPLAIN("You have asked to exclude certain relays from all positions "
"in your circuits. Expect hidden services and other Tor "
@@ -3549,8 +3566,12 @@ options_validate(or_options_t *old_options, or_options_t *options,
if (check_nickname_list(options->MyFamily, "MyFamily", msg))
return -1;
for (cl = options->NodeFamilies; cl; cl = cl->next) {
if (check_nickname_list(cl->value, "NodeFamily", msg))
routerset_t *rs = routerset_new();
if (routerset_parse(rs, cl->value, cl->key)) {
routerset_free(rs);
return -1;
}
routerset_free(rs);
}
if (validate_addr_policies(options, msg) < 0)
+18 -18
View File
@@ -23,6 +23,7 @@
#include "dirserv.h"
#include "hibernate.h"
#include "main.h"
#include "nodelist.h"
#include "policies.h"
#include "reasons.h"
#include "relay.h"
@@ -586,7 +587,7 @@ void
circuit_discard_optional_exit_enclaves(extend_info_t *info)
{
edge_connection_t *edge_conn;
routerinfo_t *r1, *r2;
const node_t *r1, *r2;
smartlist_t *conns = get_connection_array();
SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) {
@@ -598,8 +599,8 @@ circuit_discard_optional_exit_enclaves(extend_info_t *info)
if (!edge_conn->chosen_exit_optional &&
!edge_conn->chosen_exit_retries)
continue;
r1 = router_get_by_nickname(edge_conn->chosen_exit_name, 0);
r2 = router_get_by_nickname(info->nickname, 0);
r1 = node_get_by_nickname(edge_conn->chosen_exit_name, 0);
r2 = node_get_by_nickname(info->nickname, 0);
if (!r1 || !r2 || r1 != r2)
continue;
tor_assert(edge_conn->socks_request);
@@ -1574,12 +1575,12 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
return -1;
}
} else {
routerinfo_t *r;
const node_t *r;
conn->chosen_exit_name = tor_strdup(socks->address);
r = router_get_by_nickname(conn->chosen_exit_name, 1);
r = node_get_by_nickname(conn->chosen_exit_name, 1);
*socks->address = 0;
if (r) {
strlcpy(socks->address, r->address, sizeof(socks->address));
node_get_address_string(r, socks->address, sizeof(socks->address));
} else {
log_warn(LD_APP,
"Unrecognized server in exit address '%s.exit'. Refusing.",
@@ -1630,16 +1631,16 @@ connection_ap_handshake_rewrite_and_attach(edge_connection_t *conn,
if (!conn->use_begindir && !conn->chosen_exit_name && !circ) {
/* see if we can find a suitable enclave exit */
routerinfo_t *r =
const node_t *r =
router_find_exact_exit_enclave(socks->address, socks->port);
if (r) {
log_info(LD_APP,
"Redirecting address %s to exit at enclave router %s",
safe_str_client(socks->address), r->nickname);
safe_str_client(socks->address), node_get_nickname(r));
/* use the hex digest, not nickname, in case there are two
routers with this nickname */
conn->chosen_exit_name =
tor_strdup(hex_str(r->cache_info.identity_digest, DIGEST_LEN));
tor_strdup(hex_str(r->identity, DIGEST_LEN));
conn->chosen_exit_optional = 1;
}
}
@@ -2895,7 +2896,7 @@ connection_edge_is_rendezvous_stream(edge_connection_t *conn)
* this relay, return 0.
*/
int
connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
connection_ap_can_use_exit(edge_connection_t *conn, const node_t *exit,
int excluded_means_no)
{
or_options_t *options = get_options();
@@ -2909,10 +2910,10 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
* make sure the exit node of the existing circuit matches exactly.
*/
if (conn->chosen_exit_name) {
routerinfo_t *chosen_exit =
router_get_by_nickname(conn->chosen_exit_name, 1);
if (!chosen_exit || memcmp(chosen_exit->cache_info.identity_digest,
exit->cache_info.identity_digest, DIGEST_LEN)) {
const node_t *chosen_exit =
node_get_by_nickname(conn->chosen_exit_name, 1);
if (!chosen_exit || memcmp(chosen_exit->identity,
exit->identity, DIGEST_LEN)) {
/* doesn't match */
// log_debug(LD_APP,"Requested node '%s', considering node '%s'. No.",
// conn->chosen_exit_name, exit->nickname);
@@ -2927,8 +2928,7 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
addr_policy_result_t r;
if (tor_inet_aton(conn->socks_request->address, &in))
addr = ntohl(in.s_addr);
r = compare_addr_to_addr_policy(addr, conn->socks_request->port,
exit->exit_policy);
r = compare_addr_to_node_policy(addr, conn->socks_request->port, exit);
if (r == ADDR_POLICY_REJECTED)
return 0; /* We know the address, and the exit policy rejects it. */
if (r == ADDR_POLICY_PROBABLY_REJECTED && !conn->chosen_exit_name)
@@ -2937,12 +2937,12 @@ connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
* this node, err on the side of caution. */
} else if (SOCKS_COMMAND_IS_RESOLVE(conn->socks_request->command)) {
/* Don't send DNS requests to non-exit servers by default. */
if (!conn->chosen_exit_name && policy_is_reject_star(exit->exit_policy))
if (!conn->chosen_exit_name && node_exit_policy_rejects_all(exit))
return 0;
}
if (options->_ExcludeExitNodesUnion &&
(options->StrictNodes || excluded_means_no) &&
routerset_contains_router(options->_ExcludeExitNodesUnion, exit)) {
routerset_contains_node(options->_ExcludeExitNodesUnion, exit)) {
/* If we are trying to avoid this node as exit, and we have StrictNodes
* set, then this is not a suitable exit. Refuse it.
*
+2 -1
View File
@@ -47,7 +47,8 @@ int connection_exit_begin_conn(cell_t *cell, circuit_t *circ);
int connection_exit_begin_resolve(cell_t *cell, or_circuit_t *circ);
void connection_exit_connect(edge_connection_t *conn);
int connection_edge_is_rendezvous_stream(edge_connection_t *conn);
int connection_ap_can_use_exit(edge_connection_t *conn, routerinfo_t *exit,
int connection_ap_can_use_exit(edge_connection_t *conn,
const node_t *exit,
int excluded_means_no);
void connection_ap_expire_beginning(void);
void connection_ap_attach_pending(void);
+10 -7
View File
@@ -22,6 +22,7 @@
#include "geoip.h"
#include "main.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "reasons.h"
#include "relay.h"
#include "rephist.h"
@@ -446,7 +447,7 @@ connection_or_init_conn_from_address(or_connection_t *conn,
const char *id_digest,
int started_here)
{
routerinfo_t *r = router_get_by_digest(id_digest);
const node_t *r = node_get_by_id(id_digest);
connection_or_set_identity_digest(conn, id_digest);
connection_or_update_token_buckets_helper(conn, 1, get_options());
@@ -454,8 +455,10 @@ connection_or_init_conn_from_address(or_connection_t *conn,
tor_addr_copy(&conn->_base.addr, addr);
tor_addr_copy(&conn->real_addr, addr);
if (r) {
tor_addr_t node_addr;
node_get_addr(r, &node_addr);
/* XXXX proposal 118 will make this more complex. */
if (tor_addr_eq_ipv4h(&conn->_base.addr, r->addr))
if (tor_addr_eq(&conn->_base.addr, &node_addr))
conn->is_canonical = 1;
if (!started_here) {
/* Override the addr/port, so our log messages will make sense.
@@ -468,12 +471,12 @@ connection_or_init_conn_from_address(or_connection_t *conn,
* right IP address and port 56244, that wouldn't be as helpful. now we
* log the "right" port too, so we know if it's moria1 or moria2.
*/
tor_addr_from_ipv4h(&conn->_base.addr, r->addr);
conn->_base.port = r->or_port;
tor_addr_copy(&conn->_base.addr, &node_addr);
conn->_base.port = node_get_orport(r);
}
conn->nickname = tor_strdup(r->nickname);
conn->nickname = tor_strdup(node_get_nickname(r));
tor_free(conn->_base.address);
conn->_base.address = tor_strdup(r->address);
conn->_base.address = tor_dup_addr(&node_addr);
} else {
const char *n;
/* If we're an authoritative directory server, we may know a
@@ -1527,7 +1530,7 @@ connection_or_send_netinfo(or_connection_t *conn)
{
cell_t cell;
time_t now = time(NULL);
routerinfo_t *me;
const routerinfo_t *me;
int len;
char *out;
+41 -33
View File
@@ -26,6 +26,7 @@
#include "hibernate.h"
#include "main.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "reasons.h"
#include "router.h"
@@ -1344,7 +1345,7 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
} else if (!strcmp(question, "dir-usage")) {
*answer = directory_dump_request_log();
} else if (!strcmp(question, "fingerprint")) {
routerinfo_t *me = router_get_my_routerinfo();
const routerinfo_t *me = router_get_my_routerinfo();
if (!me) {
*errmsg = "No routerdesc known; am I really a server?";
return -1;
@@ -1366,8 +1367,9 @@ getinfo_helper_misc(control_connection_t *conn, const char *question,
* NOTE: <b>ri_body</b> is as returned by signed_descriptor_get_body: it might
* not be NUL-terminated. */
static char *
munge_extrainfo_into_routerinfo(const char *ri_body, signed_descriptor_t *ri,
signed_descriptor_t *ei)
munge_extrainfo_into_routerinfo(const char *ri_body,
const signed_descriptor_t *ri,
const signed_descriptor_t *ei)
{
char *out = NULL, *outp;
int i;
@@ -1412,16 +1414,17 @@ getinfo_helper_dir(control_connection_t *control_conn,
const char *question, char **answer,
const char **errmsg)
{
const routerinfo_t *ri;
(void) control_conn;
if (!strcmpstart(question, "desc/id/")) {
routerinfo_t *ri = router_get_by_hexdigest(question+strlen("desc/id/"));
ri = router_get_by_hexdigest(question+strlen("desc/id/"));
if (ri) {
const char *body = signed_descriptor_get_body(&ri->cache_info);
if (body)
*answer = tor_strndup(body, ri->cache_info.signed_descriptor_len);
}
} else if (!strcmpstart(question, "desc/name/")) {
routerinfo_t *ri = router_get_by_nickname(question+strlen("desc/name/"),1);
ri = router_get_by_nickname(question+strlen("desc/name/"),1);
if (ri) {
const char *body = signed_descriptor_get_body(&ri->cache_info);
if (body)
@@ -1431,7 +1434,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
routerlist_t *routerlist = router_get_routerlist();
smartlist_t *sl = smartlist_create();
if (routerlist && routerlist->routers) {
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
SMARTLIST_FOREACH(routerlist->routers, const routerinfo_t *, ri,
{
const char *body = signed_descriptor_get_body(&ri->cache_info);
if (body)
@@ -1447,7 +1450,7 @@ getinfo_helper_dir(control_connection_t *control_conn,
routerlist_t *routerlist = router_get_routerlist();
smartlist_t *sl = smartlist_create();
if (routerlist && routerlist->routers) {
SMARTLIST_FOREACH(routerlist->routers, routerinfo_t *, ri,
SMARTLIST_FOREACH(routerlist->routers, const routerinfo_t *, ri,
{
const char *body = signed_descriptor_get_body(&ri->cache_info);
signed_descriptor_t *ei = extrainfo_get_by_descriptor_digest(
@@ -1465,8 +1468,8 @@ getinfo_helper_dir(control_connection_t *control_conn,
SMARTLIST_FOREACH(sl, char *, c, tor_free(c));
smartlist_free(sl);
} else if (!strcmpstart(question, "desc-annotations/id/")) {
routerinfo_t *ri = router_get_by_hexdigest(question+
strlen("desc-annotations/id/"));
ri = router_get_by_hexdigest(question+
strlen("desc-annotations/id/"));
if (ri) {
const char *annotations =
signed_descriptor_get_annotations(&ri->cache_info);
@@ -2105,7 +2108,7 @@ static int
handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
const char *body)
{
smartlist_t *router_nicknames=NULL, *routers=NULL;
smartlist_t *router_nicknames=NULL, *nodes=NULL;
origin_circuit_t *circ = NULL;
int zero_circ;
uint8_t intended_purpose = CIRCUIT_PURPOSE_C_GENERAL;
@@ -2136,8 +2139,7 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
if ((smartlist_len(args) == 1) ||
(smartlist_len(args) >= 2 && is_keyval_pair(smartlist_get(args, 1)))) {
// "EXTENDCIRCUIT 0" || EXTENDCIRCUIT 0 foo=bar"
circ = circuit_launch_by_router(intended_purpose, NULL,
CIRCLAUNCH_NEED_CAPACITY);
circ = circuit_launch(intended_purpose, CIRCLAUNCH_NEED_CAPACITY);
if (!circ) {
connection_write_str_to_buf("551 Couldn't start circuit\r\n", conn);
} else {
@@ -2165,17 +2167,21 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
SMARTLIST_FOREACH(args, char *, cp, tor_free(cp));
smartlist_free(args);
routers = smartlist_create();
nodes = smartlist_create();
SMARTLIST_FOREACH(router_nicknames, const char *, n,
{
routerinfo_t *r = router_get_by_nickname(n, 1);
if (!r) {
const node_t *node = node_get_by_nickname(n, 1);
if (!node) {
connection_printf_to_buf(conn, "552 No such router \"%s\"\r\n", n);
goto done;
}
smartlist_add(routers, r);
if (!node_has_descriptor(node)) {
connection_printf_to_buf(conn, "552 descriptor for \"%s\"\r\n", n);
goto done;
}
smartlist_add(nodes, (void*)node);
});
if (!smartlist_len(routers)) {
if (!smartlist_len(nodes)) {
connection_write_str_to_buf("512 No router names provided\r\n", conn);
goto done;
}
@@ -2186,9 +2192,10 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
}
/* now circ refers to something that is ready to be extended */
SMARTLIST_FOREACH(routers, routerinfo_t *, r,
SMARTLIST_FOREACH(nodes, const node_t *, node,
{
extend_info_t *info = extend_info_from_router(r);
extend_info_t *info = extend_info_from_node(node);
tor_assert(info); /* True, since node_has_descriptor(node) == true */
circuit_append_new_exit(circ, info);
extend_info_free(info);
});
@@ -2222,7 +2229,7 @@ handle_control_extendcircuit(control_connection_t *conn, uint32_t len,
done:
SMARTLIST_FOREACH(router_nicknames, char *, n, tor_free(n));
smartlist_free(router_nicknames);
smartlist_free(routers);
smartlist_free(nodes);
return 0;
}
@@ -2338,16 +2345,17 @@ handle_control_attachstream(control_connection_t *conn, uint32_t len,
}
/* Is this a single hop circuit? */
if (circ && (circuit_get_cpath_len(circ)<2 || hop==1)) {
routerinfo_t *r = NULL;
char* exit_digest;
const node_t *node = NULL;
char *exit_digest;
if (circ->build_state &&
circ->build_state->chosen_exit &&
!tor_digest_is_zero(circ->build_state->chosen_exit->identity_digest)) {
exit_digest = circ->build_state->chosen_exit->identity_digest;
r = router_get_by_digest(exit_digest);
node = node_get_by_id(exit_digest);
}
/* Do both the client and relay allow one-hop exit circuits? */
if (!r || !r->allow_single_hop_exits ||
if (!node ||
!node_allows_single_hop_exits(node) ||
!get_options()->AllowSingleHopCircuits) {
connection_write_str_to_buf(
"551 Can't attach stream to this one-hop circuit.\r\n", conn);
@@ -3173,10 +3181,10 @@ control_event_stream_status(edge_connection_t *conn, stream_status_event_t tp,
static void
orconn_target_get_name(char *name, size_t len, or_connection_t *conn)
{
routerinfo_t *ri = router_get_by_digest(conn->identity_digest);
if (ri) {
const node_t *node = node_get_by_id(conn->identity_digest);
if (node) {
tor_assert(len > MAX_VERBOSE_NICKNAME_LEN);
router_get_verbose_nickname(name, ri);
node_get_verbose_nickname(node, name);
} else if (! tor_digest_is_zero(conn->identity_digest)) {
name[0] = '$';
base16_encode(name+1, len-1, conn->identity_digest,
@@ -3493,7 +3501,7 @@ control_event_networkstatus_changed_helper(smartlist_t *statuses,
smartlist_add(strs, tor_strdup("650+"));
smartlist_add(strs, tor_strdup(event_string));
smartlist_add(strs, tor_strdup("\r\n"));
SMARTLIST_FOREACH(statuses, routerstatus_t *, rs,
SMARTLIST_FOREACH(statuses, const routerstatus_t *, rs,
{
s = networkstatus_getinfo_helper_single(rs);
if (!s) continue;
@@ -3584,7 +3592,7 @@ control_event_buildtimeout_set(const circuit_build_times_t *cbt,
/** Called when a single local_routerstatus_t has changed: Sends an NS event
* to any controller that cares. */
int
control_event_networkstatus_changed_single(routerstatus_t *rs)
control_event_networkstatus_changed_single(const routerstatus_t *rs)
{
smartlist_t *statuses;
int r;
@@ -3593,7 +3601,7 @@ control_event_networkstatus_changed_single(routerstatus_t *rs)
return 0;
statuses = smartlist_create();
smartlist_add(statuses, rs);
smartlist_add(statuses, (void*)rs);
r = control_event_networkstatus_changed(statuses);
smartlist_free(statuses);
return r;
@@ -3718,9 +3726,9 @@ control_event_guard(const char *nickname, const char *digest,
{
char buf[MAX_VERBOSE_NICKNAME_LEN+1];
routerinfo_t *ri = router_get_by_digest(digest);
if (ri) {
router_get_verbose_nickname(buf, ri);
const node_t *node = node_get_by_id(digest);
if (node) {
node_get_verbose_nickname(node, buf);
} else {
tor_snprintf(buf, sizeof(buf), "$%s~%s", hbuf, nickname);
}
+1 -1
View File
@@ -53,7 +53,7 @@ int control_event_my_descriptor_changed(void);
int control_event_networkstatus_changed(smartlist_t *statuses);
int control_event_newconsensus(const networkstatus_t *consensus);
int control_event_networkstatus_changed_single(routerstatus_t *rs);
int control_event_networkstatus_changed_single(const routerstatus_t *rs);
int control_event_general_status(int severity, const char *format, ...)
CHECK_PRINTF(2,3);
int control_event_client_status(int severity, const char *format, ...)
+27 -20
View File
@@ -17,6 +17,7 @@
#include "main.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "rendclient.h"
#include "rendcommon.h"
@@ -219,17 +220,19 @@ dir_conn_purpose_to_string(int purpose)
int
router_supports_extrainfo(const char *identity_digest, int is_authority)
{
routerinfo_t *ri = router_get_by_digest(identity_digest);
const node_t *node = node_get_by_id(identity_digest);
if (ri) {
if (ri->caches_extra_info)
if (node && node->ri) {
if (node->ri->caches_extra_info)
return 1;
if (is_authority && ri->platform &&
tor_version_as_new_as(ri->platform, "Tor 0.2.0.0-alpha-dev (r10070)"))
if (is_authority && node->ri->platform &&
tor_version_as_new_as(node->ri->platform,
"Tor 0.2.0.0-alpha-dev (r10070)"))
return 1;
}
if (is_authority) {
routerstatus_t *rs = router_get_consensus_status_by_id(identity_digest);
const routerstatus_t *rs =
router_get_consensus_status_by_id(identity_digest);
if (rs && rs->version_supports_extrainfo_upload)
return 1;
}
@@ -328,7 +331,7 @@ void
directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
const char *resource, int pds_flags)
{
routerstatus_t *rs = NULL;
const routerstatus_t *rs = NULL;
or_options_t *options = get_options();
int prefer_authority = directory_fetches_from_authorities(options);
int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose);
@@ -400,10 +403,12 @@ directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
* possible directory question. This won't be true forever. -RD */
/* It certainly is not true with conditional consensus downloading,
* so, for now, never assume the server supports that. */
routerinfo_t *ri = choose_random_entry(NULL);
if (ri) {
const node_t *node = choose_random_entry(NULL);
if (node && node->ri) {
/* every bridge has a routerinfo. */
tor_addr_t addr;
tor_addr_from_ipv4h(&addr, ri->addr);
routerinfo_t *ri = node->ri;
node_get_addr(node, &addr);
directory_initiate_command(ri->address, &addr,
ri->or_port, 0,
0, /* don't use conditional consensus url */
@@ -512,7 +517,7 @@ directory_get_from_all_authorities(uint8_t dir_purpose,
/** Same as directory_initiate_command_routerstatus(), but accepts
* rendezvous data to fetch a hidden service descriptor. */
void
directory_initiate_command_routerstatus_rend(routerstatus_t *status,
directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
uint8_t dir_purpose,
uint8_t router_purpose,
int anonymized_connection,
@@ -522,18 +527,19 @@ directory_initiate_command_routerstatus_rend(routerstatus_t *status,
time_t if_modified_since,
const rend_data_t *rend_query)
{
routerinfo_t *router;
const node_t *node;
char address_buf[INET_NTOA_BUF_LEN+1];
struct in_addr in;
const char *address;
tor_addr_t addr;
router = router_get_by_digest(status->identity_digest);
if (!router && anonymized_connection) {
node = node_get_by_id(status->identity_digest);
if (!node && anonymized_connection) {
log_info(LD_DIR, "Not sending anonymized request to directory '%s'; we "
"don't have its router descriptor.", status->nickname);
return;
} else if (router) {
address = router->address;
} else if (node) {
node_get_address_string(node, address_buf, sizeof(address_buf));
address = address_buf;
} else {
in.s_addr = htonl(status->addr);
tor_inet_ntoa(&in, address_buf, sizeof(address_buf));
@@ -566,7 +572,7 @@ directory_initiate_command_routerstatus_rend(routerstatus_t *status,
* want to fetch.
*/
void
directory_initiate_command_routerstatus(routerstatus_t *status,
directory_initiate_command_routerstatus(const routerstatus_t *status,
uint8_t dir_purpose,
uint8_t router_purpose,
int anonymized_connection,
@@ -590,7 +596,7 @@ directory_conn_is_self_reachability_test(dir_connection_t *conn)
{
if (conn->requested_resource &&
!strcmpstart(conn->requested_resource,"authority")) {
routerinfo_t *me = router_get_my_routerinfo();
const routerinfo_t *me = router_get_my_routerinfo();
if (me &&
router_digest_is_me(conn->identity_digest) &&
tor_addr_eq_ipv4h(&conn->_base.addr, me->addr) && /*XXXX prop 118*/
@@ -1597,7 +1603,8 @@ connection_dir_client_reached_eof(dir_connection_t *conn)
"'%s:%d'. I'll try again soon.",
status_code, escaped(reason), conn->_base.address,
conn->_base.port);
if ((rs = router_get_consensus_status_by_id(conn->identity_digest)))
rs = router_get_mutable_consensus_status_by_id(conn->identity_digest);
if (rs)
rs->last_dir_503_at = now;
if ((ds = router_get_trusteddirserver_by_digest(conn->identity_digest)))
ds->fake_status.last_dir_503_at = now;
@@ -3692,7 +3699,7 @@ dir_microdesc_download_failed(smartlist_t *failed,
if (! consensus)
return;
SMARTLIST_FOREACH_BEGIN(failed, const char *, d) {
rs = router_get_consensus_status_by_descriptor_digest(consensus, d);
rs = router_get_mutable_consensus_status_by_descriptor_digest(consensus,d);
if (!rs)
continue;
dls = &rs->dl_status;
+2 -2
View File
@@ -23,7 +23,7 @@ void directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
void directory_get_from_all_authorities(uint8_t dir_purpose,
uint8_t router_purpose,
const char *resource);
void directory_initiate_command_routerstatus(routerstatus_t *status,
void directory_initiate_command_routerstatus(const routerstatus_t *status,
uint8_t dir_purpose,
uint8_t router_purpose,
int anonymized_connection,
@@ -31,7 +31,7 @@ void directory_initiate_command_routerstatus(routerstatus_t *status,
const char *payload,
size_t payload_len,
time_t if_modified_since);
void directory_initiate_command_routerstatus_rend(routerstatus_t *status,
void directory_initiate_command_routerstatus_rend(const routerstatus_t *status,
uint8_t dir_purpose,
uint8_t router_purpose,
int anonymized_connection,
+144 -109
View File
@@ -16,6 +16,7 @@
#include "hibernate.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "rephist.h"
#include "router.h"
@@ -65,8 +66,6 @@ static char *format_versions_list(config_line_t *ln);
struct authdir_config_t;
static int add_fingerprint_to_dir(const char *nickname, const char *fp,
struct authdir_config_t *list);
static uint32_t dirserv_router_get_status(const routerinfo_t *router,
const char **msg);
static uint32_t
dirserv_get_status_impl(const char *fp, const char *nickname,
const char *address,
@@ -74,7 +73,8 @@ dirserv_get_status_impl(const char *fp, const char *nickname,
const char *platform, const char *contact,
const char **msg, int should_log);
static void clear_cached_dir(cached_dir_t *d);
static signed_descriptor_t *get_signed_descriptor_by_fp(const char *fp,
static const signed_descriptor_t *get_signed_descriptor_by_fp(
const char *fp,
int extrainfo,
time_t publish_cutoff);
static int dirserv_add_extrainfo(extrainfo_t *ei, const char **msg);
@@ -303,7 +303,7 @@ dirserv_load_fingerprint_file(void)
*
* If the status is 'FP_REJECT' and <b>msg</b> is provided, set
* *<b>msg</b> to an explanation of why. */
static uint32_t
uint32_t
dirserv_router_get_status(const routerinfo_t *router, const char **msg)
{
char d[DIGEST_LEN];
@@ -325,7 +325,7 @@ dirserv_router_get_status(const routerinfo_t *router, const char **msg)
/** Return true if there is no point in downloading the router described by
* <b>rs</b> because this directory would reject it. */
int
dirserv_would_reject_router(routerstatus_t *rs)
dirserv_would_reject_router(const routerstatus_t *rs)
{
uint32_t res;
@@ -360,7 +360,7 @@ dirserv_get_name_status(const char *id_digest, const char *nickname)
return 0;
}
/** Helper: As dirserv_get_router_status, but takes the router fingerprint
/** Helper: As dirserv_router_get_status, but takes the router fingerprint
* (hex, no spaces), nickname, address (used for logging only), IP address, OR
* port, platform (logging only) and contact info (logging only) as arguments.
*
@@ -375,7 +375,7 @@ dirserv_get_status_impl(const char *id_digest, const char *nickname,
const char **msg, int should_log)
{
int reject_unlisted = get_options()->AuthDirRejectUnlisted;
uint32_t result = 0;
uint32_t result;
router_status_t *status_by_digest;
if (!fingerprint_list)
@@ -533,7 +533,7 @@ dirserv_router_has_valid_address(routerinfo_t *ri)
*/
int
authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
int complain)
int complain, int *valid_out)
{
/* Okay. Now check whether the fingerprint is recognized. */
uint32_t status = dirserv_router_get_status(ri, msg);
@@ -574,15 +574,24 @@ authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
*msg = "Rejected: Address is not an IP, or IP is a private address.";
return -1;
}
/* Okay, looks like we're willing to accept this one. */
ri->is_named = (status & FP_NAMED) ? 1 : 0;
ri->is_valid = (status & FP_INVALID) ? 0 : 1;
ri->is_bad_directory = (status & FP_BADDIR) ? 1 : 0;
ri->is_bad_exit = (status & FP_BADEXIT) ? 1 : 0;
*valid_out = ! (status & FP_INVALID);
return 0;
}
/** Update the relevant flags of <b>node</b> based on our opinion as a
* directory authority in <b>authstatus</b>, as returned by
* dirserv_router_get_status or equivalent. */
void
dirserv_set_node_flags_from_authoritative_status(node_t *node,
uint32_t authstatus)
{
node->is_valid = (authstatus & FP_INVALID) ? 0 : 1;
node->is_bad_directory = (authstatus & FP_BADDIR) ? 1 : 0;
node->is_bad_exit = (authstatus & FP_BADEXIT) ? 1 : 0;
}
/** True iff <b>a</b> is more severe than <b>b</b>. */
static int
WRA_MORE_SEVERE(was_router_added_t a, was_router_added_t b)
@@ -707,7 +716,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
* from this server. (We do this here and not in router_add_to_routerlist
* because we want to be able to accept the newest router descriptor that
* another authority has, so we all converge on the same one.) */
ri_old = router_get_by_digest(ri->cache_info.identity_digest);
ri_old = router_get_mutable_by_digest(ri->cache_info.identity_digest);
if (ri_old && ri_old->cache_info.published_on < ri->cache_info.published_on
&& router_differences_are_cosmetic(ri_old, ri)
&& !router_is_me(ri)) {
@@ -751,8 +760,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
routerlist_descriptors_added(changed, 0);
smartlist_free(changed);
if (!*msg) {
*msg = ri->is_valid ? "Descriptor for valid server accepted" :
"Descriptor for invalid server accepted";
*msg = "Descriptor accepted";
}
log_info(LD_DIRSERV,
"Added descriptor from '%s' (source: %s): %s.",
@@ -767,7 +775,7 @@ dirserv_add_descriptor(routerinfo_t *ri, const char **msg, const char *source)
static was_router_added_t
dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
{
routerinfo_t *ri;
const routerinfo_t *ri;
int r;
tor_assert(msg);
*msg = NULL;
@@ -807,50 +815,60 @@ dirserv_add_extrainfo(extrainfo_t *ei, const char **msg)
static void
directory_remove_invalid(void)
{
int i;
int changed = 0;
routerlist_t *rl = router_get_routerlist();
smartlist_t *nodes = smartlist_create();
smartlist_add_all(nodes, nodelist_get_list());
routerlist_assert_ok(rl);
for (i = 0; i < smartlist_len(rl->routers); ++i) {
SMARTLIST_FOREACH_BEGIN(nodes, node_t *, node) {
const char *msg;
routerinfo_t *ent = smartlist_get(rl->routers, i);
uint32_t r = dirserv_router_get_status(ent, &msg);
routerinfo_t *ent = node->ri;
uint32_t r;
if (!ent)
continue;
r = dirserv_router_get_status(ent, &msg);
if (r & FP_REJECT) {
log_info(LD_DIRSERV, "Router '%s' is now rejected: %s",
ent->nickname, msg?msg:"");
routerlist_remove(rl, ent, 0, time(NULL));
i--;
changed = 1;
continue;
}
if (bool_neq((r & FP_NAMED), ent->is_named)) {
#if 0
if (bool_neq((r & FP_NAMED), ent->auth_says_is_named)) {
log_info(LD_DIRSERV,
"Router '%s' is now %snamed.", ent->nickname,
(r&FP_NAMED)?"":"un");
ent->is_named = (r&FP_NAMED)?1:0;
changed = 1;
}
if (bool_neq((r & FP_INVALID), !ent->is_valid)) {
if (bool_neq((r & FP_UNNAMED), ent->auth_says_is_unnamed)) {
log_info(LD_DIRSERV,
"Router '%s' is now %snamed. (FP_UNNAMED)", ent->nickname,
(r&FP_NAMED)?"":"un");
ent->is_named = (r&FP_NUNAMED)?0:1;
changed = 1;
}
#endif
if (bool_neq((r & FP_INVALID), !node->is_valid)) {
log_info(LD_DIRSERV, "Router '%s' is now %svalid.", ent->nickname,
(r&FP_INVALID) ? "in" : "");
ent->is_valid = (r&FP_INVALID)?0:1;
node->is_valid = (r&FP_INVALID)?0:1;
changed = 1;
}
if (bool_neq((r & FP_BADDIR), ent->is_bad_directory)) {
if (bool_neq((r & FP_BADDIR), node->is_bad_directory)) {
log_info(LD_DIRSERV, "Router '%s' is now a %s directory", ent->nickname,
(r & FP_BADDIR) ? "bad" : "good");
ent->is_bad_directory = (r&FP_BADDIR) ? 1: 0;
node->is_bad_directory = (r&FP_BADDIR) ? 1: 0;
changed = 1;
}
if (bool_neq((r & FP_BADEXIT), ent->is_bad_exit)) {
if (bool_neq((r & FP_BADEXIT), node->is_bad_exit)) {
log_info(LD_DIRSERV, "Router '%s' is now a %s exit", ent->nickname,
(r & FP_BADEXIT) ? "bad" : "good");
ent->is_bad_exit = (r&FP_BADEXIT) ? 1: 0;
node->is_bad_exit = (r&FP_BADEXIT) ? 1: 0;
changed = 1;
}
}
} SMARTLIST_FOREACH_END(node);
if (changed)
directory_set_dirty();
@@ -893,10 +911,11 @@ directory_set_dirty(void)
* as running iff <b>is_live</b> is true.
*/
static char *
list_single_server_status(routerinfo_t *desc, int is_live)
list_single_server_status(const routerinfo_t *desc, int is_live)
{
char buf[MAX_NICKNAME_LEN+HEX_DIGEST_LEN+4]; /* !nickname=$hexdigest\0 */
char *cp;
const node_t *node;
tor_assert(desc);
@@ -904,7 +923,8 @@ list_single_server_status(routerinfo_t *desc, int is_live)
if (!is_live) {
*cp++ = '!';
}
if (desc->is_valid) {
node = node_get_by_id(desc->cache_info.identity_digest);
if (node && node->is_valid) {
strlcpy(cp, desc->nickname, sizeof(buf)-(cp-buf));
cp += strlen(cp);
*cp++ = '=';
@@ -943,6 +963,8 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
unreachable.
*/
int answer;
node_t *node = node_get_mutable_by_id(router->cache_info.identity_digest);
tor_assert(node);
if (router_is_me(router)) {
/* We always know if we are down ourselves. */
@@ -967,7 +989,7 @@ dirserv_set_router_is_running(routerinfo_t *router, time_t now)
rep_hist_note_router_unreachable(router->cache_info.identity_digest, now);
}
router->is_running = answer;
node->is_running = answer;
}
/** Based on the routerinfo_ts in <b>routers</b>, allocate the
@@ -995,6 +1017,8 @@ list_server_status_v1(smartlist_t *routers, char **router_status_out,
rs_entries = smartlist_create();
SMARTLIST_FOREACH_BEGIN(routers, routerinfo_t *, ri) {
const node_t *node = node_get_by_id(ri->cache_info.identity_digest);
tor_assert(node);
if (authdir) {
/* Update router status in routerinfo_t. */
dirserv_set_router_is_running(ri, now);
@@ -1002,12 +1026,13 @@ list_server_status_v1(smartlist_t *routers, char **router_status_out,
if (for_controller) {
char name_buf[MAX_VERBOSE_NICKNAME_LEN+2];
char *cp = name_buf;
if (!ri->is_running)
if (!node->is_running)
*cp++ = '!';
router_get_verbose_nickname(cp, ri);
smartlist_add(rs_entries, tor_strdup(name_buf));
} else if (ri->cache_info.published_on >= cutoff) {
smartlist_add(rs_entries, list_single_server_status(ri, ri->is_running));
smartlist_add(rs_entries, list_single_server_status(ri,
node->is_running));
}
} SMARTLIST_FOREACH_END(ri);
@@ -1045,12 +1070,12 @@ format_versions_list(config_line_t *ln)
* not hibernating, and not too old. Else return 0.
*/
static int
router_is_active(routerinfo_t *ri, time_t now)
router_is_active(const routerinfo_t *ri, const node_t *node, time_t now)
{
time_t cutoff = now - ROUTER_MAX_AGE_TO_PUBLISH;
if (ri->cache_info.published_on < cutoff)
return 0;
if (!ri->is_running || !ri->is_valid || ri->is_hibernating)
if (!node->is_running || !node->is_valid || ri->is_hibernating)
return 0;
return 1;
}
@@ -1151,7 +1176,7 @@ dirserv_dump_directory_to_string(char **dir_out,
int
directory_fetches_from_authorities(or_options_t *options)
{
routerinfo_t *me;
const routerinfo_t *me;
uint32_t addr;
int refuseunknown;
if (options->FetchDirInfoEarly)
@@ -1716,7 +1741,7 @@ static uint64_t total_exit_bandwidth = 0;
/** Helper: estimate the uptime of a router given its stated uptime and the
* amount of time since it last stated its stated uptime. */
static INLINE long
real_uptime(routerinfo_t *router, time_t now)
real_uptime(const routerinfo_t *router, time_t now)
{
if (now < router->cache_info.published_on)
return router->uptime;
@@ -1767,7 +1792,8 @@ dirserv_thinks_router_is_unreliable(time_t now,
* been set.
*/
static int
dirserv_thinks_router_is_hs_dir(routerinfo_t *router, time_t now)
dirserv_thinks_router_is_hs_dir(const routerinfo_t *router,
const node_t *node, time_t now)
{
long uptime = real_uptime(router, now);
@@ -1777,7 +1803,7 @@ dirserv_thinks_router_is_hs_dir(routerinfo_t *router, time_t now)
* version is too old. */
return (router->wants_to_be_hs_dir && router->dir_port &&
uptime > get_options()->MinUptimeHidServDirectoryV2 &&
router->is_running);
node->is_running);
}
/** Look through the routerlist, the Mean Time Between Failure history, and
@@ -1825,19 +1851,22 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
/* Weighted fractional uptime for each active router. */
wfus = tor_malloc(sizeof(double)*smartlist_len(rl->routers));
nodelist_assert_ok();
/* Now, fill in the arrays. */
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
if (router_is_active(ri, now)) {
SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) {
routerinfo_t *ri = node->ri;
if (ri && router_is_active(ri, node, now)) {
const char *id = ri->cache_info.identity_digest;
uint32_t bw;
ri->is_exit = (!router_exit_policy_rejects_all(ri) &&
exit_policy_is_general_exit(ri->exit_policy));
node->is_exit = (!router_exit_policy_rejects_all(ri) &&
exit_policy_is_general_exit(ri->exit_policy));
uptimes[n_active] = (uint32_t)real_uptime(ri, now);
mtbfs[n_active] = rep_hist_get_stability(id, now);
tks [n_active] = rep_hist_get_weighted_time_known(id, now);
bandwidths[n_active] = bw = router_get_advertised_bandwidth(ri);
total_bandwidth += bw;
if (ri->is_exit && !ri->is_bad_exit) {
if (node->is_exit && !node->is_bad_exit) {
total_exit_bandwidth += bw;
} else {
bandwidths_excluding_exits[n_active_nonexit] = bw;
@@ -1845,7 +1874,7 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
}
++n_active;
}
});
} SMARTLIST_FOREACH_END(node);
/* Now, compute thresholds. */
if (n_active) {
@@ -1871,15 +1900,17 @@ dirserv_compute_performance_thresholds(routerlist_t *rl)
/* Now that we have a time-known that 7/8 routers are known longer than,
* fill wfus with the wfu of every such "familiar" router. */
n_familiar = 0;
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
if (router_is_active(ri, now)) {
SMARTLIST_FOREACH_BEGIN(nodelist_get_list(), node_t *, node) {
routerinfo_t *ri = node->ri;
if (ri && router_is_active(ri, node, now)) {
const char *id = ri->cache_info.identity_digest;
long tk = rep_hist_get_weighted_time_known(id, now);
if (tk < guard_tk)
continue;
wfus[n_familiar++] = rep_hist_get_weighted_fractional_uptime(id, now);
}
});
} SMARTLIST_FOREACH_END(node);
if (n_familiar)
guard_wfu = median_double(wfus, n_familiar);
if (guard_wfu > WFU_TO_GUARANTEE_GUARD)
@@ -1950,7 +1981,7 @@ version_from_platform(const char *platform)
*/
int
routerstatus_format_entry(char *buf, size_t buf_len,
routerstatus_t *rs, const char *version,
const routerstatus_t *rs, const char *version,
routerstatus_format_type_t format)
{
int r;
@@ -2004,7 +2035,7 @@ routerstatus_format_entry(char *buf, size_t buf_len,
rs->is_possible_guard?" Guard":"",
rs->is_hs_dir?" HSDir":"",
rs->is_named?" Named":"",
rs->is_running?" Running":"",
rs->is_flagged_running?" Running":"",
rs->is_stable?" Stable":"",
rs->is_unnamed?" Unnamed":"",
rs->is_v2_dir?" V2Dir":"",
@@ -2026,7 +2057,7 @@ routerstatus_format_entry(char *buf, size_t buf_len,
}
if (format != NS_V2) {
routerinfo_t* desc = router_get_by_digest(rs->identity_digest);
const routerinfo_t* desc = router_get_by_digest(rs->identity_digest);
uint32_t bw;
if (format != NS_CONTROL_PORT) {
@@ -2122,6 +2153,8 @@ _compare_routerinfo_by_ip_and_bw(const void **a, const void **b)
routerinfo_t *first = *(routerinfo_t **)a, *second = *(routerinfo_t **)b;
int first_is_auth, second_is_auth;
uint32_t bw_first, bw_second;
const node_t *node_first, *node_second;
int first_is_running, second_is_running;
/* we return -1 if first should appear before second... that is,
* if first is a better router. */
@@ -2144,9 +2177,14 @@ _compare_routerinfo_by_ip_and_bw(const void **a, const void **b)
else if (!first_is_auth && second_is_auth)
return 1;
else if (first->is_running && !second->is_running)
node_first = node_get_by_id(first->cache_info.identity_digest);
node_second = node_get_by_id(second->cache_info.identity_digest);
first_is_running = node_first && node_first->is_running;
second_is_running = node_second && node_second->is_running;
if (first_is_running && !second_is_running)
return -1;
else if (!first->is_running && second->is_running)
else if (!first_is_running && second_is_running)
return 1;
bw_first = router_get_advertised_bandwidth(first);
@@ -2215,7 +2253,9 @@ get_possible_sybil_list(const smartlist_t *routers)
*/
void
set_routerstatus_from_routerinfo(routerstatus_t *rs,
routerinfo_t *ri, time_t now,
node_t *node,
routerinfo_t *ri,
time_t now,
int naming, int listbadexits,
int listbaddirs)
{
@@ -2227,48 +2267,46 @@ set_routerstatus_from_routerinfo(routerstatus_t *rs,
router_digest_is_trusted_dir(ri->cache_info.identity_digest);
/* Already set by compute_performance_thresholds. */
rs->is_exit = ri->is_exit;
rs->is_stable = ri->is_stable =
router_is_active(ri, now) &&
rs->is_exit = node->is_exit;
rs->is_stable = node->is_stable =
router_is_active(ri, node, now) &&
!dirserv_thinks_router_is_unreliable(now, ri, 1, 0) &&
!unstable_version;
rs->is_fast = ri->is_fast =
router_is_active(ri, now) &&
rs->is_fast = node->is_fast =
router_is_active(ri, node, now) &&
!dirserv_thinks_router_is_unreliable(now, ri, 0, 1);
rs->is_running = ri->is_running; /* computed above */
rs->is_flagged_running = node->is_running; /* computed above */
if (naming) {
uint32_t name_status = dirserv_get_name_status(
ri->cache_info.identity_digest, ri->nickname);
node->identity, ri->nickname);
rs->is_named = (naming && (name_status & FP_NAMED)) ? 1 : 0;
rs->is_unnamed = (naming && (name_status & FP_UNNAMED)) ? 1 : 0;
}
rs->is_valid = ri->is_valid;
rs->is_valid = node->is_valid;
if (rs->is_fast &&
if (node->is_fast &&
(router_get_advertised_bandwidth(ri) >= BANDWIDTH_TO_GUARANTEE_GUARD ||
router_get_advertised_bandwidth(ri) >=
MIN(guard_bandwidth_including_exits,
guard_bandwidth_excluding_exits))) {
long tk = rep_hist_get_weighted_time_known(
ri->cache_info.identity_digest, now);
double wfu = rep_hist_get_weighted_fractional_uptime(
ri->cache_info.identity_digest, now);
long tk = rep_hist_get_weighted_time_known(node->identity, now);
double wfu = rep_hist_get_weighted_fractional_uptime(node->identity, now);
rs->is_possible_guard = (wfu >= guard_wfu && tk >= guard_tk) ? 1 : 0;
} else {
rs->is_possible_guard = 0;
}
rs->is_bad_directory = listbaddirs && ri->is_bad_directory;
rs->is_bad_exit = listbadexits && ri->is_bad_exit;
ri->is_hs_dir = dirserv_thinks_router_is_hs_dir(ri, now);
rs->is_hs_dir = ri->is_hs_dir;
rs->is_bad_directory = listbaddirs && node->is_bad_directory;
rs->is_bad_exit = listbadexits && node->is_bad_exit;
node->is_hs_dir = dirserv_thinks_router_is_hs_dir(ri, node, now);
rs->is_hs_dir = node->is_hs_dir;
rs->is_v2_dir = ri->dir_port != 0;
if (!strcasecmp(ri->nickname, UNNAMED_ROUTER_NICKNAME))
rs->is_named = rs->is_unnamed = 0;
rs->published_on = ri->cache_info.published_on;
memcpy(rs->identity_digest, ri->cache_info.identity_digest, DIGEST_LEN);
memcpy(rs->identity_digest, node->identity, DIGEST_LEN);
memcpy(rs->descriptor_digest, ri->cache_info.signed_descriptor_digest,
DIGEST_LEN);
rs->addr = ri->addr;
@@ -2285,7 +2323,7 @@ static void
clear_status_flags_on_sybil(routerstatus_t *rs)
{
rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
rs->is_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
rs->is_flagged_running = rs->is_named = rs->is_valid = rs->is_v2_dir =
rs->is_hs_dir = rs->is_possible_guard = rs->is_bad_exit =
rs->is_bad_directory = 0;
/* FFFF we might want some mechanism to check later on if we
@@ -2293,18 +2331,6 @@ clear_status_flags_on_sybil(routerstatus_t *rs)
* forget to add it to this clause. */
}
/** Clear all the status flags in routerinfo <b>router</b>. We put this
* function here because it's eerily similar to
* clear_status_flags_on_sybil() above. One day we should merge them. */
void
router_clear_status_flags(routerinfo_t *router)
{
router->is_valid = router->is_running = router->is_hs_dir =
router->is_fast = router->is_stable =
router->is_possible_guard = router->is_exit =
router->is_bad_exit = router->is_bad_directory = 0;
}
/**
* Helper function to parse out a line in the measured bandwidth file
* into a measured_bw_line_t output structure. Returns -1 on failure
@@ -2552,17 +2578,20 @@ dirserv_generate_networkstatus_vote_obj(crypto_pk_env_t *private_key,
routerstatus_t *rs;
vote_routerstatus_t *vrs;
microdesc_t *md;
node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
if (!node)
continue;
vrs = tor_malloc_zero(sizeof(vote_routerstatus_t));
rs = &vrs->status;
set_routerstatus_from_routerinfo(rs, ri, now,
set_routerstatus_from_routerinfo(rs, node, ri, now,
naming, listbadexits, listbaddirs);
if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
clear_status_flags_on_sybil(rs);
if (!vote_on_reachability)
rs->is_running = 0;
rs->is_flagged_running = 0;
vrs->version = version_from_platform(ri->platform);
md = dirvote_create_microdescriptor(ri);
@@ -2795,8 +2824,12 @@ generate_v2_networkstatus_opinion(void)
if (ri->cache_info.published_on >= cutoff) {
routerstatus_t rs;
char *version = version_from_platform(ri->platform);
set_routerstatus_from_routerinfo(&rs, ri, now,
node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
if (!node) {
tor_free(version);
continue;
}
set_routerstatus_from_routerinfo(&rs, node, ri, now,
naming, listbadexits, listbaddirs);
if (digestmap_get(omit_as_sybil, ri->cache_info.identity_digest))
@@ -2879,7 +2912,7 @@ dirserv_get_networkstatus_v2_fingerprints(smartlist_t *result,
if (!strcmp(key,"authority")) {
if (authdir_mode_v2(get_options())) {
routerinfo_t *me = router_get_my_routerinfo();
const routerinfo_t *me = router_get_my_routerinfo();
if (me)
smartlist_add(result,
tor_memdup(me->cache_info.identity_digest, DIGEST_LEN));
@@ -2965,7 +2998,7 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
smartlist_add(fps_out,
tor_memdup(r->cache_info.identity_digest, DIGEST_LEN)));
} else if (!strcmp(key, "authority")) {
routerinfo_t *ri = router_get_my_routerinfo();
const routerinfo_t *ri = router_get_my_routerinfo();
if (ri)
smartlist_add(fps_out,
tor_memdup(ri->cache_info.identity_digest, DIGEST_LEN));
@@ -2985,8 +3018,8 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
if (for_unencrypted_conn) {
/* Remove anything that insists it not be sent unencrypted. */
SMARTLIST_FOREACH(fps_out, char *, cp, {
signed_descriptor_t *sd;
SMARTLIST_FOREACH_BEGIN(fps_out, char *, cp) {
const signed_descriptor_t *sd;
if (by_id)
sd = get_signed_descriptor_by_fp(cp,is_extrainfo,0);
else if (is_extrainfo)
@@ -2997,7 +3030,7 @@ dirserv_get_routerdesc_fingerprints(smartlist_t *fps_out, const char *key,
tor_free(cp);
SMARTLIST_DEL_CURRENT(fps_out, cp);
}
});
} SMARTLIST_FOREACH_END(cp);
}
if (!smartlist_len(fps_out)) {
@@ -3036,9 +3069,9 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, r,
smartlist_add(descs_out, &(r->cache_info)));
} else if (!strcmp(key, "/tor/server/authority")) {
routerinfo_t *ri = router_get_my_routerinfo();
const routerinfo_t *ri = router_get_my_routerinfo();
if (ri)
smartlist_add(descs_out, &(ri->cache_info));
smartlist_add(descs_out, (void*) &(ri->cache_info));
} else if (!strcmpstart(key, "/tor/server/d/")) {
smartlist_t *digests = smartlist_create();
key += strlen("/tor/server/d/");
@@ -3062,17 +3095,17 @@ dirserv_get_routerdescs(smartlist_t *descs_out, const char *key,
{
if (router_digest_is_me(d)) {
/* make sure desc_routerinfo exists */
routerinfo_t *ri = router_get_my_routerinfo();
const routerinfo_t *ri = router_get_my_routerinfo();
if (ri)
smartlist_add(descs_out, &(ri->cache_info));
smartlist_add(descs_out, (void*) &(ri->cache_info));
} else {
routerinfo_t *ri = router_get_by_digest(d);
const routerinfo_t *ri = router_get_by_digest(d);
/* Don't actually serve a descriptor that everyone will think is
* expired. This is an (ugly) workaround to keep buggy 0.1.1.10
* Tors from downloading descriptors that they will throw away.
*/
if (ri && ri->cache_info.published_on > cutoff)
smartlist_add(descs_out, &(ri->cache_info));
smartlist_add(descs_out, (void*) &(ri->cache_info));
}
});
SMARTLIST_FOREACH(digests, char *, d, tor_free(d));
@@ -3121,6 +3154,7 @@ dirserv_orconn_tls_done(const char *address,
}
}
});
/* FFFF Maybe we should reinstate the code that dumps routers with the same
* addr/port but with nonmatching keys, but instead of dumping, we should
* skip testing. */
@@ -3130,7 +3164,8 @@ dirserv_orconn_tls_done(const char *address,
* an upload or a download. Used to decide whether to relaunch reachability
* testing for the server. */
int
dirserv_should_launch_reachability_test(routerinfo_t *ri, routerinfo_t *ri_old)
dirserv_should_launch_reachability_test(const routerinfo_t *ri,
const routerinfo_t *ri_old)
{
if (!authdir_mode_handles_descs(get_options(), ri->purpose))
return 0;
@@ -3254,7 +3289,7 @@ dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff)
* its extra-info document if <b>extrainfo</b> is true. Return
* NULL if not found or if the descriptor is older than
* <b>publish_cutoff</b>. */
static signed_descriptor_t *
static const signed_descriptor_t *
get_signed_descriptor_by_fp(const char *fp, int extrainfo,
time_t publish_cutoff)
{
@@ -3264,7 +3299,7 @@ get_signed_descriptor_by_fp(const char *fp, int extrainfo,
else
return &(router_get_my_routerinfo()->cache_info);
} else {
routerinfo_t *ri = router_get_by_digest(fp);
const routerinfo_t *ri = router_get_by_digest(fp);
if (ri &&
ri->cache_info.published_on > publish_cutoff) {
if (extrainfo)
@@ -3332,7 +3367,7 @@ dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
tor_assert(fps);
if (is_serverdescs) {
int n = smartlist_len(fps);
routerinfo_t *me = router_get_my_routerinfo();
const routerinfo_t *me = router_get_my_routerinfo();
result = (me?me->cache_info.signed_descriptor_len:2048) * n;
if (compressed)
result /= 2; /* observed compressibility is between 35 and 55%. */
@@ -3399,7 +3434,7 @@ connection_dirserv_add_servers_to_outbuf(dir_connection_t *conn)
connection_get_outbuf_len(TO_CONN(conn)) < DIRSERV_BUFFER_MIN) {
const char *body;
char *fp = smartlist_pop_last(conn->fingerprint_stack);
signed_descriptor_t *sd = NULL;
const signed_descriptor_t *sd = NULL;
if (by_fp) {
sd = get_signed_descriptor_by_fp(fp, extra, publish_cutoff);
} else {
+11 -7
View File
@@ -40,8 +40,6 @@
MAX_V_LINE_LEN \
)
#define UNNAMED_ROUTER_NICKNAME "Unnamed"
int connection_dirserv_flushed_some(dir_connection_t *conn);
int dirserv_add_own_fingerprint(const char *nickname, crypto_pk_env_t *pk);
@@ -99,13 +97,19 @@ void dirserv_orconn_tls_done(const char *address,
uint16_t or_port,
const char *digest_rcvd,
int as_advertised);
int dirserv_should_launch_reachability_test(routerinfo_t *ri,
routerinfo_t *ri_old);
int dirserv_should_launch_reachability_test(const routerinfo_t *ri,
const routerinfo_t *ri_old);
void dirserv_single_reachability_test(time_t now, routerinfo_t *router);
void dirserv_test_reachability(time_t now);
int authdir_wants_to_reject_router(routerinfo_t *ri, const char **msg,
int complain);
int dirserv_would_reject_router(routerstatus_t *rs);
int complain,
int *valid_out);
uint32_t dirserv_router_get_status(const routerinfo_t *router,
const char **msg);
void dirserv_set_node_flags_from_authoritative_status(node_t *node,
uint32_t authstatus);
int dirserv_would_reject_router(const routerstatus_t *rs);
int dirserv_remove_old_statuses(smartlist_t *fps, time_t cutoff);
int dirserv_have_any_serverdesc(smartlist_t *fps, int spool_src);
int dirserv_have_any_microdesc(const smartlist_t *fps);
@@ -114,7 +118,7 @@ size_t dirserv_estimate_data_size(smartlist_t *fps, int is_serverdescs,
size_t dirserv_estimate_microdesc_size(const smartlist_t *fps, int compressed);
int routerstatus_format_entry(char *buf, size_t buf_len,
routerstatus_t *rs, const char *platform,
const routerstatus_t *rs, const char *platform,
routerstatus_format_type_t format);
void dirserv_free_all(void);
void cached_dir_decref(cached_dir_t *d);
+1
View File
@@ -63,6 +63,7 @@ const char *dirvote_get_pending_detached_signatures(void);
#define DGV_INCLUDE_PREVIOUS 4
const cached_dir_t *dirvote_get_vote(const char *fp, int flags);
void set_routerstatus_from_routerinfo(routerstatus_t *rs,
node_t *node,
routerinfo_t *ri, time_t now,
int naming, int listbadexits,
int listbaddirs);
+1 -1
View File
@@ -668,7 +668,7 @@ dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
cached_resolve_t *resolve;
cached_resolve_t search;
pending_connection_t *pending_connection;
routerinfo_t *me;
const routerinfo_t *me;
tor_addr_t addr;
time_t now = time(NULL);
uint8_t is_reverse = 0;
+13 -2
View File
@@ -33,6 +33,7 @@
#include "main.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "ntmain.h"
#include "onion.h"
#include "policies.h"
@@ -1043,6 +1044,15 @@ run_scheduled_events(time_t now)
*/
consider_hibernation(now);
/* XXXX NM REMOVE THIS. XXXX NM XXXX NM XXXX NM*/
{
static time_t nl_check_time = 0;
if (nl_check_time <= now) {
nodelist_assert_ok();
nl_check_time = now + 30;
}
}
/* 0b. If we've deferred a signewnym, make sure it gets handled
* eventually. */
if (signewnym_is_pending &&
@@ -1267,7 +1277,7 @@ run_scheduled_events(time_t now)
/* If we haven't checked for 12 hours and our bandwidth estimate is
* low, do another bandwidth test. This is especially important for
* bridges, since they might go long periods without much use. */
routerinfo_t *me = router_get_my_routerinfo();
const routerinfo_t *me = router_get_my_routerinfo();
if (time_to_recheck_bandwidth && me &&
me->bandwidthcapacity < me->bandwidthrate &&
me->bandwidthcapacity < 51200) {
@@ -1468,7 +1478,7 @@ second_elapsed_callback(periodic_timer_t *timer, void *arg)
(stats_n_seconds_working+seconds_elapsed) /
TIMEOUT_UNTIL_UNREACHABILITY_COMPLAINT) {
/* every 20 minutes, check and complain if necessary */
routerinfo_t *me = router_get_my_routerinfo();
const routerinfo_t *me = router_get_my_routerinfo();
if (me && !check_whether_orport_reachable()) {
log_warn(LD_CONFIG,"Your server (%s:%d) has not managed to confirm that "
"its ORPort is reachable. Please check your firewalls, ports, "
@@ -2209,6 +2219,7 @@ tor_free_all(int postfork)
connection_free_all();
buf_shrink_freelists(1);
memarea_clear_freelist();
nodelist_free_all();
microdesc_free_all();
if (!postfork) {
config_free_all();
+14 -5
View File
@@ -4,11 +4,13 @@
#include "or.h"
#include "config.h"
#include "directory.h"
#include "microdesc.h"
#include "routerparse.h"
#include "networkstatus.h"
#include "routerlist.h"
#include "dirserv.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "routerlist.h"
#include "routerparse.h"
/** A data structure to hold a bunch of cached microdescriptors. There are
* two active files in the cache: a "cache file" that we mmap, and a "journal
@@ -249,6 +251,12 @@ microdescs_add_list_to_cache(microdesc_cache_t *cache,
microdesc_cache_rebuild(cache);
}
{
networkstatus_t *ns = networkstatus_get_latest_consensus();
if (ns && ns->flavor == FLAV_MICRODESC)
SMARTLIST_FOREACH(added, microdesc_t *, md, nodelist_add_microdesc(md));
}
return added;
}
@@ -474,7 +482,7 @@ microdesc_free(microdesc_t *md)
SMARTLIST_FOREACH(md->family, char *, cp, tor_free(cp));
smartlist_free(md->family);
}
tor_free(md->exitsummary);
short_policy_free(md->exit_policy);
tor_free(md);
}
@@ -612,3 +620,4 @@ update_microdescs_from_networkstatus(time_t now)
md->last_listed = ns->valid_after;
} SMARTLIST_FOREACH_END(rs);
}
+80 -141
View File
@@ -22,6 +22,7 @@
#include "main.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "relay.h"
#include "router.h"
#include "routerlist.h"
@@ -106,9 +107,8 @@ void
networkstatus_reset_warnings(void)
{
if (current_consensus) {
SMARTLIST_FOREACH(current_consensus->routerstatus_list,
routerstatus_t *, rs,
rs->name_lookup_warned = 0);
SMARTLIST_FOREACH(nodelist_get_list(), node_t *, node,
node->name_lookup_warned = 0);
}
have_warned_about_old_version = 0;
@@ -939,10 +939,9 @@ compare_digest_to_routerstatus_entry(const void *_key, const void **_member)
return memcmp(key, rs->identity_digest, DIGEST_LEN);
}
/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
* NULL if none was found. */
/** As networkstatus_v2_find_entry, but do not return a const pointer */
routerstatus_t *
networkstatus_v2_find_entry(networkstatus_v2_t *ns, const char *digest)
networkstatus_v2_find_mutable_entry(networkstatus_v2_t *ns, const char *digest)
{
return smartlist_bsearch(ns->entries, digest,
compare_digest_to_routerstatus_entry);
@@ -950,13 +949,28 @@ networkstatus_v2_find_entry(networkstatus_v2_t *ns, const char *digest)
/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
* NULL if none was found. */
const routerstatus_t *
networkstatus_v2_find_entry(networkstatus_v2_t *ns, const char *digest)
{
return networkstatus_v2_find_mutable_entry(ns, digest);
}
/** As networkstatus_find_entry, but do not return a const pointer */
routerstatus_t *
networkstatus_vote_find_entry(networkstatus_t *ns, const char *digest)
networkstatus_vote_find_mutable_entry(networkstatus_t *ns, const char *digest)
{
return smartlist_bsearch(ns->routerstatus_list, digest,
compare_digest_to_routerstatus_entry);
}
/** Return the entry in <b>ns</b> for the identity digest <b>digest</b>, or
* NULL if none was found. */
const routerstatus_t *
networkstatus_vote_find_entry(networkstatus_t *ns, const char *digest)
{
return networkstatus_vote_find_mutable_entry(ns, digest);
}
/*XXXX make this static once functions are moved into this file. */
/** Search the routerstatuses in <b>ns</b> for one whose identity digest is
* <b>digest</b>. Return value and set *<b>found_out</b> as for
@@ -979,11 +993,11 @@ networkstatus_get_v2_list(void)
return networkstatus_v2_list;
}
/** Return the consensus view of the status of the router whose current
* <i>descriptor</i> digest in <b>consensus</b> is <b>digest</b>, or NULL if
* no such router is known. */
/* As router_get_consensus_status_by_descriptor_digest, but does not return
* a const pointer */
routerstatus_t *
router_get_consensus_status_by_descriptor_digest(networkstatus_t *consensus,
router_get_mutable_consensus_status_by_descriptor_digest(
networkstatus_t *consensus,
const char *digest)
{
if (!consensus)
@@ -1001,6 +1015,17 @@ router_get_consensus_status_by_descriptor_digest(networkstatus_t *consensus,
return digestmap_get(consensus->desc_digest_map, digest);
}
/** Return the consensus view of the status of the router whose current
* <i>descriptor</i> digest in <b>consensus</b> is <b>digest</b>, or NULL if
* no such router is known. */
const routerstatus_t *
router_get_consensus_status_by_descriptor_digest(networkstatus_t *consensus,
const char *digest)
{
return router_get_mutable_consensus_status_by_descriptor_digest(
consensus, digest);
}
/** Given the digest of a router descriptor, return its current download
* status, or NULL if the digest is unrecognized. */
download_status_t *
@@ -1009,8 +1034,8 @@ router_get_dl_status_by_descriptor_digest(const char *d)
routerstatus_t *rs;
if (!current_ns_consensus)
return NULL;
if ((rs = router_get_consensus_status_by_descriptor_digest(
current_ns_consensus, d)))
if ((rs = router_get_mutable_consensus_status_by_descriptor_digest(
current_ns_consensus, d)))
return &rs->dl_status;
if (v2_download_status_map)
return digestmap_get(v2_download_status_map, d);
@@ -1018,10 +1043,9 @@ router_get_dl_status_by_descriptor_digest(const char *d)
return NULL;
}
/** Return the consensus view of the status of the router whose identity
* digest is <b>digest</b>, or NULL if we don't know about any such router. */
/** As router_get_consensus_status_by_id, but do not return a const pointer */
routerstatus_t *
router_get_consensus_status_by_id(const char *digest)
router_get_mutable_consensus_status_by_id(const char *digest)
{
if (!current_consensus)
return NULL;
@@ -1029,100 +1053,27 @@ router_get_consensus_status_by_id(const char *digest)
compare_digest_to_routerstatus_entry);
}
/** Return the consensus view of the status of the router whose identity
* digest is <b>digest</b>, or NULL if we don't know about any such router. */
const routerstatus_t *
router_get_consensus_status_by_id(const char *digest)
{
return router_get_mutable_consensus_status_by_id(digest);
}
/** Given a nickname (possibly verbose, possibly a hexadecimal digest), return
* the corresponding routerstatus_t, or NULL if none exists. Warn the
* user if <b>warn_if_unnamed</b> is set, and they have specified a router by
* nickname, but the Named flag isn't set for that router. */
routerstatus_t *
const routerstatus_t *
router_get_consensus_status_by_nickname(const char *nickname,
int warn_if_unnamed)
{
char digest[DIGEST_LEN];
routerstatus_t *best=NULL;
smartlist_t *matches=NULL;
const char *named_id=NULL;
if (!current_consensus || !nickname)
const node_t *node = node_get_by_nickname(nickname, warn_if_unnamed);
if (node)
return node->rs;
else
return NULL;
/* Is this name really a hexadecimal identity digest? */
if (nickname[0] == '$') {
if (base16_decode(digest, DIGEST_LEN, nickname+1, strlen(nickname+1))<0)
return NULL;
return networkstatus_vote_find_entry(current_consensus, digest);
} else if (strlen(nickname) == HEX_DIGEST_LEN &&
(base16_decode(digest, DIGEST_LEN, nickname, strlen(nickname))==0)) {
return networkstatus_vote_find_entry(current_consensus, digest);
}
/* Is there a server that is Named with this name? */
if (named_server_map)
named_id = strmap_get_lc(named_server_map, nickname);
if (named_id)
return networkstatus_vote_find_entry(current_consensus, named_id);
/* Okay; is this name listed as Unnamed? */
if (unnamed_server_map &&
strmap_get_lc(unnamed_server_map, nickname)) {
log_info(LD_GENERAL, "The name %s is listed as Unnamed; it is not the "
"canonical name of any server we know.", escaped(nickname));
return NULL;
}
/* This name is not canonical for any server; go through the list and
* see who it matches. */
/*XXXX This is inefficient; optimize it if it matters. */
matches = smartlist_create();
SMARTLIST_FOREACH(current_consensus->routerstatus_list,
routerstatus_t *, lrs,
{
if (!strcasecmp(lrs->nickname, nickname)) {
if (lrs->is_named) {
tor_fragile_assert() /* This should never happen. */
smartlist_free(matches);
return lrs;
} else {
if (lrs->is_unnamed) {
tor_fragile_assert(); /* nor should this. */
smartlist_clear(matches);
best=NULL;
break;
}
smartlist_add(matches, lrs);
best = lrs;
}
}
});
if (smartlist_len(matches)>1 && warn_if_unnamed) {
int any_unwarned=0;
SMARTLIST_FOREACH(matches, routerstatus_t *, lrs,
{
if (! lrs->name_lookup_warned) {
lrs->name_lookup_warned=1;
any_unwarned=1;
}
});
if (any_unwarned) {
log_warn(LD_CONFIG,"There are multiple matches for the nickname \"%s\","
" but none is listed as named by the directory authorities. "
"Choosing one arbitrarily.", nickname);
}
} else if (warn_if_unnamed && best && !best->name_lookup_warned) {
char fp[HEX_DIGEST_LEN+1];
base16_encode(fp, sizeof(fp),
best->identity_digest, DIGEST_LEN);
log_warn(LD_CONFIG,
"When looking up a status, you specified a server \"%s\" by name, "
"but the directory authorities do not have any key registered for "
"this nickname -- so it could be used by any server, "
"not just the one you meant. "
"To make sure you get the same server in the future, refer to "
"it by key, as \"$%s\".", nickname, fp);
best->name_lookup_warned = 1;
}
smartlist_free(matches);
return best;
}
/** Return the identity digest that's mapped to officially by
@@ -1524,7 +1475,7 @@ routerstatus_has_changed(const routerstatus_t *a, const routerstatus_t *b)
a->is_exit != b->is_exit ||
a->is_stable != b->is_stable ||
a->is_fast != b->is_fast ||
a->is_running != b->is_running ||
a->is_flagged_running != b->is_flagged_running ||
a->is_named != b->is_named ||
a->is_unnamed != b->is_unnamed ||
a->is_valid != b->is_valid ||
@@ -1565,13 +1516,14 @@ notify_control_networkstatus_changed(const networkstatus_t *old_c,
}
changed = smartlist_create();
SMARTLIST_FOREACH_JOIN(old_c->routerstatus_list, routerstatus_t *, rs_old,
new_c->routerstatus_list, routerstatus_t *, rs_new,
memcmp(rs_old->identity_digest,
rs_new->identity_digest, DIGEST_LEN),
smartlist_add(changed, rs_new)) {
SMARTLIST_FOREACH_JOIN(
old_c->routerstatus_list, const routerstatus_t *, rs_old,
new_c->routerstatus_list, const routerstatus_t *, rs_new,
memcmp(rs_old->identity_digest,
rs_new->identity_digest, DIGEST_LEN),
smartlist_add(changed, (void*) rs_new)) {
if (routerstatus_has_changed(rs_old, rs_new))
smartlist_add(changed, rs_new);
smartlist_add(changed, (void*)rs_new);
} SMARTLIST_FOREACH_JOIN_END(rs_old, rs_new);
control_event_networkstatus_changed(changed);
@@ -1595,7 +1547,6 @@ networkstatus_copy_old_consensus_info(networkstatus_t *new_c,
rs_new->identity_digest, DIGEST_LEN),
STMT_NIL) {
/* Okay, so we're looking at the same identity. */
rs_new->name_lookup_warned = rs_old->name_lookup_warned;
rs_new->last_dir_503_at = rs_old->last_dir_503_at;
if (!memcmp(rs_old->descriptor_digest, rs_new->descriptor_digest,
@@ -1833,6 +1784,8 @@ networkstatus_set_current_consensus(const char *consensus,
/* XXXXNM Microdescs: needs a non-ns variant. */
update_consensus_networkstatus_fetch_time(now);
nodelist_set_consensus(current_consensus);
dirvote_recalculate_timing(options, now);
routerstatus_list_update_named_server_map();
cell_ewma_set_scale_factor(options, current_consensus);
@@ -1975,7 +1928,7 @@ download_status_map_update_from_v2_networkstatus(void)
dl_status = digestmap_new();
SMARTLIST_FOREACH_BEGIN(networkstatus_v2_list, networkstatus_v2_t *, ns) {
SMARTLIST_FOREACH_BEGIN(ns->entries, routerstatus_t *, rs) {
SMARTLIST_FOREACH_BEGIN(ns->entries, const routerstatus_t *, rs) {
const char *d = rs->descriptor_digest;
download_status_t *s;
if (digestmap_get(dl_status, d))
@@ -2003,7 +1956,8 @@ routerstatus_list_update_named_server_map(void)
named_server_map = strmap_new();
strmap_free(unnamed_server_map, NULL);
unnamed_server_map = strmap_new();
SMARTLIST_FOREACH(current_consensus->routerstatus_list, routerstatus_t *, rs,
SMARTLIST_FOREACH(current_consensus->routerstatus_list,
const routerstatus_t *, rs,
{
if (rs->is_named) {
strmap_set_lc(named_server_map, rs->nickname,
@@ -2025,7 +1979,6 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
trusted_dir_server_t *ds;
or_options_t *options = get_options();
int authdir = authdir_mode_v2(options) || authdir_mode_v3(options);
int namingdir = authdir && options->NamingAuthoritativeDir;
networkstatus_t *ns = current_consensus;
if (!ns || !smartlist_len(ns->routerstatus_list))
return;
@@ -2039,25 +1992,19 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
memcmp(rs->identity_digest,
router->cache_info.identity_digest, DIGEST_LEN),
{
#if 0
/* We have no routerstatus for this router. Clear flags and skip it. */
if (!namingdir)
router->is_named = 0;
if (!authdir) {
if (router->purpose == ROUTER_PURPOSE_GENERAL)
router_clear_status_flags(router);
}
#endif
}) {
/* We have a routerstatus for this router. */
const char *digest = router->cache_info.identity_digest;
ds = router_get_trusteddirserver_by_digest(digest);
if (!namingdir) {
if (rs->is_named && !strcasecmp(router->nickname, rs->nickname))
router->is_named = 1;
else
router->is_named = 0;
}
/* Is it the same descriptor, or only the same identity? */
if (!memcmp(router->cache_info.signed_descriptor_digest,
rs->descriptor_digest, DIGEST_LEN)) {
@@ -2065,28 +2012,17 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
router->cache_info.last_listed_as_valid_until = ns->valid_until;
}
if (!authdir) {
/* If we're not an authdir, believe others. */
router->is_valid = rs->is_valid;
router->is_running = rs->is_running;
router->is_fast = rs->is_fast;
router->is_stable = rs->is_stable;
router->is_possible_guard = rs->is_possible_guard;
router->is_exit = rs->is_exit;
router->is_bad_directory = rs->is_bad_directory;
router->is_bad_exit = rs->is_bad_exit;
router->is_hs_dir = rs->is_hs_dir;
} else {
if (authdir) {
/* If we _are_ an authority, we should check whether this router
* is one that will cause us to need a reachability test. */
routerinfo_t *old_router =
router_get_by_digest(router->cache_info.identity_digest);
router_get_mutable_by_digest(router->cache_info.identity_digest);
if (old_router != router) {
router->needs_retest_if_added =
dirserv_should_launch_reachability_test(router, old_router);
}
}
if (router->is_running && ds) {
if (rs->is_flagged_running && ds) {
download_status_reset(&ds->v2_ns_dl_status);
}
if (reset_failures) {
@@ -2098,7 +2034,7 @@ routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
/* XXXX If this is slow, we need to rethink the code. */
SMARTLIST_FOREACH(networkstatus_v2_list, networkstatus_v2_t *, ns, {
time_t live_until = ns->published_on + V2_NETWORKSTATUS_ROUTER_LIFETIME;
SMARTLIST_FOREACH_JOIN(ns->entries, routerstatus_t *, rs,
SMARTLIST_FOREACH_JOIN(ns->entries, const routerstatus_t *, rs,
routers, routerinfo_t *, ri,
memcmp(rs->identity_digest,
ri->cache_info.identity_digest, DIGEST_LEN),
@@ -2131,7 +2067,7 @@ signed_descs_update_status_from_consensus_networkstatus(smartlist_t *descs)
}
SMARTLIST_FOREACH(descs, signed_descriptor_t *, d,
{
routerstatus_t *rs = digestmap_get(ns->desc_digest_map,
const routerstatus_t *rs = digestmap_get(ns->desc_digest_map,
d->signed_descriptor_digest);
if (rs) {
if (ns->valid_until > d->last_listed_as_valid_until)
@@ -2144,7 +2080,7 @@ signed_descs_update_status_from_consensus_networkstatus(smartlist_t *descs)
* return the result in a newly allocated string. Used only by controller
* interface (for now.) */
char *
networkstatus_getinfo_helper_single(routerstatus_t *rs)
networkstatus_getinfo_helper_single(const routerstatus_t *rs)
{
char buf[RS_ENTRY_LEN+1];
routerstatus_format_entry(buf, sizeof(buf), rs, NULL, NS_CONTROL_PORT);
@@ -2177,6 +2113,9 @@ networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now)
statuses = smartlist_create();
SMARTLIST_FOREACH(rl->routers, routerinfo_t *, ri, {
node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
if (!node)
continue;
if (ri->cache_info.published_on < cutoff)
continue;
if (ri->purpose != purpose)
@@ -2184,7 +2123,7 @@ networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now)
if (bridge_auth && ri->purpose == ROUTER_PURPOSE_BRIDGE)
dirserv_set_router_is_running(ri, now);
/* then generate and write out status lines for each of them */
set_routerstatus_from_routerinfo(&rs, ri, now, 0, 0, 0);
set_routerstatus_from_routerinfo(&rs, node, ri, now, 0, 0, 0);
smartlist_add(statuses, networkstatus_getinfo_helper_single(&rs));
});
@@ -2300,7 +2239,7 @@ getinfo_helper_networkstatus(control_connection_t *conn,
const char *question, char **answer,
const char **errmsg)
{
routerstatus_t *status;
const routerstatus_t *status;
(void) conn;
if (!current_consensus) {
@@ -2311,7 +2250,7 @@ getinfo_helper_networkstatus(control_connection_t *conn,
if (!strcmp(question, "ns/all")) {
smartlist_t *statuses = smartlist_create();
SMARTLIST_FOREACH(current_consensus->routerstatus_list,
routerstatus_t *, rs,
const routerstatus_t *, rs,
{
smartlist_add(statuses, networkstatus_getinfo_helper_single(rs));
});
+17 -7
View File
@@ -38,20 +38,30 @@ int router_set_networkstatus_v2(const char *s, time_t arrived_at,
void networkstatus_v2_list_clean(time_t now);
int compare_digest_to_routerstatus_entry(const void *_key,
const void **_member);
routerstatus_t *networkstatus_v2_find_entry(networkstatus_v2_t *ns,
const routerstatus_t *networkstatus_v2_find_entry(networkstatus_v2_t *ns,
const char *digest);
routerstatus_t *networkstatus_vote_find_entry(networkstatus_t *ns,
const routerstatus_t *networkstatus_vote_find_entry(networkstatus_t *ns,
const char *digest);
routerstatus_t *networkstatus_v2_find_mutable_entry(networkstatus_v2_t *ns,
const char *digest);
routerstatus_t *networkstatus_vote_find_mutable_entry(networkstatus_t *ns,
const char *digest);
int networkstatus_vote_find_entry_idx(networkstatus_t *ns,
const char *digest, int *found_out);
const smartlist_t *networkstatus_get_v2_list(void);
download_status_t *router_get_dl_status_by_descriptor_digest(const char *d);
routerstatus_t *router_get_consensus_status_by_id(const char *digest);
routerstatus_t *router_get_consensus_status_by_descriptor_digest(
const routerstatus_t *router_get_consensus_status_by_id(const char *digest);
routerstatus_t *router_get_mutable_consensus_status_by_id(
const char *digest);
const routerstatus_t *router_get_consensus_status_by_descriptor_digest(
networkstatus_t *consensus,
const char *digest);
routerstatus_t *router_get_consensus_status_by_nickname(const char *nickname,
int warn_if_unnamed);
routerstatus_t *router_get_mutable_consensus_status_by_descriptor_digest(
networkstatus_t *consensus,
const char *digest);
const routerstatus_t *router_get_consensus_status_by_nickname(
const char *nickname,
int warn_if_unnamed);
const char *networkstatus_get_router_digest_by_nickname(const char *nickname);
int networkstatus_nickname_is_unnamed(const char *nickname);
void networkstatus_consensus_download_failed(int status_code,
@@ -83,7 +93,7 @@ void routers_update_status_from_consensus_networkstatus(smartlist_t *routers,
void signed_descs_update_status_from_consensus_networkstatus(
smartlist_t *descs);
char *networkstatus_getinfo_helper_single(routerstatus_t *rs);
char *networkstatus_getinfo_helper_single(const routerstatus_t *rs);
char *networkstatus_getinfo_by_purpose(const char *purpose_string, time_t now);
void networkstatus_dump_bridge_status_to_file(time_t now);
int32_t get_net_param_from_list(smartlist_t *net_params, const char *name,
+730
View File
@@ -0,0 +1,730 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
#include "or.h"
#include "config.h"
#include "dirserv.h"
#include "microdesc.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "router.h"
#include "routerlist.h"
#include <string.h>
static void nodelist_drop_node(node_t *node, int remove_from_ht);
static void node_free(node_t *node);
/** A nodelist_t holds a node_t object for every router we're "willing to use
* for something". Specifically, it should hold a node_t for every node that
* is currently in the routerlist, or currently in the consensus we're using.
*/
typedef struct nodelist_t {
/* A list of all the nodes. */
smartlist_t *nodes;
/* Hash table to map from node ID digest to node. */
HT_HEAD(nodelist_map, node_t) nodes_by_id;
} nodelist_t;
static INLINE unsigned int
node_id_hash(const node_t *node)
{
#if SIZEOF_INT == 4
const uint32_t *p = (const uint32_t*)node->identity;
return p[0] ^ p[1] ^ p[2] ^ p[3] ^ p[4];
#elif SIZEOF_INT == 8
const uint64_t *p = (const uint32_t*)node->identity;
const uint32_t *p32 = (const uint32_t*)node->identity;
return p[0] ^ p[1] ^ p32[4];
#endif
}
static INLINE unsigned int
node_id_eq(const node_t *node1, const node_t *node2)
{
return 0 == memcmp(node1->identity, node2->identity, DIGEST_LEN);
}
HT_PROTOTYPE(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq);
HT_GENERATE(nodelist_map, node_t, ht_ent, node_id_hash, node_id_eq,
0.6, malloc, realloc, free);
/** The global nodelist. */
static nodelist_t *the_nodelist=NULL;
/** Create an empty nodelist if we haven't done so already. */
static void
init_nodelist(void)
{
if (PREDICT_UNLIKELY(the_nodelist == NULL)) {
the_nodelist = tor_malloc_zero(sizeof(nodelist_t));
HT_INIT(nodelist_map, &the_nodelist->nodes_by_id);
the_nodelist->nodes = smartlist_create();
}
}
/** As node_get_by_id, but returns a non-const pointer */
node_t *
node_get_mutable_by_id(const char *identity_digest)
{
node_t search, *node;
if (PREDICT_UNLIKELY(the_nodelist == NULL))
return NULL;
memcpy(&search.identity, identity_digest, DIGEST_LEN);
node = HT_FIND(nodelist_map, &the_nodelist->nodes_by_id, &search);
return node;
}
/** Return the node_t whose identity is <b>identity_digest</b>, or NULL
* if no such node exists. */
const node_t *
node_get_by_id(const char *identity_digest)
{
return node_get_mutable_by_id(identity_digest);
}
/** Internal: return the node_t whose identity_digest is
* <b>identity_digest</b>. If none exists, create a new one, add it to the
* nodelist, and return it.
*
* Requires that the nodelist be initialized.
*/
static node_t *
node_get_or_create(const char *identity_digest)
{
node_t *node;
if ((node = node_get_mutable_by_id(identity_digest)))
return node;
node = tor_malloc_zero(sizeof(node_t));
memcpy(node->identity, identity_digest, DIGEST_LEN);
HT_INSERT(nodelist_map, &the_nodelist->nodes_by_id, node);
smartlist_add(the_nodelist->nodes, node);
node->nodelist_idx = smartlist_len(the_nodelist->nodes) - 1;
node->country = -1;
return node;
}
/** Add <b>ri</b> to the nodelist. */
node_t *
nodelist_add_routerinfo(routerinfo_t *ri)
{
node_t *node;
init_nodelist();
node = node_get_or_create(ri->cache_info.identity_digest);
node->ri = ri;
if (node->country == -1)
node_set_country(node);
if (authdir_mode(get_options())) {
const char *discard=NULL;
uint32_t status = dirserv_router_get_status(ri, &discard);
dirserv_set_node_flags_from_authoritative_status(node, status);
}
return node;
}
/** Set the appropriate node_t to use <b>md</b> as its microdescriptor.
*
* Called when a new microdesc has arrived and the usable consensus flavor
* is "microdesc".
**/
node_t *
nodelist_add_microdesc(microdesc_t *md)
{
networkstatus_t *ns =
networkstatus_get_latest_consensus_by_flavor(FLAV_MICRODESC);
const routerstatus_t *rs;
node_t *node;
if (ns == NULL)
return NULL;
init_nodelist();
/* Microdescriptors don't carry an identity digest, so we need to figure
* it out by looking up the routerstatus. */
rs = router_get_consensus_status_by_descriptor_digest(ns, md->digest);
if (rs == NULL)
return NULL;
node = node_get_mutable_by_id(rs->identity_digest);
if (node)
node->md = md;
return node;
}
/** Tell the nodelist that the current usable consensus to <b>ns</b>.
* This makes the nodelist change all of the routerstatus entries for
* the nodes, drop nodes that no longer have enough info to get used,
* and grab microdescriptors into nodes as appropriate.
*/
void
nodelist_set_consensus(networkstatus_t *ns)
{
or_options_t *options = get_options();
int authdir = authdir_mode_v2(options) || authdir_mode_v3(options);
init_nodelist();
SMARTLIST_FOREACH(the_nodelist->nodes, node_t *, node,
node->rs = NULL);
SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
node_t *node = node_get_or_create(rs->identity_digest);
node->rs = rs;
if (ns->flavor == FLAV_MICRODESC) {
if (node->md == NULL ||
0!=memcmp(node->md->digest,rs->descriptor_digest,DIGEST256_LEN)) {
node->md = microdesc_cache_lookup_by_digest256(NULL,
rs->descriptor_digest);
}
}
node_set_country(node);
/* If we're not an authdir, believe others. */
if (!authdir) {
node->is_valid = rs->is_valid;
node->is_running = rs->is_flagged_running;
node->is_fast = rs->is_fast;
node->is_stable = rs->is_stable;
node->is_possible_guard = rs->is_possible_guard;
node->is_exit = rs->is_exit;
node->is_bad_directory = rs->is_bad_directory;
node->is_bad_exit = rs->is_bad_exit;
node->is_hs_dir = rs->is_hs_dir;
}
} SMARTLIST_FOREACH_END(rs);
nodelist_purge();
if (! authdir) {
SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
/* We have no routerstatus for this router. Clear flags so we can skip
* it, maybe.*/
if (!node->rs) {
tor_assert(node->ri); /* if it had only an md, or nothing, purge
* would have removed it. */
if (node->ri->purpose == ROUTER_PURPOSE_GENERAL) {
/* Clear all flags. */
node->is_valid = node->is_running = node->is_hs_dir =
node->is_fast = node->is_stable =
node->is_possible_guard = node->is_exit =
node->is_bad_exit = node->is_bad_directory = 0;
}
}
} SMARTLIST_FOREACH_END(node);
}
}
/** Helper: return true iff a node has a usable amount of information*/
static INLINE int
node_is_usable(const node_t *node)
{
return (node->rs) || (node->ri);
}
/** Tell the nodelist that <b>md</b> is no longer a microdescriptor for the
* node with <b>identity_digest</b>. */
void
nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md)
{
node_t *node = node_get_mutable_by_id(identity_digest);
if (node && node->md == md)
node->md = NULL;
}
/** Tell the nodelist that <b>ri</b> is no longer in the routerlist. */
void
nodelist_remove_routerinfo(routerinfo_t *ri)
{
node_t *node = node_get_mutable_by_id(ri->cache_info.identity_digest);
if (node && node->ri == ri) {
node->ri = NULL;
if (! node_is_usable(node)) {
nodelist_drop_node(node, 1);
node_free(node);
}
}
}
/** Remove <b>node</b> from the nodelist. (Asserts that it was there to begin
* with.) */
static void
nodelist_drop_node(node_t *node, int remove_from_ht)
{
node_t *tmp;
int idx;
if (remove_from_ht) {
tmp = HT_REMOVE(nodelist_map, &the_nodelist->nodes_by_id, node);
tor_assert(tmp == node);
}
idx = node->nodelist_idx;
tor_assert(idx >= 0);
tor_assert(node == smartlist_get(the_nodelist->nodes, idx));
smartlist_del(the_nodelist->nodes, idx);
if (idx < smartlist_len(the_nodelist->nodes)) {
tmp = smartlist_get(the_nodelist->nodes, idx);
tmp->nodelist_idx = idx;
}
node->nodelist_idx = -1;
}
/** Release storage held by <b>node</b> */
static void
node_free(node_t *node)
{
if (!node)
return;
tor_assert(node->nodelist_idx == -1);
tor_free(node);
}
/** Remove all entries from the nodelist that don't have enough info to be
* usable for anything. */
void
nodelist_purge(void)
{
node_t **iter;
if (PREDICT_UNLIKELY(the_nodelist == NULL))
return;
/* Remove the non-usable nodes. */
for (iter = HT_START(nodelist_map, &the_nodelist->nodes_by_id); iter; ) {
node_t *node = *iter;
if (node_is_usable(node)) {
iter = HT_NEXT(nodelist_map, &the_nodelist->nodes_by_id, iter);
} else {
iter = HT_NEXT_RMV(nodelist_map, &the_nodelist->nodes_by_id, iter);
nodelist_drop_node(node, 0);
node_free(node);
}
}
nodelist_assert_ok();
}
/** Release all storage held by the nodelist. */
void
nodelist_free_all(void)
{
if (PREDICT_UNLIKELY(the_nodelist == NULL))
return;
HT_CLEAR(nodelist_map, &the_nodelist->nodes_by_id);
SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
node->nodelist_idx = -1;
node_free(node);
} SMARTLIST_FOREACH_END(node);
smartlist_free(the_nodelist->nodes);
tor_free(the_nodelist);
}
/** Check that the nodelist is internally consistent, and consistent with
* the directory info it's derived from.
*/
void
nodelist_assert_ok(void)
{
routerlist_t *rl = router_get_routerlist();
networkstatus_t *ns = networkstatus_get_latest_consensus();
digestmap_t *dm = digestmap_new();
if (!the_nodelist)
return;
/* every routerinfo in rl->routers should be in the nodelist. */
if (rl) {
SMARTLIST_FOREACH_BEGIN(rl->routers, routerinfo_t *, ri) {
const node_t *node = node_get_by_id(ri->cache_info.identity_digest);
tor_assert(node && node->ri == ri);
tor_assert(0 == memcmp(ri->cache_info.identity_digest,
node->identity, DIGEST_LEN));
tor_assert(! digestmap_get(dm, node->identity));
digestmap_set(dm, node->identity, (void*)node);
} SMARTLIST_FOREACH_END(ri);
}
/* every routerstatus in ns should be in the nodelist */
if (ns) {
SMARTLIST_FOREACH_BEGIN(ns->routerstatus_list, routerstatus_t *, rs) {
const node_t *node = node_get_by_id(rs->identity_digest);
tor_assert(node && node->rs == rs);
tor_assert(0 == memcmp(rs->identity_digest, node->identity, DIGEST_LEN));
digestmap_set(dm, node->identity, (void*)node);
if (ns->flavor == FLAV_MICRODESC) {
/* If it's a microdesc consensus, every entry that has a
* microdescriptor should be in the nodelist.
*/
microdesc_t *md =
microdesc_cache_lookup_by_digest256(NULL, rs->descriptor_digest);
tor_assert(md == node->md);
}
} SMARTLIST_FOREACH_END(rs);
}
/* The nodelist should have no other entries, and its entries should be
* well-formed. */
SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
tor_assert(digestmap_get(dm, node->identity) != NULL);
tor_assert(node_sl_idx == node->nodelist_idx);
} SMARTLIST_FOREACH_END(node);
tor_assert((long)smartlist_len(the_nodelist->nodes) ==
(long)HT_SIZE(&the_nodelist->nodes_by_id));
digestmap_free(dm, NULL);
}
/** Return a list of a node_t * for every node we know about. The caller
* MUST NOT modify the list. (You can set and clear flags in the nodes if
* you must, but you must not add or remove nodes.) */
smartlist_t *
nodelist_get_list(void)
{
init_nodelist();
return the_nodelist->nodes;
}
/** Given a nickname (possibly verbose, possibly a hexadecimal digest), return
* the corresponding node_t, or NULL if none exists. Warn the user if
* <b>warn_if_unnamed</b> is set, and they have specified a router by
* nickname, but the Named flag isn't set for that router. */
const node_t *
node_get_by_nickname(const char *nickname, int warn_if_unnamed)
{
char digest_buf[DIGEST_LEN];
char nn_buf[MAX_NICKNAME_LEN+1];
char nn_char='\0';
if (!the_nodelist)
return NULL;
/* ???? NM Naming authorities had an additional weird behavior here where
they would treat their own namings as slightly authoritative in a
strange and inconsistent way. I think that this way is better, but we
could get the old behavior back if we wanted to by adding a function
to look in the fp_by_name table in fingerprint_list, and using this
function to override the name-to-digest lookup below if we are a
naming server. -NM
*/
/* Handle these cases: DIGEST, $DIGEST, $DIGEST=name, $DIGEST~name. */
if (hex_digest_nickname_decode(nickname, digest_buf, &nn_char, nn_buf)==0) {
const node_t *node = node_get_by_id(digest_buf);
if (!node)
return NULL;
if (nn_char) {
const char *real_name = node_get_nickname(node);
if (!real_name || strcasecmp(real_name, nn_buf))
return NULL;
if (nn_char == '=') {
const char *named_id =
networkstatus_get_router_digest_by_nickname(nn_buf);
if (!named_id || memcmp(named_id, digest_buf, DIGEST_LEN))
return NULL;
}
}
return node;
}
if (!strcasecmp(nickname, UNNAMED_ROUTER_NICKNAME))
return NULL;
/* Okay, so if we get here, the nickname is just a nickname. Is there
* a binding for it in the consensus? */
{
const char *named_id =
networkstatus_get_router_digest_by_nickname(nickname);
if (named_id)
return node_get_by_id(named_id);
}
/* Is it marked as owned-by-someone-else? */
if (networkstatus_nickname_is_unnamed(nickname)) {
log_info(LD_GENERAL, "The name %s is listed as Unnamed: there is some "
"router that holds it, but not one listed in the current "
"consensus.", escaped(nickname));
return NULL;
}
/* Okay, so the name is not canonical for anybody. */
{
smartlist_t *matches = smartlist_create();
const node_t *choice = NULL;
SMARTLIST_FOREACH_BEGIN(the_nodelist->nodes, node_t *, node) {
if (!strcasecmp(node_get_nickname(node), nickname))
smartlist_add(matches, node);
} SMARTLIST_FOREACH_END(node);
if (smartlist_len(matches)>1 && warn_if_unnamed) {
int any_unwarned = 0;
SMARTLIST_FOREACH_BEGIN(matches, node_t *, node) {
if (!node->name_lookup_warned) {
node->name_lookup_warned = 1;
any_unwarned = 1;
}
} SMARTLIST_FOREACH_END(node);
if (any_unwarned) {
log_warn(LD_CONFIG, "There are multiple matches for the name %s, "
"but none is listed as Named in the directory consensus. "
"Choosing one arbitrarily.", nickname);
}
} else if (smartlist_len(matches)>1 && warn_if_unnamed) {
char fp[HEX_DIGEST_LEN+1];
node_t *node = smartlist_get(matches, 0);
if (node->name_lookup_warned) {
base16_encode(fp, sizeof(fp), node->identity, DIGEST_LEN);
log_warn(LD_CONFIG,
"You specified a server \"%s\" by name, but the directory "
"authorities do not have any key registered for this "
"nickname -- so it could be used by any server, not just "
"the one you meant. "
"To make sure you get the same server in the future, refer "
"to it by key, as \"$%s\".", nickname, fp);
node->name_lookup_warned = 1;
}
}
if (smartlist_len(matches))
choice = smartlist_get(matches, 0);
smartlist_free(matches);
return choice;
}
}
/** Return the nickname of <b>node</b>, or NULL if we can't find one. */
const char *
node_get_nickname(const node_t *node)
{
tor_assert(node);
if (node->rs)
return node->rs->nickname;
else if (node->ri)
return node->ri->nickname;
else
return NULL;
}
/** Return true iff the nickname of <b>node</b> is canonical, based on the
* latest consensus. */
int
node_is_named(const node_t *node)
{
const char *named_id;
const char *nickname = node_get_nickname(node);
if (!nickname)
return 0;
named_id = networkstatus_get_router_digest_by_nickname(nickname);
if (!named_id)
return 0;
return !memcmp(named_id, node->identity, DIGEST_LEN);
}
/** Return true iff <b>node</b> appears to be a directory authority or
* directory cache */
int
node_is_dir(const node_t *node)
{
if (node->rs)
return node->rs->dir_port != 0;
else if (node->ri)
return node->ri->dir_port != 0;
else
return 0;
}
/** Return true iff <b>node</b> has either kind of usable descriptor -- that
* is, a routerdecriptor or a microdescriptor. */
int
node_has_descriptor(const node_t *node)
{
return (node->ri ||
(node->rs && node->md));
}
/** Return the router_purpose of <b>node</b>. */
int
node_get_purpose(const node_t *node)
{
if (node->ri)
return node->ri->purpose;
else
return ROUTER_PURPOSE_GENERAL;
}
/** Compute the verbose ("extended") nickname of <b>node</b> and store it
* into the MAX_VERBOSE_NICKNAME_LEN+1 character buffer at
* <b>verbose_nickname_out</b> */
void
node_get_verbose_nickname(const node_t *node,
char *verbose_name_out)
{
const char *nickname = node_get_nickname(node);
int is_named = node_is_named(node);
verbose_name_out[0] = '$';
base16_encode(verbose_name_out+1, HEX_DIGEST_LEN+1, node->identity,
DIGEST_LEN);
if (!nickname)
return;
verbose_name_out[1+HEX_DIGEST_LEN] = is_named ? '=' : '~';
strlcpy(verbose_name_out+1+HEX_DIGEST_LEN+1, nickname, MAX_NICKNAME_LEN+1);
}
/** Return true iff it seems that <b>node</b> allows circuits to exit
* through it directlry from the client. */
int
node_allows_single_hop_exits(const node_t *node)
{
if (node && node->ri)
return node->ri->allow_single_hop_exits;
else
return 0;
}
/** Return true iff it seems that <b>node</b> has an exit policy that doesn't
* actually permit anything to exit, or we don't know its exit policy */
int
node_exit_policy_rejects_all(const node_t *node)
{
if (node->ri)
return node->ri->policy_is_reject_star;
else if (node->md)
return node->md->exit_policy == NULL ||
short_policy_is_reject_star(node->md->exit_policy);
else
return 1;
}
/** Copy the address for <b>node</b> into *<b>addr_out</b>. */
int
node_get_addr(const node_t *node, tor_addr_t *addr_out)
{
if (node->ri) {
tor_addr_from_ipv4h(addr_out, node->ri->addr);
return 0;
} else if (node->rs) {
tor_addr_from_ipv4h(addr_out, node->rs->addr);
return 0;
}
return -1;
}
/** Return the host-order IPv4 address for <b>node</b>, or 0 if it doesn't
* seem to have one. */
uint32_t
node_get_addr_ipv4h(const node_t *node)
{
if (node->ri) {
return node->ri->addr;
} else if (node->rs) {
return node->rs->addr;
}
return 0;
}
/** Copy a string representation of the IP address for <b>node</b> into the
* <b>len</b>-byte buffer at <b>buf</b>.
*/
void
node_get_address_string(const node_t *node, char *buf, size_t len)
{
if (node->ri) {
strlcpy(buf, node->ri->address, len);
} else if (node->rs) {
tor_addr_t addr;
tor_addr_from_ipv4h(&addr, node->rs->addr);
tor_addr_to_str(buf, &addr, len, 0);
} else {
buf[0] = '\0';
}
}
/** Return <b>node</b>'s declared uptime, or -1 if it doesn't seem to have
* one. */
long
node_get_declared_uptime(const node_t *node)
{
if (node->ri)
return node->ri->uptime;
else
return -1;
}
/** Return <b>node</b>'s declared or_port */
uint16_t
node_get_orport(const node_t *node)
{
if (node->ri)
return node->ri->or_port;
else if (node->rs)
return node->rs->or_port;
else
return 0;
}
/** Return <b>node</b>'s platform string, or NULL if we don't know it. */
const char *
node_get_platform(const node_t *node)
{
/* If we wanted, we could record the version in the routerstatus_t, since
* the consensus lists it. We don't, though, so this function just won't
* work with microdescriptors. */
if (node->ri)
return node->ri->platform;
else
return NULL;
}
/** Return <b>node</b>'s time of publication, or 0 if we don't have one. */
time_t
node_get_published_on(const node_t *node)
{
if (node->ri)
return node->ri->cache_info.published_on;
else
return 0;
}
/** Return true iff <b>node</b> is one representing this router. */
int
node_is_me(const node_t *node)
{
return router_digest_is_me(node->identity);
}
/** Return <b>node</b> declared family (as a list of names), or NULL if
* the node didn't declare a family. */
const smartlist_t *
node_get_declared_family(const node_t *node)
{
if (node->ri && node->ri->declared_family)
return node->ri->declared_family;
else if (node->md && node->md->family)
return node->md->family;
else
return NULL;
}
/* KILLTHIS XXXX NM -- it's a dummy to keep UNIMPLEMENTED_NODELIST()
* working */
int unimplemented_nodelist_truth = 1;
+66
View File
@@ -0,0 +1,66 @@
/* Copyright (c) 2001 Matej Pfajfar.
* Copyright (c) 2001-2004, Roger Dingledine.
* Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
* Copyright (c) 2007-2010, The Tor Project, Inc. */
/* See LICENSE for licensing information */
/**
* \file microdesc.h
* \brief Header file for microdesc.c.
**/
#ifndef _TOR_NODELIST_H
#define _TOR_NODELIST_H
node_t *node_get_mutable_by_id(const char *identity_digest);
const node_t *node_get_by_id(const char *identity_digest);
node_t *nodelist_add_routerinfo(routerinfo_t *ri);
node_t *nodelist_add_microdesc(microdesc_t *md);
void nodelist_set_consensus(networkstatus_t *ns);
void nodelist_remove_microdesc(const char *identity_digest, microdesc_t *md);
void nodelist_remove_routerinfo(routerinfo_t *ri);
void nodelist_purge(void);
void nodelist_free_all(void);
void nodelist_assert_ok(void);
const node_t *node_get_by_nickname(const char *nickname, int warn_if_unnamed);
void node_get_verbose_nickname(const node_t *node,
char *verbose_name_out);
int node_is_named(const node_t *node);
int node_is_dir(const node_t *node);
int node_has_descriptor(const node_t *node);
int node_get_purpose(const node_t *node);
#define node_is_bridge(node) \
(node_get_purpose((node)) == ROUTER_PURPOSE_BRIDGE)
int node_is_me(const node_t *node);
int node_exit_policy_rejects_all(const node_t *node);
int node_get_addr(const node_t *node, tor_addr_t *addr_out);
uint32_t node_get_addr_ipv4h(const node_t *node);
int node_allows_single_hop_exits(const node_t *node);
uint16_t node_get_orport(const node_t *node);
const char *node_get_nickname(const node_t *node);
const char *node_get_platform(const node_t *node);
void node_get_address_string(const node_t *node, char *cp, size_t len);
long node_get_declared_uptime(const node_t *node);
time_t node_get_published_on(const node_t *node);
const smartlist_t *node_get_declared_family(const node_t *node);
smartlist_t *nodelist_get_list(void);
/* XXXX These need to move out of routerlist.c */
void nodelist_refresh_countries(void);
void node_set_country(node_t *node);
void nodelist_add_node_family(smartlist_t *nodes, const node_t *node);
int nodes_in_same_family(const node_t *node1, const node_t *node2);
/* This means: implement this code or function or thing, nick! */
#define UNIMPLEMENTED_NODELIST() \
while (unimplemented_nodelist_truth) { \
tor_assert(0); \
}
extern int unimplemented_nodelist_truth;
#endif
+112 -34
View File
@@ -809,6 +809,9 @@ typedef enum {
* Tor 0.1.2.x is obsolete, we can remove this. */
#define DEFAULT_CLIENT_NICKNAME "client"
/** Name chosen by routers that don't configure nicknames */
#define UNNAMED_ROUTER_NICKNAME "Unnamed"
/** Number of bytes in a SOCKS4 header. */
#define SOCKS4_NETWORK_LEN 8
@@ -1510,52 +1513,44 @@ typedef struct {
unsigned int allow_single_hop_exits:1; /**< Whether the router says
* it allows single hop exits. */
/* local info */
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?)
*/
unsigned int is_named:1; /**< Do we believe the nickname that this OR gives
* us? */
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? */
unsigned int is_exit:1; /**< Do we think this is an OK exit? */
unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked,
* or otherwise nasty? */
unsigned int is_bad_directory:1; /**< Do we think this directory is junky,
* underpowered, or otherwise useless? */
unsigned int wants_to_be_hs_dir:1; /**< True iff this router claims to be
* a hidden service directory. */
unsigned int is_hs_dir:1; /**< True iff this router is a hidden service
* directory according to the authorities. */
unsigned int policy_is_reject_star:1; /**< True iff the exit policy for this
* router rejects everything. */
/** True if, after we have added this router, we should re-launch
* tests for it. */
unsigned int needs_retest_if_added:1;
/** Tor can use this router for general positions in circuits. */
/** Tor can use this router for general positions in circuits; we got it
* from a directory server as usual, or we're an authority and a server
* uploaded it. */
#define ROUTER_PURPOSE_GENERAL 0
/** Tor should avoid using this router for circuit-building. */
/** Tor should avoid using this router for circuit-building: we got it
* from a crontroller. If the controller wants to use it, it'll have to
* ask for it by identity. */
#define ROUTER_PURPOSE_CONTROLLER 1
/** Tor should use this router only for bridge positions in circuits. */
/** Tor should use this router only for bridge positions in circuits: we got
* it via a directory request from the bridge itself, or a bridge
* authority. x*/
#define ROUTER_PURPOSE_BRIDGE 2
/** Tor should not use this router; it was marked in cached-descriptors with
* a purpose we didn't recognize. */
#define ROUTER_PURPOSE_UNKNOWN 255
uint8_t purpose; /** What positions in a circuit is this router good for? */
/* In what way did we find out about this router? One of ROUTER_PURPOSE_*.
* Routers of different purposes are kept segregated and used for different
* 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;
/** According to the geoip db what country is this router in? */
country_t country;
} routerinfo_t;
/** Information needed to keep and cache a signed extra-info document. */
@@ -1591,7 +1586,11 @@ typedef struct routerstatus_t {
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. */
unsigned int is_fast:1; /**< True iff this router has good bandwidth. */
unsigned int is_running:1; /**< True iff this router is up. */
/** True iff this router is called 'running' in the consensus. We give it
* this funny name so that we don't accidentally use this bit as a view of
* whether we think the router is *currently* running. If that's what you
* want to know, look at is_running in node_t. */
unsigned int is_flagged_running:1;
unsigned int is_named:1; /**< True iff "nickname" belongs to this router. */
unsigned int is_unnamed:1; /**< True iff "nickname" belongs to another
* router. */
@@ -1643,15 +1642,31 @@ typedef struct routerstatus_t {
* from this authority.) Applies in v2 networkstatus document only.
*/
unsigned int need_to_mirror:1;
unsigned int name_lookup_warned:1; /**< Have we warned the user for referring
* to this (unnamed) router by nickname?
*/
time_t last_dir_503_at; /**< When did this router last tell us that it
* was too busy to serve directory info? */
download_status_t dl_status;
} routerstatus_t;
/** A single entry in a parsed policy summary, describing a range of ports. */
typedef struct short_policy_entry_t {
uint16_t min_port, max_port;
} short_policy_entry_t;
/** A short_poliy_t is the parsed version of a policy summary. */
typedef struct short_policy_t {
/** True if the members of 'entries' are port ranges to accept; false if
* they are port ranges to reject */
unsigned int is_accept : 1;
/** The actual number of values in 'entries'. */
unsigned int n_entries : 31;
/** An array of (probably more than 1!) short_policy_entry_t values,
* each descriping a range of ports that this policy accepts or rejects
* (depending on the value of is_accept).
*/
short_policy_entry_t entries[1];
} short_policy_t;
/** A microdescriptor is the smallest amount of information needed to build a
* circuit through a router. They are generated by the directory authorities,
* using information from the uploaded routerinfo documents. They are not
@@ -1693,11 +1708,72 @@ typedef struct microdesc_t {
crypto_pk_env_t *onion_pkey;
/** As routerinfo_t.family */
smartlist_t *family;
/** Encoded exit policy summary */
char *exitsummary; /**< exit policy summary -
* XXX this probably should not stay a string. */
/** Exit policy summary */
short_policy_t *exit_policy;
} microdesc_t;
/** A node_t represents a Tor router.
*
* Specifically, a node_t is a Tor router as we are using it: a router that
* we are considering for circuits, connections, and so on. A node_t is a
* thin wrapper around the routerstatus, routerinfo, and microdesc for a
* single wrapper, and provides a consistent interface for all of them.
*
* Also, a node_t has mutable state. While a routerinfo, a routerstatus,
* and a microdesc have[*] only the information read from a router
* descriptor, a consensus entry, and a microdescriptor (respectively)...
* a node_t has flags based on *our own current opinion* of the node.
*
* [*] Actually, there is some leftover information in each that is mutable.
* We should try to excise that.
*/
typedef struct node_t {
/* Indexing information */
/** Used to look up the node_t by its identity digest. */
HT_ENTRY(node_t) ht_ent;
/** Position of the node within the list of nodes */
int nodelist_idx;
/** The identity digest of this node_t. No more than one node_t per
* identity may exist at a time. */
char identity[DIGEST_LEN];
microdesc_t *md;
routerinfo_t *ri;
routerstatus_t *rs;
/* local info: copied from routerstatus, then possibly frobbed based
* on experience. Authorities set this stuff directly. */
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?)
*/
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? */
unsigned int is_exit:1; /**< Do we think this is an OK exit? */
unsigned int is_bad_exit:1; /**< Do we think this exit is censored, borked,
* or otherwise nasty? */
unsigned int is_bad_directory:1; /**< Do we think this directory is junky,
* underpowered, or otherwise useless? */
unsigned int is_hs_dir:1; /**< True iff this router is a hidden service
* directory according to the authorities. */
/* Local info: warning state. */
unsigned int name_lookup_warned:1; /**< Have we warned the user for referring
* to this (unnamed) router by nickname?
*/
/* Local info: derived. */
/** According to the geoip db what country is this router in? */
country_t country;
} node_t;
/** How many times will we try to download a router's descriptor before giving
* up? */
#define MAX_ROUTERDESC_DOWNLOAD_FAILURES 8
@@ -2667,7 +2743,8 @@ typedef struct {
char *MyFamily; /**< Declared family for this OR. */
config_line_t *NodeFamilies; /**< List of config lines for
* node families */
* node families */
smartlist_t *NodeFamilySets; /**< List of parsed NodeFamilies values. */
config_line_t *AuthDirBadDir; /**< Address policy for descriptors to
* mark as bad dir mirrors. */
config_line_t *AuthDirBadExit; /**< Address policy for descriptors to
@@ -3385,7 +3462,7 @@ typedef enum {
ADDR_POLICY_PROBABLY_ACCEPTED=1,
/** Part of the address was unknown, but as far as we can tell, it was
* rejected. */
ADDR_POLICY_PROBABLY_REJECTED=2
ADDR_POLICY_PROBABLY_REJECTED=2,
} addr_policy_result_t;
/********************************* rephist.c ***************************/
@@ -3535,7 +3612,8 @@ typedef enum {
CRN_NEED_GUARD = 1<<2,
CRN_ALLOW_INVALID = 1<<3,
/* XXXX not used, apparently. */
CRN_WEIGHT_AS_EXIT = 1<<5
CRN_WEIGHT_AS_EXIT = 1<<5,
CRN_NEED_DESC = 1<<6
} router_crn_flags_t;
/** Return value for router_add_to_routerlist() and dirserv_add_descriptor() */
+213 -1
View File
@@ -11,6 +11,7 @@
#include "or.h"
#include "config.h"
#include "dirserv.h"
#include "nodelist.h"
#include "policies.h"
#include "routerparse.h"
#include "ht.h"
@@ -261,7 +262,7 @@ fascist_firewall_allows_address_or(const tor_addr_t *addr, uint16_t port)
/** Return true iff we think our firewall will let us make an OR connection to
* <b>ri</b>. */
int
fascist_firewall_allows_or(routerinfo_t *ri)
fascist_firewall_allows_or(const routerinfo_t *ri)
{
/* XXXX proposal 118 */
tor_addr_t addr;
@@ -269,6 +270,22 @@ fascist_firewall_allows_or(routerinfo_t *ri)
return fascist_firewall_allows_address_or(&addr, ri->or_port);
}
/** Return true iff we think our firewall will let us make an OR connection to
* <b>node</b>. */
int
fascist_firewall_allows_node(const node_t *node)
{
if (node->ri) {
return fascist_firewall_allows_or(node->ri);
} else if (node->rs) {
tor_addr_t addr;
tor_addr_from_ipv4h(&addr, node->rs->addr);
return fascist_firewall_allows_address_or(&addr, node->rs->or_port);
} else {
return 1;
}
}
/** Return true iff we think our firewall will let us make a directory
* connection to addr:port. */
int
@@ -858,6 +875,7 @@ policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
return 0;
}
#if 0
/** Replace the exit policy of <b>r</b> with reject *:*. */
void
policies_set_router_exitpolicy_to_reject_all(routerinfo_t *r)
@@ -868,6 +886,15 @@ policies_set_router_exitpolicy_to_reject_all(routerinfo_t *r)
item = router_parse_addr_policy_item_from_string("reject *:*", -1);
smartlist_add(r->exit_policy, item);
}
#endif
/** Replace the exit policy of <b>node</b> with reject *:* */
void
policies_set_node_exitpolicy_to_reject_all(node_t *node)
{
(void)node;
UNIMPLEMENTED_NODELIST();
}
/** Return 1 if there is at least one /8 subnet in <b>policy</b> that
* allows exiting to <b>port</b>. Otherwise, return 0. */
@@ -1288,6 +1315,191 @@ policy_summarize(smartlist_t *policy)
return result;
}
/** Convert a summarized policy string into a short_policy_t. Return NULL
* if the string is not well-formed. */
short_policy_t *
parse_short_policy(const char *summary)
{
const char *orig_summary = summary;
short_policy_t *result;
int is_accept;
int n_entries;
short_policy_entry_t entries[MAX_EXITPOLICY_SUMMARY_LEN]; /* overkill */
const char *next;
if (!strcmpstart(summary, "accept ")) {
is_accept = 1;
summary += strlen("accept ");
} else if (!strcmpstart(summary, "reject ")) {
is_accept = 0;
summary += strlen("reject ");
} else {
log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Unrecognized policy summary keyword");
return NULL;
}
n_entries = 0;
for ( ; *summary; summary = next) {
const char *comma = strchr(summary, ',');
unsigned low, high;
char dummy;
char ent_buf[32];
next = comma ? comma+1 : strchr(summary, '\0');
if (n_entries == MAX_EXITPOLICY_SUMMARY_LEN) {
log_fn(LOG_PROTOCOL_WARN, LD_DIR, "Impossibly long policy summary %s",
escaped(orig_summary));
return NULL;
}
if (! TOR_ISDIGIT(*summary) || next-summary > (int)(sizeof(ent_buf)-1)) {
/* unrecognized entry format. skip it. */
continue;
}
if (next-summary < 2) {
/* empty; skip it. */
continue;
}
memcpy(ent_buf, summary, next-summary-1);
ent_buf[next-summary-1] = '\0';
if (tor_sscanf(ent_buf, "%u-%u%c", &low, &high, &dummy) == 2) {
if (low<1 || low>65535 || high<1 || high>65535) {
log_fn(LOG_PROTOCOL_WARN, LD_DIR,"Found bad entry in policy summary %s",
escaped(orig_summary));
return NULL;
}
} else if (tor_sscanf(ent_buf, "%u%c", &low, &dummy) == 1) {
if (low<1 || low>65535) {
log_fn(LOG_PROTOCOL_WARN, LD_DIR,"Found bad entry in policy summary %s",
escaped(orig_summary));
return NULL;
}
high = low;
} else {
log_fn(LOG_PROTOCOL_WARN, LD_DIR,"Found bad entry in policy summary %s",
escaped(orig_summary));
return NULL;
}
entries[n_entries].min_port = low;
entries[n_entries].max_port = high;
n_entries++;
}
if (n_entries == 0) {
log_fn(LOG_PROTOCOL_WARN, LD_DIR,
"Found no port-range entries in summary %s", escaped(orig_summary));
return NULL;
}
{
size_t size = sizeof(short_policy_t) +
sizeof(short_policy_entry_t)*(n_entries-1);
result = tor_malloc_zero(size);
tor_assert( (char*)&result->entries[n_entries-1] < ((char*)result)+size);
}
result->is_accept = is_accept;
result->n_entries = n_entries;
memcpy(result->entries, entries, sizeof(short_policy_entry_t)*n_entries);
return result;
}
/** Release all storage held in <b>policy</b>. */
void
short_policy_free(short_policy_t *policy)
{
tor_free(policy);
}
/** See whether the <b>addr</b>:<b>port</b> address is likely to be accepted
* or rejected by the summarized policy <b>policy</b>. Return values are as
* for compare_tor_addr_to_addr_policy. Unlike the regular addr_policy
* functions, requires the <b>port</b> be specified. */
addr_policy_result_t
compare_tor_addr_to_short_policy(const tor_addr_t *addr, uint16_t port,
const short_policy_t *policy)
{
int i;
int found_match = 0;
int accept;
(void)addr;
tor_assert(port != 0);
if (addr && (tor_addr_is_internal(addr, 0) ||
tor_addr_is_null(addr) ||
tor_addr_is_loopback(addr)))
return ADDR_POLICY_REJECTED;
for (i=0; i < policy->n_entries; ++i) {
const short_policy_entry_t *e = &policy->entries[i];
if (e->min_port <= port && port <= e->max_port) {
found_match = 1;
break;
}
}
if (found_match)
accept = policy->is_accept;
else
accept = ! policy->is_accept;
/* ???? are these right? */
if (accept)
return ADDR_POLICY_PROBABLY_ACCEPTED;
else
return ADDR_POLICY_REJECTED;
}
/** Return true iff <b>policy</b> seems reject all ports */
int
short_policy_is_reject_star(const short_policy_t *policy)
{
/* This doesn't need to be as much on the lookout as policy_is_reject_star,
* since policy summaries are from the consensus or from consensus microdescs.
*/
tor_assert(policy);
/* Check for an exact match of "reject 1-65535". */
return (policy->is_accept == 0 && policy->n_entries == 1 &&
policy->entries[0].min_port == 1 &&
policy->entries[0].max_port == 65535);
}
/** Decides whether addr:port is probably or definitely accepted or rejcted by
* <b>node</b>. See compare_tor_addr_to_addr_policy for details on addr/port
* interpretation. */
addr_policy_result_t
compare_addr_to_node_policy(uint32_t addr, uint16_t port, const node_t *node)
{
tor_addr_t a;
tor_addr_from_ipv4h(&a, addr);
return compare_tor_addr_to_node_policy(&a, port, node);
}
/** Decides whether addr:port is probably or definitely accepted or rejcted by
* <b>node</b>. See compare_tor_addr_to_addr_policy for details on addr/port
* interpretation. */
addr_policy_result_t
compare_tor_addr_to_node_policy(const tor_addr_t *addr, uint16_t port,
const node_t *node)
{
if (node->ri)
return compare_tor_addr_to_addr_policy(addr, port, node->ri->exit_policy);
else if (node->md && node->md) {
if (node->md->exit_policy == NULL)
return ADDR_POLICY_REJECTED;
else
return compare_tor_addr_to_short_policy(addr, port,
node->md->exit_policy);
} else
return ADDR_POLICY_PROBABLY_REJECTED;
}
/** Implementation for GETINFO control command: knows the answer for questions
* about "exit-policy/..." */
int
+16 -2
View File
@@ -19,7 +19,8 @@
int firewall_is_fascist_or(void);
int fascist_firewall_allows_address_or(const tor_addr_t *addr, uint16_t port);
int fascist_firewall_allows_or(routerinfo_t *ri);
int fascist_firewall_allows_or(const routerinfo_t *ri);
int fascist_firewall_allows_node(const node_t *node);
int fascist_firewall_allows_address_dir(const tor_addr_t *addr, uint16_t port);
int dir_policy_permits_address(const tor_addr_t *addr);
int socks_policy_permits_address(const tor_addr_t *addr);
@@ -38,10 +39,16 @@ addr_policy_result_t compare_tor_addr_to_addr_policy(const tor_addr_t *addr,
uint16_t port, const smartlist_t *policy);
addr_policy_result_t compare_addr_to_addr_policy(uint32_t addr,
uint16_t port, const smartlist_t *policy);
addr_policy_result_t compare_addr_to_node_policy(uint32_t addr,
uint16_t port, const node_t *node);
addr_policy_result_t compare_tor_addr_to_node_policy(const tor_addr_t *addr,
uint16_t port, const node_t *node);
int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
int rejectprivate, const char *local_address,
int add_default_policy);
void policies_set_router_exitpolicy_to_reject_all(routerinfo_t *exitrouter);
void policies_set_node_exitpolicy_to_reject_all(node_t *exitrouter);
int exit_policy_is_general_exit(smartlist_t *policy);
int policy_is_reject_star(const smartlist_t *policy);
int getinfo_helper_policies(control_connection_t *conn,
@@ -56,5 +63,12 @@ void policies_free_all(void);
char *policy_summarize(smartlist_t *policy);
short_policy_t *parse_short_policy(const char *summary);
void short_policy_free(short_policy_t *policy);
int short_policy_is_reject_star(const short_policy_t *policy);
addr_policy_result_t compare_tor_addr_to_short_policy(
const tor_addr_t *addr, uint16_t port,
const short_policy_t *policy);
#endif
+8 -6
View File
@@ -24,6 +24,7 @@
#include "main.h"
#include "mempool.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "reasons.h"
#include "relay.h"
@@ -712,7 +713,7 @@ connection_ap_process_end_not_open(
edge_connection_t *conn, crypt_path_t *layer_hint)
{
struct in_addr in;
routerinfo_t *exitrouter;
node_t *exitrouter;
int reason = *(cell->payload+RELAY_HEADER_SIZE);
int control_reason = reason | END_STREAM_REASON_FLAG_REMOTE;
(void) layer_hint; /* unused */
@@ -720,11 +721,12 @@ connection_ap_process_end_not_open(
if (rh->length > 0 && edge_reason_is_retriable(reason) &&
!connection_edge_is_rendezvous_stream(conn) /* avoid retry if rend */
) {
const char *chosen_exit_digest =
circ->build_state->chosen_exit->identity_digest;
log_info(LD_APP,"Address '%s' refused due to '%s'. Considering retrying.",
safe_str(conn->socks_request->address),
stream_end_reason_to_string(reason));
exitrouter =
router_get_by_digest(circ->build_state->chosen_exit->identity_digest);
exitrouter = node_get_mutable_by_id(chosen_exit_digest);
switch (reason) {
case END_STREAM_REASON_EXITPOLICY:
if (rh->length >= 5) {
@@ -759,8 +761,8 @@ connection_ap_process_end_not_open(
log_info(LD_APP,
"Exitrouter '%s' seems to be more restrictive than its exit "
"policy. Not using this router as exit for now.",
exitrouter->nickname);
policies_set_router_exitpolicy_to_reject_all(exitrouter);
node_get_nickname(exitrouter));
policies_set_node_exitpolicy_to_reject_all(exitrouter);
}
/* rewrite it to an IP if we learned one. */
if (addressmap_rewrite(conn->socks_request->address,
@@ -823,7 +825,7 @@ connection_ap_process_end_not_open(
case END_STREAM_REASON_HIBERNATING:
case END_STREAM_REASON_RESOURCELIMIT:
if (exitrouter) {
policies_set_router_exitpolicy_to_reject_all(exitrouter);
policies_set_node_exitpolicy_to_reject_all(exitrouter);
}
if (conn->chosen_exit_optional) {
/* stop wanting a specific exit */
+4 -4
View File
@@ -16,6 +16,7 @@
#include "connection_edge.h"
#include "directory.h"
#include "main.h"
#include "nodelist.h"
#include "relay.h"
#include "rendclient.h"
#include "rendcommon.h"
@@ -738,7 +739,6 @@ rend_client_get_random_intro(const rend_data_t *rend_query)
int i;
rend_cache_entry_t *entry;
rend_intro_point_t *intro;
routerinfo_t *router;
if (rend_cache_lookup_entry(rend_query->onion_address, -1, &entry) < 1) {
log_warn(LD_REND,
@@ -755,8 +755,8 @@ rend_client_get_random_intro(const rend_data_t *rend_query)
intro = smartlist_get(entry->parsed->intro_nodes, i);
/* Do we need to look up the router or is the extend info complete? */
if (!intro->extend_info->onion_key) {
router = router_get_by_nickname(intro->extend_info->nickname, 0);
if (!router) {
const node_t *node = node_get_by_nickname(intro->extend_info->nickname, 0);
if (!node) {
log_info(LD_REND, "Unknown router with nickname '%s'; trying another.",
intro->extend_info->nickname);
rend_intro_point_free(intro);
@@ -764,7 +764,7 @@ rend_client_get_random_intro(const rend_data_t *rend_query)
goto again;
}
extend_info_free(intro->extend_info);
intro->extend_info = extend_info_from_router(router);
intro->extend_info = extend_info_from_node(node);
}
return extend_info_dup(intro->extend_info);
}
+21 -20
View File
@@ -14,6 +14,7 @@
#include "config.h"
#include "directory.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "rendclient.h"
#include "rendcommon.h"
#include "rendservice.h"
@@ -1001,7 +1002,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
} else {
char *rp_nickname;
size_t nickname_field_len;
routerinfo_t *router;
const node_t *node;
int version;
if (*buf == 1) {
rp_nickname = buf+1;
@@ -1028,8 +1029,8 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
len -= nickname_field_len;
len -= rp_nickname - buf; /* also remove header space used by version, if
* any */
router = router_get_by_nickname(rp_nickname, 0);
if (!router) {
node = node_get_by_nickname(rp_nickname, 0);
if (!node) {
log_info(LD_REND, "Couldn't find router %s named in introduce2 cell.",
escaped_safe_str_client(rp_nickname));
/* XXXX Add a no-such-router reason? */
@@ -1037,7 +1038,7 @@ rend_service_introduce(origin_circuit_t *circuit, const char *request,
goto err;
}
extend_info = extend_info_from_router(router);
extend_info = extend_info_from_node(node);
}
if (len != REND_COOKIE_LEN+DH_KEY_LEN) {
@@ -1754,19 +1755,19 @@ void
rend_services_introduce(void)
{
int i,j,r;
routerinfo_t *router;
const node_t *node;
rend_service_t *service;
rend_intro_point_t *intro;
int changed, prev_intro_nodes;
smartlist_t *intro_routers;
smartlist_t *intro_nodes;
time_t now;
or_options_t *options = get_options();
intro_routers = smartlist_create();
intro_nodes = smartlist_create();
now = time(NULL);
for (i=0; i < smartlist_len(rend_service_list); ++i) {
smartlist_clear(intro_routers);
smartlist_clear(intro_nodes);
service = smartlist_get(rend_service_list, i);
tor_assert(service);
@@ -1786,8 +1787,8 @@ rend_services_introduce(void)
service. */
for (j=0; j < smartlist_len(service->intro_nodes); ++j) {
intro = smartlist_get(service->intro_nodes, j);
router = router_get_by_digest(intro->extend_info->identity_digest);
if (!router || !find_intro_circuit(intro, service->pk_digest)) {
node = node_get_by_id(intro->extend_info->identity_digest);
if (!node || !find_intro_circuit(intro, service->pk_digest)) {
log_info(LD_REND,"Giving up on %s as intro point for %s.",
intro->extend_info->nickname, service->service_id);
if (service->desc) {
@@ -1806,8 +1807,8 @@ rend_services_introduce(void)
smartlist_del(service->intro_nodes,j--);
changed = 1;
}
if (router)
smartlist_add(intro_routers, router);
if (node)
smartlist_add(intro_nodes, (void*)node);
}
/* We have enough intro points, and the intro points we thought we had were
@@ -1836,26 +1837,26 @@ rend_services_introduce(void)
#define NUM_INTRO_POINTS_INIT (NUM_INTRO_POINTS + 2)
for (j=prev_intro_nodes; j < (prev_intro_nodes == 0 ?
NUM_INTRO_POINTS_INIT : NUM_INTRO_POINTS); ++j) {
router_crn_flags_t flags = CRN_NEED_UPTIME;
router_crn_flags_t flags = CRN_NEED_UPTIME|CRN_NEED_DESC;
if (get_options()->_AllowInvalid & ALLOW_INVALID_INTRODUCTION)
flags |= CRN_ALLOW_INVALID;
router = router_choose_random_node(intro_routers,
options->ExcludeNodes, flags);
if (!router) {
node = router_choose_random_node(intro_nodes,
options->ExcludeNodes, flags);
if (!node) {
log_warn(LD_REND,
"Could only establish %d introduction points for %s.",
smartlist_len(service->intro_nodes), service->service_id);
break;
}
changed = 1;
smartlist_add(intro_routers, router);
smartlist_add(intro_nodes, (void*)node);
intro = tor_malloc_zero(sizeof(rend_intro_point_t));
intro->extend_info = extend_info_from_router(router);
intro->extend_info = extend_info_from_node(node);
intro->intro_key = crypto_new_pk_env();
tor_assert(!crypto_pk_generate_key(intro->intro_key));
smartlist_add(service->intro_nodes, intro);
log_info(LD_REND, "Picked router %s as an intro point for %s.",
router->nickname, service->service_id);
node_get_nickname(node), service->service_id);
}
/* If there's no need to launch new circuits, stop here. */
@@ -1872,7 +1873,7 @@ rend_services_introduce(void)
}
}
}
smartlist_free(intro_routers);
smartlist_free(intro_nodes);
}
/** Regenerate and upload rendezvous service descriptors for all
+21 -16
View File
@@ -14,6 +14,7 @@
#include "circuitlist.h"
#include "circuituse.h"
#include "config.h"
#include "nodelist.h"
#include "rephist.h"
#include "router.h"
#include "routerlist.h"
@@ -579,7 +580,7 @@ rep_hist_dump_stats(time_t now, int severity)
size_t len;
int ret;
unsigned long upt, downt;
routerinfo_t *r;
const node_t *node;
rep_history_clean(now - get_options()->RephistTrackTime);
@@ -593,8 +594,8 @@ rep_hist_dump_stats(time_t now, int severity)
digestmap_iter_get(orhist_it, &digest1, &or_history_p);
or_history = (or_history_t*) or_history_p;
if ((r = router_get_by_digest(digest1)))
name1 = r->nickname;
if ((node = node_get_by_id(digest1)) && node_get_nickname(node))
name1 = node_get_nickname(node);
else
name1 = "(unknown)";
base16_encode(hexdigest1, sizeof(hexdigest1), digest1, DIGEST_LEN);
@@ -624,8 +625,8 @@ rep_hist_dump_stats(time_t now, int severity)
lhist_it = digestmap_iter_next(or_history->link_history_map,
lhist_it)) {
digestmap_iter_get(lhist_it, &digest2, &link_history_p);
if ((r = router_get_by_digest(digest2)))
name2 = r->nickname;
if ((node = node_get_by_id(digest2)) && node_get_nickname(node))
name2 = node_get_nickname(node);
else
name2 = "(unknown)";
@@ -871,28 +872,32 @@ rep_hist_get_router_stability_doc(time_t now)
}
DIGESTMAP_FOREACH(history_map, id, or_history_t *, hist) {
routerinfo_t *ri;
const node_t *node;
char dbuf[BASE64_DIGEST_LEN+1];
char header_buf[512];
char *info;
digest_to_base64(dbuf, id);
ri = router_get_by_digest(id);
if (ri) {
char *ip = tor_dup_ip(ri->addr);
node = node_get_by_id(id);
if (node) {
char ip[INET_NTOA_BUF_LEN+1];
char tbuf[ISO_TIME_LEN+1];
format_iso_time(tbuf, ri->cache_info.published_on);
time_t published = node_get_published_on(node);
node_get_address_string(node,ip,sizeof(ip));
if (published > 0)
format_iso_time(tbuf, published);
else
strlcpy(tbuf, "???", sizeof(tbuf));
tor_snprintf(header_buf, sizeof(header_buf),
"router %s %s %s\n"
"published %s\n"
"relevant-flags %s%s%s\n"
"declared-uptime %ld\n",
dbuf, ri->nickname, ip,
dbuf, node_get_nickname(node), ip,
tbuf,
ri->is_running ? "Running " : "",
ri->is_valid ? "Valid " : "",
ri->is_hibernating ? "Hibernating " : "",
ri->uptime);
tor_free(ip);
node->is_running ? "Running " : "",
node->is_valid ? "Valid " : "",
node->ri && node->ri->is_hibernating ? "Hibernating " : "",
node_get_declared_uptime(node));
} else {
tor_snprintf(header_buf, sizeof(header_buf),
"router %s {no descriptor}\n", dbuf);
+32 -24
View File
@@ -7,6 +7,7 @@
#define ROUTER_PRIVATE
#include "or.h"
#include "circuitbuild.h"
#include "circuitlist.h"
#include "circuituse.h"
#include "config.h"
@@ -19,6 +20,7 @@
#include "hibernate.h"
#include "main.h"
#include "networkstatus.h"
#include "nodelist.h"
#include "policies.h"
#include "relay.h"
#include "rephist.h"
@@ -773,18 +775,21 @@ decide_to_advertise_dirport(or_options_t *options, uint16_t dir_port)
void
consider_testing_reachability(int test_or, int test_dir)
{
routerinfo_t *me = router_get_my_routerinfo();
const routerinfo_t *me = router_get_my_routerinfo();
int orport_reachable = check_whether_orport_reachable();
tor_addr_t addr;
if (!me)
return;
if (test_or && (!orport_reachable || !circuit_enough_testing_circs())) {
extend_info_t *ei;
log_info(LD_CIRC, "Testing %s of my ORPort: %s:%d.",
!orport_reachable ? "reachability" : "bandwidth",
me->address, me->or_port);
circuit_launch_by_router(CIRCUIT_PURPOSE_TESTING, me,
CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
ei = extend_info_from_router(me);
circuit_launch_by_extend_info(CIRCUIT_PURPOSE_TESTING, ei,
CIRCLAUNCH_NEED_CAPACITY|CIRCLAUNCH_IS_INTERNAL);
extend_info_free(ei);
}
tor_addr_from_ipv4h(&addr, me->addr);
@@ -808,7 +813,7 @@ void
router_orport_found_reachable(void)
{
if (!can_reach_or_port) {
routerinfo_t *me = router_get_my_routerinfo();
const routerinfo_t *me = router_get_my_routerinfo();
log_notice(LD_OR,"Self-testing indicates your ORPort is reachable from "
"the outside. Excellent.%s",
get_options()->_PublishServerDescriptor != NO_AUTHORITY ?
@@ -831,7 +836,7 @@ void
router_dirport_found_reachable(void)
{
if (!can_reach_dir_port) {
routerinfo_t *me = router_get_my_routerinfo();
const routerinfo_t *me = router_get_my_routerinfo();
log_notice(LD_DIRSERV,"Self-testing indicates your DirPort is reachable "
"from the outside. Excellent.");
can_reach_dir_port = 1;
@@ -1093,7 +1098,7 @@ static int desc_needs_upload = 0;
void
router_upload_dir_desc_to_dirservers(int force)
{
routerinfo_t *ri;
const routerinfo_t *ri;
extrainfo_t *ei;
char *msg;
size_t desc_len, extra_len = 0, total_len;
@@ -1186,7 +1191,7 @@ router_extrainfo_digest_is_me(const char *digest)
/** A wrapper around router_digest_is_me(). */
int
router_is_me(routerinfo_t *router)
router_is_me(const routerinfo_t *router)
{
return router_digest_is_me(router->cache_info.identity_digest);
}
@@ -1205,7 +1210,7 @@ router_fingerprint_is_me(const char *fp)
/** Return a routerinfo for this OR, rebuilding a fresh one if
* necessary. Return NULL on error, or if called on an OP. */
routerinfo_t *
const routerinfo_t *
router_get_my_routerinfo(void)
{
if (!server_mode(get_options()))
@@ -1333,13 +1338,12 @@ router_rebuild_descriptor(int force)
ri->policy_is_reject_star =
policy_is_reject_star(ri->exit_policy);
if (desc_routerinfo) { /* inherit values */
ri->is_valid = desc_routerinfo->is_valid;
ri->is_running = desc_routerinfo->is_running;
ri->is_named = desc_routerinfo->is_named;
}
#if 0
/* XXXX NM NM I belive this is safe to remove */
if (authdir_mode(options))
ri->is_valid = ri->is_named = 1; /* believe in yourself */
#endif
if (options->MyFamily) {
smartlist_t *family;
if (!warned_nonexistent_family)
@@ -1348,13 +1352,12 @@ router_rebuild_descriptor(int force)
ri->declared_family = smartlist_create();
smartlist_split_string(family, options->MyFamily, ",",
SPLIT_SKIP_SPACE|SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
SMARTLIST_FOREACH(family, char *, name,
{
routerinfo_t *member;
SMARTLIST_FOREACH_BEGIN(family, char *, name) {
const node_t *member;
if (!strcasecmp(name, options->Nickname))
member = ri;
goto skip; /* Don't list ourself, that's redundant */
else
member = router_get_by_nickname(name, 1);
member = node_get_by_nickname(name, 1);
if (!member) {
int is_legal = is_legal_nickname_or_hexdigest(name);
if (!smartlist_string_isin(warned_nonexistent_family, name) &&
@@ -1374,19 +1377,21 @@ router_rebuild_descriptor(int force)
smartlist_add(ri->declared_family, name);
name = NULL;
}
} else if (router_is_me(member)) {
} else if (router_digest_is_me(member->identity)) {
/* Don't list ourself in our own family; that's redundant */
/* XXX shouldn't be possible */
} else {
char *fp = tor_malloc(HEX_DIGEST_LEN+2);
fp[0] = '$';
base16_encode(fp+1,HEX_DIGEST_LEN+1,
member->cache_info.identity_digest, DIGEST_LEN);
member->identity, DIGEST_LEN);
smartlist_add(ri->declared_family, fp);
if (smartlist_string_isin(warned_nonexistent_family, name))
smartlist_string_remove(warned_nonexistent_family, name);
}
skip:
tor_free(name);
});
} SMARTLIST_FOREACH_END(name);
/* remove duplicates from the list */
smartlist_sort_strings(ri->declared_family);
@@ -1444,8 +1449,6 @@ router_rebuild_descriptor(int force)
strlen(ri->cache_info.signed_descriptor_body),
ri->cache_info.signed_descriptor_digest);
routerinfo_set_country(ri);
tor_assert(! routerinfo_incompatible_with_extrainfo(ri, ei, NULL, NULL));
routerinfo_free(desc_routerinfo);
@@ -2099,10 +2102,15 @@ is_legal_hexdigest(const char *s)
void
router_get_verbose_nickname(char *buf, const routerinfo_t *router)
{
const char *good_digest = networkstatus_get_router_digest_by_nickname(
router->nickname);
int is_named = good_digest && !memcmp(good_digest,
router->cache_info.identity_digest,
DIGEST_LEN);
buf[0] = '$';
base16_encode(buf+1, HEX_DIGEST_LEN+1, router->cache_info.identity_digest,
DIGEST_LEN);
buf[1+HEX_DIGEST_LEN] = router->is_named ? '=' : '~';
buf[1+HEX_DIGEST_LEN] = is_named ? '=' : '~';
strlcpy(buf+1+HEX_DIGEST_LEN+1, router->nickname, MAX_NICKNAME_LEN+1);
}
+2 -2
View File
@@ -62,12 +62,12 @@ void router_new_address_suggestion(const char *suggestion,
const dir_connection_t *d_conn);
int router_compare_to_my_exit_policy(edge_connection_t *conn);
int router_my_exit_policy_is_reject_star(void);
routerinfo_t *router_get_my_routerinfo(void);
const routerinfo_t *router_get_my_routerinfo(void);
extrainfo_t *router_get_my_extrainfo(void);
const char *router_get_my_descriptor(void);
int router_digest_is_me(const char *digest);
int router_extrainfo_digest_is_me(const char *digest);
int router_is_me(routerinfo_t *router);
int router_is_me(const routerinfo_t *router);
int router_fingerprint_is_me(const char *fp);
int router_pick_published_address(or_options_t *options, uint32_t *addr);
int router_rebuild_descriptor(int force);
+534 -430
View File
File diff suppressed because it is too large Load Diff
+48 -40
View File
@@ -27,37 +27,34 @@ int router_reload_router_list(void);
int authority_cert_dl_looks_uncertain(const char *id_digest);
smartlist_t *router_get_trusted_dir_servers(void);
routerstatus_t *router_pick_directory_server(authority_type_t type, int flags);
const routerstatus_t *router_pick_directory_server(authority_type_t type,
int flags);
trusted_dir_server_t *router_get_trusteddirserver_by_digest(const char *d);
trusted_dir_server_t *trusteddirserver_get_by_v3_auth_digest(const char *d);
routerstatus_t *router_pick_trusteddirserver(authority_type_t type, int flags);
const routerstatus_t *router_pick_trusteddirserver(authority_type_t type,
int flags);
int router_get_my_share_of_directory_requests(double *v2_share_out,
double *v3_share_out);
void router_reset_status_download_failures(void);
void routerlist_add_family(smartlist_t *sl, routerinfo_t *router);
int routers_in_same_family(routerinfo_t *r1, routerinfo_t *r2);
void routerlist_add_family(smartlist_t *sl, const routerinfo_t *router);
int routers_have_same_or_addr(const routerinfo_t *r1, const routerinfo_t *r2);
void add_nickname_list_to_smartlist(smartlist_t *sl, const char *list,
int must_be_running);
int router_nickname_is_in_list(routerinfo_t *router, const char *list);
routerinfo_t *routerlist_find_my_routerinfo(void);
routerinfo_t *router_find_exact_exit_enclave(const char *address,
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,
uint16_t port);
int router_is_unreliable(routerinfo_t *router, int need_uptime,
int node_is_unreliable(const node_t *router, int need_uptime,
int need_capacity, int need_guard);
uint32_t router_get_advertised_bandwidth(routerinfo_t *router);
uint32_t router_get_advertised_bandwidth_capped(routerinfo_t *router);
uint32_t router_get_advertised_bandwidth(const routerinfo_t *router);
uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router);
routerinfo_t *routerlist_sl_choose_by_bandwidth(smartlist_t *sl,
bandwidth_weight_rule_t rule);
routerstatus_t *routerstatus_sl_choose_by_bandwidth(smartlist_t *sl,
bandwidth_weight_rule_t rule);
const node_t *node_sl_choose_by_bandwidth(smartlist_t *sl,
bandwidth_weight_rule_t rule);
routerinfo_t *router_choose_random_node(smartlist_t *excludedsmartlist,
const node_t *router_choose_random_node(smartlist_t *excludedsmartlist,
struct routerset_t *excludedset,
router_crn_flags_t flags);
routerinfo_t *router_get_by_nickname(const char *nickname,
const routerinfo_t *router_get_by_nickname(const char *nickname,
int warn_if_unnamed);
int router_digest_version_as_new_as(const char *digest, const char *cutoff);
int router_digest_is_trusted_dir_type(const char *digest,
@@ -67,13 +64,14 @@ int router_digest_is_trusted_dir_type(const char *digest,
int router_addr_is_trusted_dir(uint32_t addr);
int hexdigest_to_digest(const char *hexdigest, char *digest);
routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
routerinfo_t *router_get_by_digest(const char *digest);
const routerinfo_t *router_get_by_hexdigest(const char *hexdigest);
const routerinfo_t *router_get_by_digest(const char *digest);
routerinfo_t *router_get_mutable_by_digest(const char *digest);
signed_descriptor_t *router_get_by_descriptor_digest(const char *digest);
signed_descriptor_t *router_get_by_extrainfo_digest(const char *digest);
signed_descriptor_t *extrainfo_get_by_descriptor_digest(const char *digest);
const char *signed_descriptor_get_body(signed_descriptor_t *desc);
const char *signed_descriptor_get_annotations(signed_descriptor_t *desc);
const char *signed_descriptor_get_body(const signed_descriptor_t *desc);
const char *signed_descriptor_get_annotations(const signed_descriptor_t *desc);
routerlist_t *router_get_routerlist(void);
void routerinfo_free(routerinfo_t *router);
void extrainfo_free(extrainfo_t *extrainfo);
@@ -132,9 +130,10 @@ void router_load_extrainfo_from_string(const char *s, const char *eos,
int descriptor_digests);
void routerlist_retry_directory_downloads(time_t now);
int router_exit_policy_all_routers_reject(uint32_t addr, uint16_t port,
int need_uptime);
int router_exit_policy_rejects_all(routerinfo_t *router);
int router_exit_policy_all_nodes_reject(uint32_t addr, uint16_t port,
int need_uptime);
int router_exit_policy_rejects_all(const routerinfo_t *router);
trusted_dir_server_t *add_trusted_dir_server(const char *nickname,
const char *address,
uint16_t dir_port, uint16_t or_port,
@@ -152,39 +151,43 @@ void router_dir_info_changed(void);
const char *get_dir_info_status_string(void);
int count_loading_descriptors_progress(void);
void router_reset_descriptor_download_failures(void);
int router_differences_are_cosmetic(routerinfo_t *r1, routerinfo_t *r2);
int routerinfo_incompatible_with_extrainfo(routerinfo_t *ri, extrainfo_t *ei,
int router_differences_are_cosmetic(const routerinfo_t *r1,
const routerinfo_t *r2);
int routerinfo_incompatible_with_extrainfo(const routerinfo_t *ri,
extrainfo_t *ei,
signed_descriptor_t *sd,
const char **msg);
void routerlist_assert_ok(routerlist_t *rl);
const char *esc_router_info(routerinfo_t *router);
void routerlist_assert_ok(const routerlist_t *rl);
const char *esc_router_info(const routerinfo_t *router);
void routers_sort_by_identity(smartlist_t *routers);
routerset_t *routerset_new(void);
void routerset_refresh_countries(routerset_t *rs);
int routerset_parse(routerset_t *target, const char *s,
const char *description);
void routerset_union(routerset_t *target, const routerset_t *source);
int routerset_is_list(const routerset_t *set);
int routerset_needs_geoip(const routerset_t *set);
int routerset_contains_router(const routerset_t *set, routerinfo_t *ri);
int routerset_contains_router(const routerset_t *set, const routerinfo_t *ri,
country_t country);
int routerset_contains_routerstatus(const routerset_t *set,
routerstatus_t *rs);
const routerstatus_t *rs,
country_t country);
int routerset_contains_extendinfo(const routerset_t *set,
const extend_info_t *ei);
void routerset_get_all_routers(smartlist_t *out, const routerset_t *routerset,
int running_only);
void routersets_get_disjunction(smartlist_t *target, const smartlist_t *source,
int routerset_contains_node(const routerset_t *set, const node_t *node);
void routerset_get_all_nodes(smartlist_t *out, const routerset_t *routerset,
int running_only);
void routersets_get_node_disjunction(smartlist_t *target,
const smartlist_t *source,
const routerset_t *include,
const routerset_t *exclude, int running_only);
void routerset_subtract_routers(smartlist_t *out,
const routerset_t *routerset);
void routerset_subtract_nodes(smartlist_t *out,
const routerset_t *routerset);
char *routerset_to_string(const routerset_t *routerset);
void routerset_refresh_countries(routerset_t *target);
int routerset_equal(const routerset_t *old, const routerset_t *new);
void routerset_free(routerset_t *routerset);
void routerinfo_set_country(routerinfo_t *ri);
void routerlist_refresh_countries(void);
void refresh_all_country_info(void);
int hid_serv_get_responsible_directories(smartlist_t *responsible_dirs,
@@ -195,8 +198,13 @@ int hid_serv_responsible_for_desc_id(const char *id);
void list_pending_microdesc_downloads(digestmap_t *result);
void launch_descriptor_downloads(int purpose,
smartlist_t *downloadable,
routerstatus_t *source,
const routerstatus_t *source,
time_t now);
int hex_digest_nickname_decode(const char *hexdigest,
char *digest_out,
char *nickname_qualifier_out,
char *nickname_out);
#endif
+2 -5
View File
@@ -1344,7 +1344,6 @@ router_parse_entry_from_string(const char *s, const char *end,
tor_assert(tok->n_args >= 5);
router = tor_malloc_zero(sizeof(routerinfo_t));
router->country = -1;
router->cache_info.routerlist_index = -1;
router->cache_info.annotations_len = s-start_of_annotations + prepend_len;
router->cache_info.signed_descriptor_len = end-s;
@@ -1543,8 +1542,6 @@ router_parse_entry_from_string(const char *s, const char *end,
"router descriptor") < 0)
goto err;
routerinfo_set_country(router);
if (!router->or_port) {
log_warn(LD_DIR,"or_port unreadable or 0. Failing.");
goto err;
@@ -2030,7 +2027,7 @@ routerstatus_parse_entry_from_string(memarea_t *area,
else if (!strcmp(tok->args[i], "Fast"))
rs->is_fast = 1;
else if (!strcmp(tok->args[i], "Running"))
rs->is_running = 1;
rs->is_flagged_running = 1;
else if (!strcmp(tok->args[i], "Named"))
rs->is_named = 1;
else if (!strcmp(tok->args[i], "Valid"))
@@ -4305,7 +4302,7 @@ microdescs_parse_from_string(const char *s, const char *eos,
}
if ((tok = find_opt_by_keyword(tokens, K_P))) {
md->exitsummary = tor_strdup(tok->args[0]);
md->exit_policy = parse_short_policy(tok->args[0]);
}
crypto_digest256(md->digest, md->body, md->bodylen, DIGEST_SHA256);
+5
View File
@@ -576,6 +576,7 @@ test_policy_summary_helper(const char *policy_str,
smartlist_t *policy = smartlist_create();
char *summary = NULL;
int r;
short_policy_t *short_policy = NULL;
line.key = (char*)"foo";
line.value = (char *)policy_str;
@@ -588,10 +589,14 @@ test_policy_summary_helper(const char *policy_str,
test_assert(summary != NULL);
test_streq(summary, expected_summary);
short_policy = parse_short_policy(summary);
tt_assert(short_policy);
done:
tor_free(summary);
if (policy)
addr_policy_list_free(policy);
short_policy_free(short_policy);
}
/** Run unit tests for generating summary lines of exit policies */
+7 -5
View File
@@ -801,7 +801,7 @@ test_dir_v3_networkstatus(void)
rs->or_port = 443;
rs->dir_port = 8000;
/* all flags but running cleared */
rs->is_running = 1;
rs->is_flagged_running = 1;
smartlist_add(vote->routerstatus_list, vrs);
test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
@@ -816,7 +816,7 @@ test_dir_v3_networkstatus(void)
rs->addr = 0x99009901;
rs->or_port = 443;
rs->dir_port = 0;
rs->is_exit = rs->is_stable = rs->is_fast = rs->is_running =
rs->is_exit = rs->is_stable = rs->is_fast = rs->is_flagged_running =
rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
smartlist_add(vote->routerstatus_list, vrs);
test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
@@ -833,7 +833,8 @@ test_dir_v3_networkstatus(void)
rs->or_port = 400;
rs->dir_port = 9999;
rs->is_authority = rs->is_exit = rs->is_stable = rs->is_fast =
rs->is_running = rs->is_valid = rs->is_v2_dir = rs->is_possible_guard = 1;
rs->is_flagged_running = rs->is_valid = rs->is_v2_dir =
rs->is_possible_guard = 1;
smartlist_add(vote->routerstatus_list, vrs);
test_assert(router_add_to_routerlist(generate_ri_from_rs(vrs), &msg,0,0)>=0);
@@ -1073,7 +1074,8 @@ test_dir_v3_networkstatus(void)
test_assert(!rs->is_fast);
test_assert(!rs->is_possible_guard);
test_assert(!rs->is_stable);
test_assert(rs->is_running); /* If it wasn't running it wouldn't be here */
/* (If it wasn't running it wouldn't be here) */
test_assert(rs->is_flagged_running);
test_assert(!rs->is_v2_dir);
test_assert(!rs->is_valid);
test_assert(!rs->is_named);
@@ -1095,7 +1097,7 @@ test_dir_v3_networkstatus(void)
test_assert(rs->is_fast);
test_assert(rs->is_possible_guard);
test_assert(rs->is_stable);
test_assert(rs->is_running);
test_assert(rs->is_flagged_running);
test_assert(rs->is_v2_dir);
test_assert(rs->is_valid);
test_assert(!rs->is_named);