diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/or/circuitbuild.c | 6 | ||||
-rw-r--r-- | src/or/config.c | 62 | ||||
-rw-r--r-- | src/or/or.h | 3 | ||||
-rw-r--r-- | src/or/routerlist.c | 9 |
4 files changed, 74 insertions, 6 deletions
diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index 1b41fd507..0e047120a 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -1112,6 +1112,7 @@ static routerinfo_t *choose_good_entry_server(cpath_build_state_t *state) { routerinfo_t *r, *choice; smartlist_t *excluded = smartlist_create(); + char buf[16]; if((r = router_get_by_digest(state->chosen_exit_digest))) smartlist_add(excluded, r); @@ -1128,8 +1129,9 @@ static routerinfo_t *choose_good_entry_server(cpath_build_state_t *state) for(i=0; i < smartlist_len(rl->routers); i++) { r = smartlist_get(rl->routers, i); - if(r->or_port != REQUIRED_FIREWALL_ORPORT) - smartlist_add(excluded, r); + sprintf(buf, "%d", r->or_port); + if(!smartlist_string_isin(options.FirewallPorts, buf)) + smartlist_add(excluded, r); } } choice = router_choose_random_node(options.EntryNodes, diff --git a/src/or/config.c b/src/or/config.c index 8a28e02c6..e87a02454 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -17,6 +17,8 @@ typedef enum config_type_t { CONFIG_TYPE_INT, /**< An integer */ CONFIG_TYPE_DOUBLE, /**< A floating-point value */ CONFIG_TYPE_BOOL, /**< A boolean value, expressed as 0 or 1. */ + CONFIG_TYPE_CSV, /**< A list of strings, separated by commas and optional + * whitespace. */ CONFIG_TYPE_LINELIST, /**< Uninterpreted config lines */ } config_type_t; @@ -126,6 +128,39 @@ static void config_free_lines(struct config_line_t *front) { } } +/** + * Given a list of comma-separated entries, each surrounded by optional + * whitespace, insert copies the entries (in order) into lst, without + * their surrounding whitespace. + */ +static void parse_csv_into_smartlist(smartlist_t *lst, const char *val) +{ + const char *cp, *start, *end; + + cp = val; + while (1) { + while (isspace(*cp)) + ++cp; + start = cp; + end = strchr(cp, ','); + if (!end) + end = strchr(cp, '\0'); + for (cp=end-1; cp>=start && isspace(*cp); --cp) + ; + /* Now start points to the first nonspace character of an entry, + * end points to the terminator of that entry, + * and cp points to the last nonspace character of an entry. */ + tor_assert(start <= cp); + tor_assert(cp <= end); + tor_assert(*end == '\0' || *end == ','); + tor_assert((!isspace(*start) && !isspace(*cp)) || start==cp); + smartlist_add(lst, tor_strndup(start, cp-start)); + if (!*end) + break; + cp = end+1; + } +} + /** Search the linked list <b>c</b> for any option whose key is <b>key</b>. * If such an option is found, interpret it as of type <b>type</b>, and store * the result in <b>arg</b>. If the option is misformatted, log a warning and @@ -164,6 +199,14 @@ static int config_compare(struct config_line_t *c, const char *key, config_type_ case CONFIG_TYPE_DOUBLE: *(double *)arg = atof(c->value); break; + case CONFIG_TYPE_CSV: + if (arg) { + SMARTLIST_FOREACH((smartlist_t*)arg, char *, cp, tor_free(cp)); + smartlist_free((smartlist_t*)arg); + } + arg = smartlist_create(); + parse_csv_into_smartlist(arg, c->value); + break; case CONFIG_TYPE_LINELIST: /* Note: this reverses the order that the lines appear in. That's * just fine, since we build up the list of lines reversed in the @@ -210,6 +253,7 @@ static int config_assign(or_options_t *options, struct config_line_t *list) { config_compare(list, "ExcludeNodes", CONFIG_TYPE_STRING, &options->ExcludeNodes) || config_compare(list, "FascistFirewall",CONFIG_TYPE_BOOL, &options->FascistFirewall) || + config_compare(list, "FirewallPorts",CONFIG_TYPE_CSV, &options->FirewallPorts) || config_compare(list, "Group", CONFIG_TYPE_STRING, &options->Group) || @@ -529,6 +573,8 @@ static void free_options(or_options_t *options) { config_free_lines(options->DirBindAddress); config_free_lines(options->ExitPolicy); config_free_lines(options->SocksPolicy); + SMARTLIST_FOREACH(options->FirewallPorts, char *, cp, tor_free(cp)); + smartlist_free(options->FirewallPorts); } /** Set <b>options</b> to hold reasonable defaults for most options. */ @@ -561,6 +607,7 @@ static void init_options(or_options_t *options) { options->BandwidthBurst = 10000000; /* max burst on the token bucket */ options->NumCpus = 1; options->RendConfigLines = NULL; + options->FirewallPorts = NULL; } /** Read a configuration file into <b>options</b>, finding the configuration @@ -754,6 +801,21 @@ int getconfig(int argc, char **argv, or_options_t *options) { result = -1; } + if(options->FascistFirewall && !options->FirewallPorts) { + options->FirewallPorts = smartlist_create(); + smartlist_add(options->FirewallPorts, "80"); + smartlist_add(options->FirewallPorts, "443"); + } + if(options->FirewallPorts) { + SMARTLIST_FOREACH(options->FirewallPorts, const char *, cp, + { i = atoi(cp); + if (i < 1 || i > 65535) { + log(LOG_WARN, "Port %s out of range in FirewallPorts", cp); + result=-1; + } + }); + } + if(options->SocksPort >= 1 && (options->PathlenCoinWeight < 0.0 || options->PathlenCoinWeight >= 1.0)) { log(LOG_WARN,"PathlenCoinWeight option must be >=0.0 and <1.0."); diff --git a/src/or/or.h b/src/or/or.h index 9d3fd976c..3edf23a48 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -863,7 +863,8 @@ typedef struct { int IgnoreVersion; /**< If true, run no matter what versions of Tor the * directory recommends. */ int RunAsDaemon; /**< If true, run in the background. (Unix only) */ - int FascistFirewall; /**< Whether to prefer ORs reachable on 80/443. */ + int FascistFirewall; /**< Whether to prefer ORs reachable on open ports. */ + smartlist_t *FirewallPorts; /** Which ports our firewall allows. */ int DirFetchPostPeriod; /**< How often do we fetch new directories * and post server descriptros to the directory * server? */ diff --git a/src/or/routerlist.c b/src/or/routerlist.c index adc894369..b74573607 100644 --- a/src/or/routerlist.c +++ b/src/or/routerlist.c @@ -84,6 +84,7 @@ router_pick_directory_server_impl(int requireauth, int requireothers) int i; routerinfo_t *router; smartlist_t *sl; + char buf[16]; if(!routerlist) return NULL; @@ -98,9 +99,11 @@ router_pick_directory_server_impl(int requireauth, int requireothers) continue; if(requireothers && router_is_me(router)) continue; - if(options.FascistFirewall && - router->dir_port != REQUIRED_FIREWALL_DIRPORT) - continue; + if(options.FascistFirewall) { + sprintf(buf,"%d",router->dir_port); + if (!smartlist_string_isin(options.FirewallPorts, buf)) + continue; + } smartlist_add(sl, router); } |