Forráskód Böngészése

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 éve
szülő
commit
9016d9e829
8 módosított fájl, 34 hozzáadás és 6 törlés
  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(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,

+ 15 - 2
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);

+ 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);
 
 #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;

+ 2 - 0
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. */

+ 5 - 0
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) {

+ 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);
 
 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);

+ 1 - 0
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);
   }

+ 3 - 3
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 *:*");