Browse Source

Add an IPv6Exit configuration option

Don't advertise an IPv6 exit policy, or accept IPv6 exit requests,
if IPv6Exit is not true.
Nick Mathewson 11 years ago
parent
commit
9016d9e829
8 changed files with 34 additions and 6 deletions
  1. 2 1
      src/or/config.c
  2. 15 2
      src/or/connection_edge.c
  3. 5 0
      src/or/connection_edge.h
  4. 2 0
      src/or/or.h
  5. 5 0
      src/or/policies.c
  6. 1 0
      src/or/policies.h
  7. 1 0
      src/or/router.c
  8. 3 3
      src/test/test.c

+ 2 - 1
src/or/config.c

@@ -276,7 +276,7 @@ static config_var_t option_vars_[] = {
   V(HTTPProxyAuthenticator,      STRING,   NULL),
   V(HTTPProxyAuthenticator,      STRING,   NULL),
   V(HTTPSProxy,                  STRING,   NULL),
   V(HTTPSProxy,                  STRING,   NULL),
   V(HTTPSProxyAuthenticator,     STRING,   NULL),
   V(HTTPSProxyAuthenticator,     STRING,   NULL),
-  //  V(IPv6EXit,                    BOOL,     "0"),
+  V(IPv6Exit,                    BOOL,     "0"),
   VAR("ServerTransportPlugin",   LINELIST, ServerTransportPlugin,  NULL),
   VAR("ServerTransportPlugin",   LINELIST, ServerTransportPlugin,  NULL),
   V(Socks4Proxy,                 STRING,   NULL),
   V(Socks4Proxy,                 STRING,   NULL),
   V(Socks5Proxy,                 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) ||
       !config_lines_eq(old_options->ExitPolicy,new_options->ExitPolicy) ||
       old_options->ExitPolicyRejectPrivate !=
       old_options->ExitPolicyRejectPrivate !=
         new_options->ExitPolicyRejectPrivate ||
         new_options->ExitPolicyRejectPrivate ||
+      old_options->IPv6Exit != new_options->IPv6Exit ||
       !config_lines_eq(old_options->ORPort_lines,
       !config_lines_eq(old_options->ORPort_lines,
                        new_options->ORPort_lines) ||
                        new_options->ORPort_lines) ||
       !config_lines_eq(old_options->DirPort_lines,
       !config_lines_eq(old_options->DirPort_lines,

+ 15 - 2
src/or/connection_edge.c

@@ -2238,6 +2238,17 @@ connection_exit_begin_conn(cell_t *cell, circuit_t *circ)
     return 0;
     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.");
   log_debug(LD_EXIT,"Creating new exit connection.");
   n_stream = edge_connection_new(CONN_TYPE_EXIT, AF_INET);/*XXXX IPv6*/
   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);
   connection_t *conn = TO_CONN(edge_conn);
   int socket_error = 0;
   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.",
     log_info(LD_EXIT,"%s:%d failed exit policy. Closing.",
              escaped_safe_str_client(conn->address), conn->port);
              escaped_safe_str_client(conn->address), conn->port);
     connection_edge_end(edge_conn, END_STREAM_REASON_EXITPOLICY);
     connection_edge_end(edge_conn, END_STREAM_REASON_EXITPOLICY);

+ 5 - 0
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);
 void circuit_clear_isolation(origin_circuit_t *circ);
 
 
 #ifdef CONNECTION_EDGE_PRIVATE
 #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*/
 /*DOCDOC*/
 typedef struct begin_cell_t {
 typedef struct begin_cell_t {
   char *address;
   char *address;

+ 2 - 0
src/or/or.h

@@ -3745,6 +3745,8 @@ typedef struct {
   int PathBiasScaleFactor;
   int PathBiasScaleFactor;
   /** @} */
   /** @} */
 
 
+  int IPv6Exit; /**< DOCDOC*/
+
 } or_options_t;
 } or_options_t;
 
 
 /** Persistent state for an onion router, as saved to disk. */
 /** Persistent state for an onion router, as saved to disk. */

+ 5 - 0
src/or/policies.c

@@ -437,6 +437,7 @@ validate_addr_policies(const or_options_t *options, char **msg)
   *msg = NULL;
   *msg = NULL;
 
 
   if (policies_parse_exit_policy(options->ExitPolicy, &addr_policy,
   if (policies_parse_exit_policy(options->ExitPolicy, &addr_policy,
+                                 options->IPv6Exit,
                                  options->ExitPolicyRejectPrivate, NULL,
                                  options->ExitPolicyRejectPrivate, NULL,
                                  !options->BridgeRelay))
                                  !options->BridgeRelay))
     REJECT("Error in ExitPolicy entry.");
     REJECT("Error in ExitPolicy entry.");
@@ -938,9 +939,13 @@ exit_policy_remove_redundancies(smartlist_t *dest)
  */
  */
 int
 int
 policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
 policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
+                           int ipv6_exit,
                            int rejectprivate, const char *local_address,
                            int rejectprivate, const char *local_address,
                            int add_default_policy)
                            int add_default_policy)
 {
 {
+  if (!ipv6_exit) {
+    append_exit_policy_string(dest, "reject *6:*");
+  }
   if (rejectprivate) {
   if (rejectprivate) {
     append_exit_policy_string(dest, "reject private:*");
     append_exit_policy_string(dest, "reject private:*");
     if (local_address) {
     if (local_address) {

+ 1 - 0
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);
                               uint16_t port, const node_t *node);
 
 
 int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
 int policies_parse_exit_policy(config_line_t *cfg, smartlist_t **dest,
+                               int ipv6exit,
                                int rejectprivate, const char *local_address,
                                int rejectprivate, const char *local_address,
                                int add_default_policy);
                                int add_default_policy);
 void policies_exit_policy_append_reject_star(smartlist_t **dest);
 void policies_exit_policy_append_reject_star(smartlist_t **dest);

+ 1 - 0
src/or/router.c

@@ -1604,6 +1604,7 @@ router_rebuild_descriptor(int force)
     policies_exit_policy_append_reject_star(&ri->exit_policy);
     policies_exit_policy_append_reject_star(&ri->exit_policy);
   } else {
   } else {
     policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
     policies_parse_exit_policy(options->ExitPolicy, &ri->exit_policy,
+                               options->IPv6Exit,
                                options->ExitPolicyRejectPrivate,
                                options->ExitPolicyRejectPrivate,
                                ri->address, !options->BridgeRelay);
                                ri->address, !options->BridgeRelay);
   }
   }

