From 9016d9e8294a35295851d12b62de4ac9a5549709 Mon Sep 17 00:00:00 2001 From: Nick Mathewson Date: Thu, 25 Oct 2012 00:20:41 -0400 Subject: Add an IPv6Exit configuration option Don't advertise an IPv6 exit policy, or accept IPv6 exit requests, if IPv6Exit is not true. --- src/or/config.c | 3 ++- src/or/connection_edge.c | 17 +++++++++++++++-- src/or/connection_edge.h | 5 +++++ src/or/or.h | 2 ++ src/or/policies.c | 5 +++++ src/or/policies.h | 1 + src/or/router.c | 1 + src/test/test.c | 6 +++--- 8 files changed, 34 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/or/config.c b/src/or/config.c index f8ac67ed38..76038d51ef 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -276,7 +276,7 @@ static config_var_t option_vars_[] = { V(HTTPProxyAuthenticator, STRING, NULL), V(HTTPSProxy, STRING, NULL), V(HTTPSProxyAuthenticator, STRING, NULL), - // V(IPv6EXit, BOOL, "0"), + V(IPv6Exit, BOOL, "0"), VAR("ServerTransportPlugin", LINELIST, ServerTransportPlugin, NULL), V(Socks4Proxy, STRING, NULL), V(Socks5Proxy, STRING, NULL), @@ -3170,6 +3170,7 @@ options_transition_affects_descriptor(const or_options_t *old_options, !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) || old_options->ExitPolicyRejectPrivate != new_options->ExitPolicyRejectPrivate || + old_options->IPv6Exit != new_options->IPv6Exit || !config_lines_eq(old_options->ORPort_lines, new_options->ORPort_lines) || !config_lines_eq(old_options->DirPort_lines, diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index d97bea7e66..373edf71ab 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -2238,6 +2238,17 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ) return 0; } + if (! options->IPv6Exit) { + /* I don't care if you prefer IPv6; I can't give you any. */ + bcell.flags &= ~BEGIN_FLAG_IPV6_PREFERRED; + /* If you don't want IPv4, I can't help. */ + if (bcell.flags & BEGIN_FLAG_IPV4_NOT_OK) { + tor_free(address); + relay_send_end_cell_from_edge(rh.stream_id, circ, + END_STREAM_REASON_EXITPOLICY, NULL); + } + } + log_debug(LD_EXIT,"Creating new exit connection."); n_stream = edge_connection_new(CONN_TYPE_EXIT, AF_INET);/*XXXX IPv6*/ @@ -2395,8 +2406,10 @@ connection_exit_connect(edge_connection_t *edge_conn) connection_t *conn = TO_CONN(edge_conn); int socket_error = 0; - if (!connection_edge_is_rendezvous_stream(edge_conn) && - router_compare_to_my_exit_policy(edge_conn)) { + if ( (!connection_edge_is_rendezvous_stream(edge_conn) && + router_compare_to_my_exit_policy(edge_conn)) || + (tor_addr_family(&conn->addr) == AF_INET6 && + ! get_options()->IPv6Exit)) { log_info(LD_EXIT,"%s:%d failed exit policy. Closing.", escaped_safe_str_client(conn->address), conn->port); connection_edge_end(edge_conn, END_STREAM_REASON_EXITPOLICY); diff --git a/src/or/connection_edge.h b/src/or/connection_edge.h index f3d10383f2..39f492de9c 100644 --- a/src/or/connection_edge.h +++ b/src/or/connection_edge.h @@ -92,6 +92,11 @@ int connection_edge_update_circuit_isolation(const entry_connection_t *conn, void circuit_clear_isolation(origin_circuit_t *circ); #ifdef CONNECTION_EDGE_PRIVATE + +#define BEGIN_FLAG_IPV6_OK (1u<<0) +#define BEGIN_FLAG_IPV4_NOT_OK (1u<<1) +#define BEGIN_FLAG_IPV6_PREFERRED (1u<<2) + /*DOCDOC*/ typedef struct begin_cell_t { char *address; diff --git a/src/or/or.h b/src/or/or.h index fa90aaee5b..9d22e117de 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -3745,6 +3745,8 @@ typedef struct { int PathBiasScaleFactor; /** @} */ + int IPv6Exit; /**< DOCDOC*/ + } or_options_t; /** Persistent state for an onion router, as saved to disk. */ diff --git a/src/or/policies.c b/src/or/policies.c index 16b3e4fa7a..f9646f8f61 100644 --- a/src/or/policies.c +++ b/src/or/policies.c @@ -437,6 +437,7 @@ validate_addr_policies(const or_options_t *options, char **msg) *msg = NULL; if (policies_parse_exit_policy(options->ExitPolicy, &addr_policy, + options->IPv6Exit, options->ExitPolicyRejectPrivate, NULL, !options->BridgeRelay)) REJECT("Error in ExitPolicy entry."); @@ -938,9 +939,13 @@ exit_policy_remove_redundancies(smartlist_t *dest) */ int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest, + int ipv6_exit, int rejectprivate, const char *local_address, int add_default_policy) { + if (!ipv6_exit) { + append_exit_policy_string(dest, "reject *6:*"); + } if (rejectprivate) { append_exit_policy_string(dest, "reject private:*"); if (local_address) { diff --git a/src/or/policies.h b/src/or/policies.h index e9d214dda5..f8de91133d 100644 --- a/src/or/policies.h +++ b/src/or/policies.h @@ -43,6 +43,7 @@ addr_policy_result_t compare_tor_addr_to_node_policy(const tor_addr_t *addr, uint16_t port, const node_t *node); int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest, + int ipv6exit, int rejectprivate, const char *local_address, int add_default_policy); void policies_exit_policy_append_reject_star(smartlist_t **dest); diff --git a/src/or/router.c b/src/or/router.c index 642656fc05..5e9f3d542b 100644 --- a/src/or/router.c +++ b/src/or/router.c @@ -1604,6 +1604,7 @@ router_rebuild_descriptor(int force) policies_exit_policy_append_reject_star(&ri->exit_policy); } else { policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy, + options->IPv6Exit, options->ExitPolicyRejectPrivate, ri->address, !options->BridgeRelay); } diff --git a/src/test/test.c b/src/test/test.c index 6652e77098..d70f255106 100644 --- a/src/test/test.c +++ b/src/test/test.c @@ -1044,7 +1044,7 @@ test_policy_summary_helper(const char *policy_str, line.value = (char *)policy_str; line.next = NULL; - r = policies_parse_exit_policy(&line, &policy, 0, NULL, 1); + r = policies_parse_exit_policy(&line, &policy, 1, 0, NULL, 1); test_eq(r, 0); summary = policy_summarize(policy, AF_INET); @@ -1101,7 +1101,7 @@ test_policies(void) test_assert(ADDR_POLICY_REJECTED == compare_tor_addr_to_addr_policy(&tar, 2, policy)); - test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, NULL, 1)); + test_assert(0 == policies_parse_exit_policy(NULL, &policy2, 1, 1, NULL, 1)); test_assert(policy2); policy3 = smartlist_new(); @@ -1188,7 +1188,7 @@ test_policies(void) line.key = (char*)"foo"; line.value = (char*)"accept *:80,reject private:*,reject *:*"; line.next = NULL; - test_assert(0 == policies_parse_exit_policy(&line, &policy, 0, NULL, 1)); + test_assert(0 == policies_parse_exit_policy(&line, &policy, 1, 0, NULL, 1)); test_assert(policy); //test_streq(policy->string, "accept *:80"); //test_streq(policy->next->string, "reject *:*"); -- cgit v1.2.3-54-g00ecf