From 416653271a7505e7a219240eaeeb379d4d22afac Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Sun, 15 Aug 2004 20:14:44 +0000 Subject: Implement strict{entry|exit}nodes config options svn:r2236 --- doc/tor.1.in | 8 ++++++++ src/or/circuitbuild.c | 15 +++++++++------ src/or/config.c | 11 +++++++++++ src/or/or.h | 7 ++++++- src/or/routerlist.c | 13 ++++++++----- 5 files changed, 42 insertions(+), 12 deletions(-) diff --git a/doc/tor.1.in b/doc/tor.1.in index 59b2f02a7..254c333d0 100644 --- a/doc/tor.1.in +++ b/doc/tor.1.in @@ -72,6 +72,14 @@ A list of preferred nodes to use for the last hop in the circuit, if possible. \fBexcludenodes \fR\fInickname,nickname,...\fP A list of nodes to never use when building a circuit. .TP +\fBstrictexitnodes \fR\fI0|1\fP +If 1, Tor will never use any nodes besides those listed in "exitnodes" for +the last hop of a circuit. +.TP +\fBstrictentrynodes \fR\fI0|1\fP +If 1, Tor will never use any nodes besides those listed in "entrynodes" for +the first hop of a circuit. +.TP \fBnewcircuitperiod \fR\fINUM\fP Every NUM seconds consider whether to build a new circuit. (Default: 60) .TP diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 66210fe89..1b41fd507 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -897,7 +897,7 @@ static routerinfo_t *choose_good_exit_server_general(routerlist_t *dir) smartlist_add(sl, smartlist_get(dir->routers, i)); smartlist_subtract(sl,excludedexits); - if (smartlist_overlap(sl,preferredexits)) + if (options.StrictExitNodes || smartlist_overlap(sl,preferredexits)) smartlist_intersect(sl,preferredexits); router = smartlist_choose(sl); } else { @@ -911,7 +911,7 @@ static routerinfo_t *choose_good_exit_server_general(routerlist_t *dir) smartlist_add(sl, smartlist_get(dir->routers, i)); smartlist_subtract(sl,excludedexits); - if (smartlist_overlap(sl,preferredexits)) + if (options.StrictExitNodes || smartlist_overlap(sl,preferredexits)) smartlist_intersect(sl,preferredexits); router = smartlist_choose(sl); } @@ -924,7 +924,9 @@ static routerinfo_t *choose_good_exit_server_general(routerlist_t *dir) log_fn(LOG_INFO, "Chose exit server '%s'", router->nickname); return router; } - log_fn(LOG_WARN, "No exit routers seem to be running; can't choose an exit."); + if (options.StrictExitNodes) + log_fn(LOG_WARN, "No exit routers seem to be running; can't choose an exit."); + return NULL; } @@ -946,7 +948,7 @@ static routerinfo_t *choose_good_exit_server(uint8_t purpose, routerlist_t *dir) case CIRCUIT_PURPOSE_C_GENERAL: return choose_good_exit_server_general(dir); case CIRCUIT_PURPOSE_C_ESTABLISH_REND: - r = router_choose_random_node(options.RendNodes, options.RendExcludeNodes, NULL, 0, 1); + r = router_choose_random_node(options.RendNodes, options.RendExcludeNodes, NULL, 0, 1, 0); return r; default: log_fn(LOG_WARN,"unhandled purpose %d", purpose); @@ -1101,7 +1103,7 @@ static routerinfo_t *choose_good_middle_server(cpath_build_state_t *state, tor_assert(r); smartlist_add(excluded, r); } - choice = router_choose_random_node("", options.ExcludeNodes, excluded, 0, 1); + choice = router_choose_random_node("", options.ExcludeNodes, excluded, 0, 1, 0); smartlist_free(excluded); return choice; } @@ -1131,7 +1133,8 @@ static routerinfo_t *choose_good_entry_server(cpath_build_state_t *state) } } choice = router_choose_random_node(options.EntryNodes, - options.ExcludeNodes, excluded, 0, 1); + options.ExcludeNodes, excluded, 0, 1, + options.StrictEntryNodes); smartlist_free(excluded); return choice; } diff --git a/src/or/config.c b/src/or/config.c index ed9f0db39..067ab4ba6 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -204,6 +204,8 @@ static int config_assign(or_options_t *options, struct config_line_t *list) { config_compare(list, "ExitNodes", CONFIG_TYPE_STRING, &options->ExitNodes) || config_compare(list, "EntryNodes", CONFIG_TYPE_STRING, &options->EntryNodes) || + config_compare(list, "StrictExitNodes", CONFIG_TYPE_BOOL, &options->StrictExitNodes) || + config_compare(list, "StrictEntryNodes", CONFIG_TYPE_BOOL, &options->StrictEntryNodes) || config_compare(list, "ExitPolicy", CONFIG_TYPE_LINELIST, &options->ExitPolicy) || config_compare(list, "ExcludeNodes", CONFIG_TYPE_STRING, &options->ExcludeNodes) || @@ -529,6 +531,7 @@ static void init_options(or_options_t *options) { options->LogOptions = NULL; options->ExitNodes = tor_strdup(""); options->EntryNodes = tor_strdup(""); + options->StrictEntryNodes = options->StrictExitNodes = 0; options->ExcludeNodes = tor_strdup(""); options->RendNodes = tor_strdup(""); options->RendExcludeNodes = tor_strdup(""); @@ -713,6 +716,14 @@ int getconfig(int argc, char **argv, or_options_t *options) { result = -1; } + if(options->StrictExitNodes && !strlen(options->ExitNodes)) { + log(LOG_WARN,"StrictExitNodes set, but no ExitNodes listed."); + } + + if(options->StrictEntryNodes && !strlen(options->EntryNodes)) { + log(LOG_WARN,"StrictEntryNodes set, but no EntryNodes listed."); + } + if(options->AuthoritativeDir && options->RecommendedVersions == NULL) { log(LOG_WARN,"Directory servers must configure RecommendedVersions."); result = -1; diff --git a/src/or/or.h b/src/or/or.h index 4a05a0474..a382e9b32 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -824,6 +824,10 @@ typedef struct { * as exits. */ char *EntryNodes; /**< Comma-separated list of nicknames of ORs to consider * as entry points. */ + int StrictExitNodes; /**< Boolean: When none of our ExitNodes are up, do we + * stop building circuits? */ + int StrictEntryNodes; /**< Boolean: When none of our EntryNodes are up, do we + * stop building circuits? */ char *ExcludeNodes; /**< Comma-separated list of nicknames of ORs not to * use in circuits. */ @@ -1381,7 +1385,8 @@ void router_add_running_routers_to_smartlist(struct smartlist_t *sl); int router_nickname_matches(routerinfo_t *router, const char *nickname); routerinfo_t *router_choose_random_node(char *preferred, char *excluded, struct smartlist_t *excludedsmartlist, - int preferuptime, int preferbandwidth); + int preferuptime, int preferbandwidth, + int strict); routerinfo_t *router_get_by_addr_port(uint32_t addr, uint16_t port); routerinfo_t *router_get_by_nickname(const char *nickname); routerinfo_t *router_get_by_hexdigest(const char *hexdigest); diff --git a/src/or/routerlist.c b/src/or/routerlist.c index a1de86c43..adc894369 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -275,13 +275,16 @@ routerlist_sl_choose_by_bandwidth(smartlist_t *sl) } /** Return a random running router from the routerlist. If any node - * named in preferred is available, pick one of those. Never pick a - * node named in excluded, or whose routerinfo is in - * excludedsmartlist, even if they are the only nodes available. + * named in preferred is available, pick one of those. Never + * pick a node named in excluded, or whose routerinfo is in + * excludedsmartlist, even if they are the only nodes + * available. If strict is true, never pick any node besides + * those in preferred. */ routerinfo_t *router_choose_random_node(char *preferred, char *excluded, smartlist_t *excludedsmartlist, - int preferuptime, int preferbandwidth) + int preferuptime, int preferbandwidth, + int strict) { smartlist_t *sl, *excludednodes; routerinfo_t *choice; @@ -302,7 +305,7 @@ routerinfo_t *router_choose_random_node(char *preferred, char *excluded, else choice = smartlist_choose(sl); smartlist_free(sl); - if(!choice) { + if(!choice && !strict) { sl = smartlist_create(); router_add_running_routers_to_smartlist(sl); smartlist_subtract(sl,excludednodes); -- cgit v1.2.3