commit ed14888e7e9ffb1877ddb7780b5033314d244fb3
Merge: 9f61450 8b01fd7
Author: Nick Mathewson <nickm(a)torproject.org>
Date: Sun Mar 6 13:20:21 2011 -0500
Merge remote branch 'origin/maint-0.2.1' into maint-0.2.2
Conflicts:
src/or/policies.c
changes/ipv6_crash | 3 +++
src/or/policies.c | 2 ++
2 files changed, 5 insertions(+), 0 deletions(-)
diff --combined src/or/policies.c
index 38c2f7c,f8c36c7..e48f420
--- a/src/or/policies.c
+++ b/src/or/policies.c
@@@ -9,10 -9,6 +9,10 @@@
**/
#include "or.h"
+#include "config.h"
+#include "dirserv.h"
+#include "policies.h"
+#include "routerparse.h"
#include "ht.h"
/** Policy that addresses for incoming SOCKS connections must match. */
@@@ -348,8 -344,7 +348,8 @@@ validate_addr_policies(or_options_t *op
*msg = NULL;
if (policies_parse_exit_policy(options->ExitPolicy, &addr_policy,
- options->ExitPolicyRejectPrivate, NULL))
+ options->ExitPolicyRejectPrivate, NULL,
+ !options->BridgeRelay))
REJECT("Error in ExitPolicy entry.");
/* The rest of these calls *append* to addr_policy. So don't actually
@@@ -380,8 -375,14 +380,8 @@@
if (parse_addr_policy(options->ReachableDirAddresses, &addr_policy,
ADDR_POLICY_ACCEPT))
REJECT("Error in ReachableDirAddresses entry.");
- if (parse_addr_policy(options->AuthDirReject, &addr_policy,
- ADDR_POLICY_REJECT))
- REJECT("Error in AuthDirReject entry.");
- if (parse_addr_policy(options->AuthDirInvalid, &addr_policy,
- ADDR_POLICY_REJECT))
- REJECT("Error in AuthDirInvalid entry.");
-err:
+ err:
addr_policy_list_free(addr_policy);
return *msg ? -1 : 0;
#undef REJECT
@@@ -828,16 -829,14 +828,16 @@@ exit_policy_remove_redundancies(smartli
"reject *:6346-6429,reject *:6699,reject *:6881-6999,accept *:*"
/** Parse the exit policy <b>cfg</b> into the linked list *<b>dest</b>. If
- * cfg doesn't end in an absolute accept or reject, add the default exit
+ * cfg doesn't end in an absolute accept or reject and if
+ * <b>add_default_policy</b> is true, add the default exit
* policy afterwards. If <b>rejectprivate</b> is true, prepend
* "reject private:*" to the policy. Return -1 if we can't parse cfg,
* else return 0.
*/
int
policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
- int rejectprivate, const char *local_address)
+ int rejectprivate, const char *local_address,
+ int add_default_policy)
{
if (rejectprivate) {
append_exit_policy_string(dest, "reject private:*");
@@@ -849,23 -848,13 +849,23 @@@
}
if (parse_addr_policy(cfg, dest, -1))
return -1;
- append_exit_policy_string(dest, DEFAULT_EXIT_POLICY);
-
+ if (add_default_policy)
+ append_exit_policy_string(dest, DEFAULT_EXIT_POLICY);
+ else
+ append_exit_policy_string(dest, "reject *:*");
exit_policy_remove_redundancies(*dest);
return 0;
}
+/** Add "reject *:*" to the end of the policy in *<b>dest</b>, allocating
+ * *<b>dest</b> as needed. */
+void
+policies_exit_policy_append_reject_star(smartlist_t **dest)
+{
+ append_exit_policy_string(dest, "reject *:*");
+}
+
/** Replace the exit policy of <b>r</b> with reject *:*. */
void
policies_set_router_exitpolicy_to_reject_all(routerinfo_t *r)
@@@ -877,49 -866,6 +877,51 @@@
smartlist_add(r->exit_policy, item);
}
+/** Return 1 if there is at least one /8 subnet in <b>policy</b> that
+ * allows exiting to <b>port</b>. Otherwise, return 0. */
+static int
+exit_policy_is_general_exit_helper(smartlist_t *policy, int port)
+{
+ uint32_t mask, ip, i;
+ /* Is this /8 rejected (1), or undecided (0)? */
+ char subnet_status[256];
+
+ memset(subnet_status, 0, sizeof(subnet_status));
+ SMARTLIST_FOREACH(policy, addr_policy_t *, p, {
++ if (tor_addr_family(&p->addr) != AF_INET)
++ continue; /* IPv4 only for now */
+ if (p->prt_min > port || p->prt_max < port)
+ continue; /* Doesn't cover our port. */
+ mask = 0;
+ tor_assert(p->maskbits <= 32);
+
+ if (p->maskbits)
+ mask = UINT32_MAX<<(32-p->maskbits);
+ ip = tor_addr_to_ipv4h(&p->addr);
+
+ /* Calculate the first and last subnet that this exit policy touches
+ * and set it as loop boundaries. */
+ for (i = ((mask & ip)>>24); i <= (~((mask & ip) ^ mask)>>24); ++i) {
+ tor_addr_t addr;
+ if (subnet_status[i] != 0)
+ continue; /* We already reject some part of this /8 */
+ tor_addr_from_ipv4h(&addr, i<<24);
+ if (tor_addr_is_internal(&addr, 0))
+ continue; /* Local or non-routable addresses */
+ if (p->policy_type == ADDR_POLICY_ACCEPT) {
+ if (p->maskbits > 8)
+ continue; /* Narrower than a /8. */
+ /* We found an allowed subnet of at least size /8. Done
+ * for this port! */
+ return 1;
+ } else if (p->policy_type == ADDR_POLICY_REJECT) {
+ subnet_status[i] = 1;
+ }
+ }
+ });
+ return 0;
+}
+
/** Return true iff <b>ri</b> is "useful as an exit node", meaning
* it allows exit to at least one /8 address space for at least
* two of ports 80, 443, and 6667. */
@@@ -933,7 -879,21 +935,7 @@@ exit_policy_is_general_exit(smartlist_
return 0;
for (i = 0; i < 3; ++i) {
- SMARTLIST_FOREACH(policy, addr_policy_t *, p, {
- if (tor_addr_family(&p->addr) != AF_INET)
- continue; /* IPv4 only for now */
- if (p->prt_min > ports[i] || p->prt_max < ports[i])
- continue; /* Doesn't cover our port. */
- if (p->maskbits > 8)
- continue; /* Narrower than a /8. */
- if (tor_addr_is_loopback(&p->addr))
- continue; /* 127.x or ::1. */
- /* We have a match that is at least a /8. */
- if (p->policy_type == ADDR_POLICY_ACCEPT) {
- ++n_allowed;
- break; /* stop considering this port */
- }
- });
+ n_allowed += exit_policy_is_general_exit_helper(policy, ports[i]);
}
return n_allowed >= 2;
}
@@@ -1280,7 -1240,7 +1282,7 @@@ policy_summarize(smartlist_t *policy
result = tor_malloc(final_size);
tor_snprintf(result, final_size, "%s %s", prefix, shorter_str);
-cleanup:
+ cleanup:
/* cleanup */
SMARTLIST_FOREACH(summary, policy_summary_item_t *, s, tor_free(s));
smartlist_free(summary);
@@@ -1300,11 -1260,9 +1302,11 @@@
* about "exit-policy/..." */
int
getinfo_helper_policies(control_connection_t *conn,
- const char *question, char **answer)
+ const char *question, char **answer,
+ const char **errmsg)
{
(void) conn;
+ (void) errmsg;
if (!strcmp(question, "exit-policy/default")) {
*answer = tor_strdup(DEFAULT_EXIT_POLICY);
}
@@@ -1315,8 -1273,7 +1317,8 @@@
void
addr_policy_list_free(smartlist_t *lst)
{
- if (!lst) return;
+ if (!lst)
+ return;
SMARTLIST_FOREACH(lst, addr_policy_t *, policy, addr_policy_free(policy));
smartlist_free(lst);
}
@@@ -1325,20 -1282,19 +1327,20 @@@
void
addr_policy_free(addr_policy_t *p)
{
- if (p) {
- if (--p->refcnt <= 0) {
- if (p->is_canonical) {
- policy_map_ent_t search, *found;
- search.policy = p;
- found = HT_REMOVE(policy_map, &policy_root, &search);
- if (found) {
- tor_assert(p == found->policy);
- tor_free(found);
- }
+ if (!p)
+ return;
+
+ if (--p->refcnt <= 0) {
+ if (p->is_canonical) {
+ policy_map_ent_t search, *found;
+ search.policy = p;
+ found = HT_REMOVE(policy_map, &policy_root, &search);
+ if (found) {
+ tor_assert(p == found->policy);
+ tor_free(found);
}
- tor_free(p);
}
+ tor_free(p);
}
}