Переглянути джерело

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 роки тому
батько
коміт
9016d9e829
8 змінених файлів з 34 додано та 6 видалено
  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 *:*");