aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/or/circuitbuild.c6
-rw-r--r--src/or/config.c62
-rw-r--r--src/or/or.h3
-rw-r--r--src/or/routerlist.c9
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);
}