+ 3 - 3
src/test/test.c

@@ -1044,7 +1044,7 @@ test_policy_summary_helper(const char *policy_str,
   line.value = (char *)policy_str;
   line.value = (char *)policy_str;
   line.next = NULL;
   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);
   test_eq(r, 0);
   summary = policy_summarize(policy, AF_INET);
   summary = policy_summarize(policy, AF_INET);
 
 
@@ -1101,7 +1101,7 @@ test_policies(void)
   test_assert(ADDR_POLICY_REJECTED ==
   test_assert(ADDR_POLICY_REJECTED ==
           compare_tor_addr_to_addr_policy(&tar, 2, policy));
           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);
   test_assert(policy2);
 
 
   policy3 = smartlist_new();
   policy3 = smartlist_new();
@@ -1188,7 +1188,7 @@ test_policies(void)
   line.key = (char*)"foo";
   line.key = (char*)"foo";
   line.value = (char*)"accept *:80,reject private:*,reject *:*";
   line.value = (char*)"accept *:80,reject private:*,reject *:*";
   line.next = NULL;
   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_assert(policy);
   //test_streq(policy->string, "accept *:80");
   //test_streq(policy->string, "accept *:80");
   //test_streq(policy->next->string, "reject *:*");
   //test_streq(policy->next->string, "reject *:*");