mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-28 14:23:30 +01:00
Implement "families" of coadministered nodes; prevent them all from appearing on the same circuit.
svn:r2523
This commit is contained in:
parent
e448879e3c
commit
7fa5d224d4
@ -1080,16 +1080,16 @@ static routerinfo_t *choose_good_middle_server(cpath_build_state_t *state,
|
||||
excluded = smartlist_create();
|
||||
if((r = router_get_by_digest(state->chosen_exit_digest))) {
|
||||
smartlist_add(excluded, r);
|
||||
routerlist_add_friends(excluded, r);
|
||||
routerlist_add_family(excluded, r);
|
||||
}
|
||||
if((r = routerlist_find_my_routerinfo())) {
|
||||
smartlist_add(excluded, r);
|
||||
routerlist_add_friends(excluded, r);
|
||||
routerlist_add_family(excluded, r);
|
||||
}
|
||||
for (i = 0, cpath = head; i < cur_len; ++i, cpath=cpath->next) {
|
||||
if((r = router_get_by_digest(cpath->identity_digest))) {
|
||||
smartlist_add(excluded, r);
|
||||
routerlist_add_friends(excluded, r);
|
||||
routerlist_add_family(excluded, r);
|
||||
}
|
||||
}
|
||||
choice = router_choose_random_node("", options.ExcludeNodes, excluded,
|
||||
@ -1106,11 +1106,11 @@ static routerinfo_t *choose_good_entry_server(cpath_build_state_t *state)
|
||||
|
||||
if((r = router_get_by_digest(state->chosen_exit_digest))) {
|
||||
smartlist_add(excluded, r);
|
||||
routerlist_add_friends(excluded, r);
|
||||
routerlist_add_family(excluded, r);
|
||||
}
|
||||
if((r = routerlist_find_my_routerinfo())) {
|
||||
smartlist_add(excluded, r);
|
||||
routerlist_add_friends(excluded, r);
|
||||
routerlist_add_family(excluded, r);
|
||||
}
|
||||
if(options.FascistFirewall) {
|
||||
/* exclude all ORs that listen on the wrong port */
|
||||
|
@ -244,6 +244,7 @@ config_assign(or_options_t *options, struct config_line_t *list)
|
||||
|
||||
config_compare(list, "FascistFirewall",CONFIG_TYPE_BOOL, &options->FascistFirewall) ||
|
||||
config_compare(list, "FirewallPorts",CONFIG_TYPE_CSV, &options->FirewallPorts) ||
|
||||
config_compare(list, "MyFamily", CONFIG_TYPE_STRING, &options->MyFamily) ||
|
||||
|
||||
config_compare(list, "Group", CONFIG_TYPE_STRING, &options->Group) ||
|
||||
|
||||
@ -517,6 +518,7 @@ init_options(or_options_t *options)
|
||||
options->RendConfigLines = NULL;
|
||||
options->FirewallPorts = NULL;
|
||||
options->DirServers = NULL;
|
||||
options->MyFamily = NULL;
|
||||
}
|
||||
|
||||
static char *
|
||||
@ -554,6 +556,30 @@ get_default_conf_file(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Verify whether lst is a string containing valid-looking space-separated
|
||||
* nicknames, or NULL. Return 0 on success. Warn and return -1 on failure.
|
||||
*/
|
||||
static int check_nickname_list(const char *lst, const char *name)
|
||||
{
|
||||
int r = 0;
|
||||
smartlist_t *sl;
|
||||
|
||||
if (!lst)
|
||||
return 0;
|
||||
sl = smartlist_create();
|
||||
smartlist_split_string(sl, lst, ",", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
SMARTLIST_FOREACH(sl, const char *, s,
|
||||
{
|
||||
if (!is_legal_nickname_or_hexdigest(s)) {
|
||||
log_fn(LOG_WARN, "Invalid nickname '%s' in %s line", s, name);
|
||||
r = -1;
|
||||
}
|
||||
});
|
||||
SMARTLIST_FOREACH(sl, char *, s, tor_free(s));
|
||||
smartlist_free(sl);
|
||||
return r;
|
||||
}
|
||||
|
||||
/** Read a configuration file into <b>options</b>, finding the configuration
|
||||
* file location based on the command line. After loading the options,
|
||||
* validate them for consistency. Return 0 if success, <0 if failure. */
|
||||
@ -838,6 +864,19 @@ getconfig(int argc, char **argv, or_options_t *options)
|
||||
}
|
||||
}
|
||||
|
||||
if (check_nickname_list(options->ExitNodes, "ExitNodes"))
|
||||
return -1;
|
||||
if (check_nickname_list(options->EntryNodes, "EntryNodes"))
|
||||
return -1;
|
||||
if (check_nickname_list(options->ExcludeNodes, "ExcludeNodes"))
|
||||
return -1;
|
||||
if (check_nickname_list(options->RendNodes, "RendNodes"))
|
||||
return -1;
|
||||
if (check_nickname_list(options->RendNodes, "RendExcludeNodes"))
|
||||
return -1;
|
||||
if (check_nickname_list(options->MyFamily, "MyFamily"))
|
||||
return -1;
|
||||
|
||||
clear_trusted_dir_servers();
|
||||
if (!options->DirServers) {
|
||||
add_default_trusted_dirservers();
|
||||
@ -848,10 +887,6 @@ getconfig(int argc, char **argv, or_options_t *options)
|
||||
}
|
||||
}
|
||||
|
||||
/* XXX look at the various nicknamelists and make sure they're
|
||||
* valid and don't have hostnames that are too long.
|
||||
*/
|
||||
|
||||
if (rend_config_services(options) < 0) {
|
||||
result = -1;
|
||||
}
|
||||
|
@ -597,6 +597,8 @@ typedef struct {
|
||||
int is_verified; /**< Has a trusted dirserver validated this OR? */
|
||||
int is_trusted_dir; /**< Do we trust this OR as a directory server? */
|
||||
|
||||
smartlist_t *declared_family; /**< Nicknames of router which this router
|
||||
* claims are its family. */
|
||||
} routerinfo_t;
|
||||
|
||||
/** Contents of a directory of onion routers. */
|
||||
@ -890,8 +892,6 @@ typedef struct {
|
||||
int NumCpus; /**< How many CPUs should we try to use? */
|
||||
int RunTesting; /**< If true, create testing circuits to measure how well the
|
||||
* other ORs are running. */
|
||||
struct config_line_t *TrustedDirs; /**< List of fingerprints of keys that are
|
||||
allowed to sign directories. */
|
||||
struct config_line_t *RendConfigLines; /**< List of configuration lines
|
||||
* for rendezvous services. */
|
||||
char *ContactInfo; /**< Contact info to be published in the directory */
|
||||
@ -902,6 +902,7 @@ typedef struct {
|
||||
|
||||
struct config_line_t *DirServers; /**< List of configuration lines
|
||||
* for directory servers. */
|
||||
char *MyFamily; /**< Declared family for this OR. */
|
||||
} or_options_t;
|
||||
|
||||
/* XXX are these good enough defaults? */
|
||||
@ -1415,7 +1416,7 @@ routerinfo_t *router_pick_directory_server(int requireothers);
|
||||
trusted_dir_server_t *router_pick_trusteddirserver(int requireothers);
|
||||
int all_trusted_directory_servers_down(void);
|
||||
struct smartlist_t;
|
||||
void routerlist_add_friends(struct smartlist_t *sl, routerinfo_t *router);
|
||||
void routerlist_add_family(struct smartlist_t *sl, routerinfo_t *router);
|
||||
void add_nickname_list_to_smartlist(struct smartlist_t *sl, const char *list, int warn_if_down);
|
||||
routerinfo_t *routerlist_find_my_routerinfo(void);
|
||||
int router_nickname_matches(routerinfo_t *router, const char *nickname);
|
||||
|
@ -552,6 +552,13 @@ int router_rebuild_descriptor(void) {
|
||||
ri->is_trusted_dir = authdir_mode();
|
||||
if(desc_routerinfo) /* inherit values */
|
||||
ri->is_verified = desc_routerinfo->is_verified;
|
||||
if (options.MyFamily) {
|
||||
ri->declared_family = smartlist_create();
|
||||
smartlist_split_string(ri->declared_family, options.MyFamily, ",",
|
||||
SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0);
|
||||
} else {
|
||||
ri->declared_family = NULL;
|
||||
}
|
||||
|
||||
if (desc_routerinfo)
|
||||
routerinfo_free(desc_routerinfo);
|
||||
@ -600,6 +607,7 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
||||
int result=0;
|
||||
struct exit_policy_t *tmpe;
|
||||
char *bandwidth_usage;
|
||||
char *family_line;
|
||||
#ifdef DEBUG_ROUTER_DUMP_ROUTER_TO_STRING
|
||||
char *s_tmp, *s_dup;
|
||||
const char *cp;
|
||||
@ -639,6 +647,16 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
||||
/* How busy have we been? */
|
||||
bandwidth_usage = rep_hist_get_bandwidth_lines();
|
||||
|
||||
if (router->declared_family && smartlist_len(router->declared_family)) {
|
||||
char *s = smartlist_join_strings(router->declared_family, " ", 0);
|
||||
size_t n = strlen(s) + strlen("opt family ") + 2; /* 1 for \n, 1 for \0. */
|
||||
family_line = tor_malloc(n);
|
||||
snprintf(family_line, n, "opt family %s\n", s);
|
||||
tor_free(s);
|
||||
} else {
|
||||
family_line = tor_strdup("");
|
||||
}
|
||||
|
||||
/* Generate the easy portion of the router descriptor. */
|
||||
result = snprintf(s, maxlen,
|
||||
"router %s %s %d %d %d\n"
|
||||
@ -648,7 +666,7 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
||||
"opt uptime %ld\n"
|
||||
"bandwidth %d %d %d\n"
|
||||
"onion-key\n%s"
|
||||
"signing-key\n%s%s",
|
||||
"signing-key\n%s%s%s",
|
||||
router->nickname,
|
||||
router->address,
|
||||
router->or_port,
|
||||
@ -665,7 +683,7 @@ int router_dump_router_to_string(char *s, size_t maxlen, routerinfo_t *router,
|
||||
(int) router->bandwidthburst,
|
||||
(int) router->bandwidthcapacity,
|
||||
onion_pkey, identity_pkey,
|
||||
bandwidth_usage);
|
||||
family_line, bandwidth_usage);
|
||||
|
||||
tor_free(onion_pkey);
|
||||
tor_free(identity_pkey);
|
||||
|
@ -225,11 +225,28 @@ int all_trusted_directory_servers_down(void) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/** Add all the friends of <b>router</b> to the smartlist <b>sl</b>.
|
||||
/** Add all the family of <b>router</b> to the smartlist <b>sl</b>.
|
||||
*/
|
||||
void routerlist_add_friends(smartlist_t *sl, routerinfo_t *router) {
|
||||
void routerlist_add_family(smartlist_t *sl, routerinfo_t *router) {
|
||||
routerinfo_t *r;
|
||||
|
||||
if (!router->declared_family)
|
||||
return;
|
||||
|
||||
/* Add every r such that router declares familyhip with r, and r
|
||||
* declares familyhip with router. */
|
||||
SMARTLIST_FOREACH(router->declared_family, const char *, n,
|
||||
{
|
||||
if (!(r = router_get_by_nickname(n)))
|
||||
continue;
|
||||
if (!r->declared_family)
|
||||
continue;
|
||||
SMARTLIST_FOREACH(r->declared_family, const char *, n2,
|
||||
{
|
||||
if (router_nickname_matches(router, n2))
|
||||
smartlist_add(sl, r);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** Given a comma-and-whitespace separated list of nicknames, see which
|
||||
@ -583,6 +600,10 @@ void routerinfo_free(routerinfo_t *router)
|
||||
crypto_free_pk_env(router->onion_pkey);
|
||||
if (router->identity_pkey)
|
||||
crypto_free_pk_env(router->identity_pkey);
|
||||
if (router->declared_family) {
|
||||
SMARTLIST_FOREACH(router->declared_family, char *, s, tor_free(s));
|
||||
smartlist_free(router->declared_family);
|
||||
}
|
||||
exit_policy_free(router->exit_policy);
|
||||
tor_free(router);
|
||||
}
|
||||
@ -611,6 +632,11 @@ routerinfo_t *routerinfo_copy(const routerinfo_t *router)
|
||||
(*e)->string = tor_strdup((*e)->string);
|
||||
e = & ((*e)->next);
|
||||
}
|
||||
if (r->declared_family) {
|
||||
r->declared_family = smartlist_create();
|
||||
SMARTLIST_FOREACH(router->declared_family, const char *, s,
|
||||
smartlist_add(r->declared_family, tor_strdup(s)));
|
||||
}
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -41,6 +41,7 @@ typedef enum {
|
||||
K_NETWORK_STATUS,
|
||||
K_UPTIME,
|
||||
K_DIR_SIGNING_KEY,
|
||||
K_FAMILY,
|
||||
_UNRECOGNIZED,
|
||||
_ERR,
|
||||
_EOF,
|
||||
@ -115,6 +116,7 @@ static struct {
|
||||
{ "network-status", K_NETWORK_STATUS, NO_ARGS, NO_OBJ, DIR_ONLY },
|
||||
{ "uptime", K_UPTIME, ARGS, NO_OBJ, RTR_ONLY },
|
||||
{ "dir-signing-key", K_DIR_SIGNING_KEY, ARGS, OBJ_OK, DIR_ONLY },
|
||||
{ "family", K_FAMILY, ARGS, NO_OBJ, RTR_ONLY },
|
||||
{ NULL, -1, NO_ARGS, NO_OBJ, ANY }
|
||||
};
|
||||
|
||||
@ -769,6 +771,7 @@ routerinfo_t *router_parse_entry_from_string(const char *s,
|
||||
|
||||
router = tor_malloc_zero(sizeof(routerinfo_t));
|
||||
router->onion_pkey = router->identity_pkey = NULL;
|
||||
router->declared_family = NULL;
|
||||
ports_set = bw_set = 0;
|
||||
|
||||
if (tok->n_args == 2 || tok->n_args == 5 || tok->n_args == 6) {
|
||||
@ -876,6 +879,19 @@ routerinfo_t *router_parse_entry_from_string(const char *s,
|
||||
log_fn(LOG_WARN,"Error in exit policy"); goto err;}
|
||||
);
|
||||
|
||||
|
||||
if ((tok = find_first_by_keyword(tokens, K_FAMILY)) && tok->n_args) {
|
||||
int i;
|
||||
router->declared_family = smartlist_create();
|
||||
for (i=0;i<tok->n_args;++i) {
|
||||
if (!is_legal_nickname_or_hexdigest(tok->args[i])) {
|
||||
log_fn(LOG_WARN, "Illegal nickname %s in family line", tok->args[i]);
|
||||
goto err;
|
||||
}
|
||||
smartlist_add(router->declared_family, tor_strdup(tok->args[i]));
|
||||
}
|
||||
}
|
||||
|
||||
if (!(tok = find_first_by_keyword(tokens, K_ROUTER_SIGNATURE))) {
|
||||
log_fn(LOG_WARN, "Missing router signature"); goto err;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user