diff --git a/src/or/config.c b/src/or/config.c index 60028f27d9..1df10e110e 100644 --- a/src/or/config.c +++ b/src/or/config.c @@ -4605,6 +4605,7 @@ port_cfg_new(void) port_cfg_t *cfg = tor_malloc_zero(sizeof(port_cfg_t)); cfg->ipv4_traffic = 1; cfg->cache_ipv4_answers = 1; + cfg->prefer_ipv6_virtaddr = 1; return cfg; } @@ -4789,6 +4790,7 @@ parse_port_config(smartlist_t *out, cfg->no_listen = 1; cfg->bind_ipv4_only = 1; cfg->ipv4_traffic = 1; + cfg->prefer_ipv6_virtaddr = 1; smartlist_add(out, cfg); } @@ -4853,7 +4855,8 @@ parse_port_config(smartlist_t *out, bind_ipv4_only = 0, bind_ipv6_only = 0, ipv4_traffic = 1, ipv6_traffic = 0, prefer_ipv6 = 0, cache_ipv4 = 1, use_cached_ipv4 = 0, - cache_ipv6 = 0, use_cached_ipv6 = 0; + cache_ipv6 = 0, use_cached_ipv6 = 0, + prefer_ipv6_automap = 1; smartlist_split_string(elts, ports->value, NULL, SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 0); @@ -5008,6 +5011,9 @@ parse_port_config(smartlist_t *out, } else if (!strcasecmp(elt, "UseDNSCache")) { use_cached_ipv4 = use_cached_ipv6 = ! no; continue; + } else if (!strcasecmp(elt, "PreferIPv6Automap")) { + prefer_ipv6_automap = ! no; + continue; } if (!strcasecmpend(elt, "s")) @@ -5066,6 +5072,7 @@ parse_port_config(smartlist_t *out, cfg->cache_ipv6_answers = cache_ipv6; cfg->use_cached_ipv4_answers = use_cached_ipv4; cfg->use_cached_ipv6_answers = use_cached_ipv6; + cfg->prefer_ipv6_virtaddr = prefer_ipv6_automap; smartlist_add(out, cfg); } diff --git a/src/or/connection.c b/src/or/connection.c index 1395d3ebd7..740462e7c6 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -1134,6 +1134,7 @@ connection_listener_new(const struct sockaddr *listensockaddr, lis_conn->cache_ipv6_answers = port_cfg->cache_ipv6_answers; lis_conn->use_cached_ipv4_answers = port_cfg->use_cached_ipv4_answers; lis_conn->use_cached_ipv6_answers = port_cfg->use_cached_ipv6_answers; + lis_conn->prefer_ipv6_virtaddr = port_cfg->prefer_ipv6_virtaddr; if (connection_add(conn) < 0) { /* no space, forget it */ log_warn(LD_NET,"connection_add for listener failed. Giving up."); @@ -1376,6 +1377,8 @@ connection_init_accepted_conn(connection_t *conn, listener->use_cached_ipv4_answers; TO_ENTRY_CONN(conn)->use_cached_ipv6_answers = listener->use_cached_ipv6_answers; + TO_ENTRY_CONN(conn)->prefer_ipv6_virtaddr = + listener->prefer_ipv6_virtaddr; switch (TO_CONN(listener)->type) { case CONN_TYPE_AP_LISTENER: diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 960802654e..28c9e09ee5 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -932,9 +932,15 @@ connection_ap_handshake_rewrite_and_attach(entry_connection_t *conn, automap = addressmap_address_should_automap(socks->address, options); if (automap) { const char *new_addr; - /*XXXX IPv6 Sometimes this should be RESOLVED_TYPE_IPV6 */ + int addr_type = RESOLVED_TYPE_IPV4; + if (conn->socks_request->socks_version != 4) { + if (!conn->ipv4_traffic_ok || + (conn->ipv6_traffic_ok && conn->prefer_ipv6_traffic) || + conn->prefer_ipv6_virtaddr) + addr_type = RESOLVED_TYPE_IPV6; + } new_addr = addressmap_register_virtual_address( - RESOLVED_TYPE_IPV4, tor_strdup(socks->address)); + addr_type, tor_strdup(socks->address)); if (! new_addr) { log_warn(LD_APP, "Unable to automap address %s", escaped_safe_str(socks->address)); diff --git a/src/or/or.h b/src/or/or.h index 5b6019340c..17cd99b29f 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -1242,6 +1242,7 @@ typedef struct listener_connection_t { unsigned int cache_ipv6_answers : 1; unsigned int use_cached_ipv4_answers : 1; unsigned int use_cached_ipv6_answers : 1; + unsigned int prefer_ipv6_virtaddr : 1; } listener_connection_t; @@ -1556,6 +1557,7 @@ typedef struct entry_connection_t { unsigned int cache_ipv6_answers : 1; unsigned int use_cached_ipv4_answers : 1; unsigned int use_cached_ipv6_answers : 1; + unsigned int prefer_ipv6_virtaddr : 1; } entry_connection_t; @@ -3107,6 +3109,7 @@ typedef struct port_cfg_t { unsigned int cache_ipv6_answers : 1; unsigned int use_cached_ipv4_answers : 1; unsigned int use_cached_ipv6_answers : 1; + unsigned int prefer_ipv6_virtaddr : 1; /* Unix sockets only: */ /** Path for an AF_UNIX address */