diff options
author | Roger Dingledine <arma@torproject.org> | 2004-10-25 06:16:26 +0000 |
---|---|---|
committer | Roger Dingledine <arma@torproject.org> | 2004-10-25 06:16:26 +0000 |
commit | 0113a643a2e32b80931400e07d3b7389875570d1 (patch) | |
tree | e60392062eb6222025ca15fc02aed0186895711b /src | |
parent | f084bc07b5157fce4d4b647310f152bcaac46c69 (diff) | |
download | tor-0113a643a2e32b80931400e07d3b7389875570d1.tar.gz tor-0113a643a2e32b80931400e07d3b7389875570d1.zip |
quick-and-dirty dir policy since the dirservers are getting hammered
nick, could you abstract this sometime so we don't repeat the
sockspolicy code twice?
svn:r2589
Diffstat (limited to 'src')
-rw-r--r-- | src/or/config.c | 4 | ||||
-rw-r--r-- | src/or/connection.c | 9 | ||||
-rw-r--r-- | src/or/directory.c | 44 | ||||
-rw-r--r-- | src/or/or.h | 2 |
4 files changed, 58 insertions, 1 deletions
diff --git a/src/or/config.c b/src/or/config.c index fce0e49e3a..aafe4c2d06 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -236,6 +236,7 @@ config_assign(or_options_t *options, struct config_line_t *list) config_compare(list, "DirPort", CONFIG_TYPE_UINT, &options->DirPort) || config_compare(list, "DirBindAddress", CONFIG_TYPE_LINELIST, &options->DirBindAddress) || config_compare(list, "DirFetchPostPeriod",CONFIG_TYPE_UINT, &options->DirFetchPostPeriod) || + config_compare(list, "DirPolicy", CONFIG_TYPE_LINELIST, &options->DirPolicy) || config_compare(list, "DirServer", CONFIG_TYPE_LINELIST, &options->DirServers) || config_compare(list, "ExitNodes", CONFIG_TYPE_STRING, &options->ExitNodes) || @@ -479,6 +480,7 @@ free_options(or_options_t *options) config_free_lines(options->DirBindAddress); config_free_lines(options->ExitPolicy); config_free_lines(options->SocksPolicy); + config_free_lines(options->DirPolicy); config_free_lines(options->DirServers); config_free_lines(options->RecommendedVersions); config_free_lines(options->NodeFamilies); @@ -487,7 +489,7 @@ free_options(or_options_t *options) SMARTLIST_FOREACH(options->RedirectExitList, exit_redirect_t *, p, tor_free(p)); smartlist_free(options->RedirectExitList); - options->RedirectExitList = NULL; + options->RedirectExitList = NULL; } if (options->FirewallPorts) { SMARTLIST_FOREACH(options->FirewallPorts, char *, cp, tor_free(cp)); diff --git a/src/or/connection.c b/src/or/connection.c index 0c45b7fb2b..0c3908ff04 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -420,6 +420,15 @@ static int connection_handle_listener_read(connection_t *conn, int new_type) { return 0; } } + if(new_type == CONN_TYPE_DIR) { + /* check dirpolicy to see if we should accept it */ + if(dir_policy_permits_address(ntohl(remote.sin_addr.s_addr)) == 0) { + log_fn(LOG_WARN,"Denying dir connection from address %s.", + inet_ntoa(remote.sin_addr)); + tor_close_socket(news); + return 0; + } + } newconn = connection_new(new_type); newconn->s = news; diff --git a/src/or/directory.c b/src/or/directory.c index 40f408ffce..8325988704 100644 --- a/src/or/directory.c +++ b/src/or/directory.c @@ -48,6 +48,8 @@ static int directory_handle_command(connection_t *conn); extern or_options_t options; /* command-line and config-file options */ +static struct exit_policy_t *dir_policy = NULL; + #if 0 /* commented out for now, since for now what clients send is different from what servers want to receive */ /** URL for publishing rendezvous descriptors. */ @@ -63,6 +65,48 @@ char rend_fetch_url[] = "/tor/rendezvous/"; /********* END VARIABLES ************/ +/** A helper function for dir_policy_permits_address() below. + * + * Parse options.DirPolicy in the same way that the exit policy + * is parsed, and put the processed version in &dir_policy. + * Ignore port specifiers. + */ +static void parse_dir_policy(void) +{ + struct exit_policy_t *n; + if (dir_policy) { + exit_policy_free(dir_policy); + dir_policy = NULL; + } + config_parse_exit_policy(options.DirPolicy, &dir_policy); + /* ports aren't used. */ + for (n=dir_policy; n; n = n->next) { + n->prt_min = 1; + n->prt_max = 65535; + } +} + +/** Return 1 if <b>addr</b> is permitted to connect to our dir port, + * based on <b>dir_policy</b>. Else return 0. + */ +int dir_policy_permits_address(uint32_t addr) +{ + int a; + if (options.DirPolicy && !dir_policy) + parse_dir_policy(); + + if(!dir_policy) /* 'no dir policy' means 'accept' */ + return 1; + a = router_compare_addr_to_exit_policy(addr, 1, dir_policy); + if (a==-1) + return 0; + else if (a==0) + return 1; + tor_assert(a==1); + log_fn(LOG_WARN, "Got unexpected 'maybe' answer from dir policy"); + return 0; +} + /** Start a connection to every known directory server, using * connection purpose 'purpose' and uploading the payload 'payload' * (length 'payload_len'). The purpose should be one of diff --git a/src/or/or.h b/src/or/or.h index 668422c8d7..4db838ac98 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -860,6 +860,7 @@ typedef struct { int _AllowUnverified; /**< Bitmask; derived from AllowUnverifiedNodes; */ struct config_line_t *ExitPolicy; /**< Lists of exit policy components. */ struct config_line_t *SocksPolicy; /**< Lists of socks policy components */ + struct config_line_t *DirPolicy; /**< Lists of dir policy components */ /** Addresses to bind for listening for SOCKS connections. */ struct config_line_t *SocksBindAddress; /** Addresses to bind for listening for OR connections. */ @@ -1191,6 +1192,7 @@ int assign_to_cpuworker(connection_t *cpuworker, unsigned char question_type, /********************************* directory.c ***************************/ +int dir_policy_permits_address(uint32_t addr); void directory_post_to_dirservers(uint8_t purpose, const char *payload, size_t payload_len); void directory_get_from_dirserver(uint8_t purpose, const char *payload, |