Loading changes/feature17840 0 → 100644 +9 −0 Original line number Diff line number Diff line o Minor feature (IPv6): - Add ClientUseIPv4, which is set to 1 by default. If set to 0, tor avoids using IPv4 for client OR and directory connections. - Add ClientPreferIPv6DirPort, which is set to 0 by default. If set to 1, tor prefers IPv6 directory addresses. - Try harder to fulfil IP version restrictions ClientUseIPv4 0 and ClientUseIPv6 0; and the preferences ClientPreferIPv6ORPort and ClientPreferIPv6DirPort. Closes ticket 17840; patch by "teor". doc/tor.1.txt +29 −8 Original line number Diff line number Diff line Loading @@ -390,6 +390,7 @@ GENERAL OPTIONS authorities. By default, the directory authorities are also FallbackDirs. Specifying a FallbackDir replaces Tor's default hard-coded FallbackDirs (if any). (See the **DirAuthority** entry for an explanation of each flag.) [[UseDefaultFallbackDirs]] **UseDefaultFallbackDirs** **0**|**1**:: Use Tor's default hard-coded FallbackDirs (if any). (When a Loading @@ -413,6 +414,10 @@ GENERAL OPTIONS if an "ipv6=__address__:__orport__" flag is present, then the directory authority is listening for IPv6 connections on the indicated IPv6 address and OR Port. + + Tor will contact the authority at __address__:__port__ (the DirPort) to download directory documents. If an IPv6 address is supplied, Tor will also download directory documents at the IPv6 address on the DirPort. + + If no **DirAuthority** line is given, Tor will use the default directory authorities. NOTE: this option is intended for setting up a private Tor Loading Loading @@ -1506,17 +1511,33 @@ The following options are useful only for clients (that is, if If no defaults are available there, these options default to 20, .80, .60, and 100, respectively. [[ClientUseIPv4]] **ClientUseIPv4** **0**|**1**:: If this option is set to 0, Tor will avoid connecting to directory servers and entry nodes over IPv4. Note that clients with an IPv4 address in a **Bridge**, proxy, or pluggable transport line will try connecting over IPv4 even if **ClientUseIPv4** is set to 0. (Default: 1) [[ClientUseIPv6]] **ClientUseIPv6** **0**|**1**:: If this option is set to 1, Tor might connect to entry nodes over IPv6. Note that clients configured with an IPv6 address in a **Bridge** line will try connecting over IPv6 even if **ClientUseIPv6** is set to 0. (Default: 0) If this option is set to 1, Tor might connect to directory servers or entry nodes over IPv6. Note that clients configured with an IPv6 address in a **Bridge**, proxy, or pluggable transport line will try connecting over IPv6 even if **ClientUseIPv6** is set to 0. (Default: 0) [[ClientPreferIPv6DirPort]] **ClientPreferIPv6DirPort** **0**|**1**|**auto**:: If this option is set to 1, Tor prefers a directory port with an IPv6 address over one with IPv4, for direct connections, if a given directory server has both. (Tor also prefers an IPv6 DirPort if IPv4Client is set to 0.) If this option is set to auto, clients prefer IPv4. Other things may influence the choice. This option breaks a tie to the favor of IPv6. (Default: auto) [[ClientPreferIPv6ORPort]] **ClientPreferIPv6ORPort** **0**|**1**:: [[ClientPreferIPv6ORPort]] **ClientPreferIPv6ORPort** **0**|**1**|**auto**:: If this option is set to 1, Tor prefers an OR port with an IPv6 address over one with IPv4 if a given entry node has both. Other things may influence the choice. This option breaks a tie to the favor of IPv6. (Default: 0) address over one with IPv4 if a given entry node has both. (Tor also prefers an IPv6 ORPort if IPv4Client is set to 0.) If this option is set to auto, Tor bridge clients prefer the configured bridge address, and other clients prefer IPv4. Other things may influence the choice. This option breaks a tie to the favor of IPv6. (Default: auto) [[PathsNeededToBuildCircuits]] **PathsNeededToBuildCircuits** __NUM__:: Tor clients don't build circuits for user traffic until they know Loading src/common/address.c +53 −0 Original line number Diff line number Diff line Loading @@ -910,6 +910,59 @@ tor_addr_is_loopback(const tor_addr_t *addr) } } /* Is addr valid? * Checks that addr is non-NULL and not tor_addr_is_null(). * If for_listening is true, IPv4 addr 0.0.0.0 is allowed. * It means "bind to all addresses on the local machine". */ int tor_addr_is_valid(const tor_addr_t *addr, int for_listening) { /* NULL addresses are invalid regardless of for_listening */ if (addr == NULL) { return 0; } /* Only allow IPv4 0.0.0.0 for_listening. */ if (for_listening && addr->family == AF_INET && tor_addr_to_ipv4h(addr) == 0) { return 1; } /* Otherwise, the address is valid if it's not tor_addr_is_null() */ return !tor_addr_is_null(addr); } /* Is the network-order IPv4 address v4n_addr valid? * Checks that addr is not zero. * Except if for_listening is true, where IPv4 addr 0.0.0.0 is allowed. */ int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening) { /* Any IPv4 address is valid with for_listening. */ if (for_listening) { return 1; } /* Otherwise, zero addresses are invalid. */ return v4n_addr != 0; } /* Is port valid? * Checks that port is not 0. * Except if for_listening is true, where port 0 is allowed. * It means "OS chooses a port". */ int tor_port_is_valid(uint16_t port, int for_listening) { /* Any port value is valid with for_listening. */ if (for_listening) { return 1; } /* Otherwise, zero ports are invalid. */ return port != 0; } /** Set <b>dest</b> to equal the IPv4 address in <b>v4addr</b> (given in * network order). */ void Loading src/common/address.h +21 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,27 @@ void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6); int tor_addr_is_null(const tor_addr_t *addr); int tor_addr_is_loopback(const tor_addr_t *addr); int tor_addr_is_valid(const tor_addr_t *addr, int for_listening); int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening); #define tor_addr_is_valid_ipv4h(v4h_addr, for_listening) \ tor_addr_is_valid_ipv4n(htonl(v4h_addr), (for_listening)) int tor_port_is_valid(uint16_t port, int for_listening); /* Are addr and port both valid? */ #define tor_addr_port_is_valid(addr, port, for_listening) \ (tor_addr_is_valid((addr), (for_listening)) && \ tor_port_is_valid((port), (for_listening))) /* Are ap->addr and ap->port both valid? */ #define tor_addr_port_is_valid_ap(ap, for_listening) \ tor_addr_port_is_valid(&(ap)->addr, (ap)->port, (for_listening)) /* Are the network-order v4addr and port both valid? */ #define tor_addr_port_is_valid_ipv4n(v4n_addr, port, for_listening) \ (tor_addr_is_valid_ipv4n((v4n_addr), (for_listening)) && \ tor_port_is_valid((port), (for_listening))) /* Are the host-order v4addr and port both valid? */ #define tor_addr_port_is_valid_ipv4h(v4h_addr, port, for_listening) \ (tor_addr_is_valid_ipv4h((v4h_addr), (for_listening)) && \ tor_port_is_valid((port), (for_listening))) int tor_addr_port_split(int severity, const char *addrport, char **address_out, uint16_t *port_out); Loading src/or/circuitbuild.c +27 −21 Original line number Diff line number Diff line Loading @@ -1778,7 +1778,7 @@ pick_tor2web_rendezvous_node(router_crn_flags_t flags, router_add_running_nodes_to_smartlist(all_live_nodes, allow_invalid, 0, 0, 0, need_desc); need_desc, 0); /* Filter all_live_nodes to only add live *and* whitelisted RPs to * the list whitelisted_live_rps. */ Loading Loading @@ -2144,7 +2144,9 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state) const node_t *choice; smartlist_t *excluded; const or_options_t *options = get_options(); router_crn_flags_t flags = CRN_NEED_GUARD|CRN_NEED_DESC; /* If possible, choose an entry server with a preferred address, * otherwise, choose one with an allowed address */ router_crn_flags_t flags = CRN_NEED_GUARD|CRN_NEED_DESC|CRN_PREF_ADDR; const node_t *node; if (state && options->UseEntryGuards && Loading @@ -2161,14 +2163,6 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state) * family. */ nodelist_add_node_and_family(excluded, node); } if (firewall_is_fascist_or()) { /* Exclude all ORs that we can't reach through our firewall */ smartlist_t *nodes = nodelist_get_list(); SMARTLIST_FOREACH(nodes, const node_t *, node, { if (!fascist_firewall_allows_node(node)) smartlist_add(excluded, (void*)node); }); } /* and exclude current entry guards and their families, * unless we're in a test network, and excluding guards * would exclude all nodes (i.e. we're in an incredibly small tor network, Loading Loading @@ -2247,9 +2241,11 @@ onion_extend_cpath(origin_circuit_t *circ) if (r) { /* If we're a client, use the preferred address rather than the primary address, for potentially connecting to an IPv6 OR port. */ info = extend_info_from_node(r, server_mode(get_options()) == 0); tor_assert(info); port. Servers always want the primary (IPv4) address. */ int client = (server_mode(get_options()) == 0); info = extend_info_from_node(r, client); /* Clients can fail to find an allowed address */ tor_assert(info || client); } } else { const node_t *r = Loading Loading @@ -2324,33 +2320,43 @@ extend_info_new(const char *nickname, const char *digest, * <b>for_direct_connect</b> is true, in which case the preferred * address is used instead. May return NULL if there is not enough * info about <b>node</b> to extend to it--for example, if there is no * routerinfo_t or microdesc_t. * routerinfo_t or microdesc_t, or if for_direct_connect is true and none of * the node's addresses are allowed by tor's firewall and IP version config. **/ extend_info_t * extend_info_from_node(const node_t *node, int for_direct_connect) { tor_addr_port_t ap; int valid_addr = 0; if (node->ri == NULL && (node->rs == NULL || node->md == NULL)) return NULL; /* Choose a preferred address first, but fall back to an allowed address. * choose_address returns 1 on success, but get_prim_orport returns 0. */ if (for_direct_connect) node_get_pref_orport(node, &ap); valid_addr = fascist_firewall_choose_address_node(node, FIREWALL_OR_CONNECTION, 0, &ap); else node_get_prim_orport(node, &ap); valid_addr = !node_get_prim_orport(node, &ap); if (valid_addr) log_debug(LD_CIRC, "using %s for %s", fmt_addrport(&ap.addr, ap.port), node->ri ? node->ri->nickname : node->rs->nickname); else log_warn(LD_CIRC, "Could not choose valid address for %s", node->ri ? node->ri->nickname : node->rs->nickname); if (node->ri) if (valid_addr && node->ri) return extend_info_new(node->ri->nickname, node->identity, node->ri->onion_pkey, node->ri->onion_curve25519_pkey, &ap.addr, ap.port); else if (node->rs && node->md) else if (valid_addr && node->rs && node->md) return extend_info_new(node->rs->nickname, node->identity, node->md->onion_pkey, Loading Loading
changes/feature17840 0 → 100644 +9 −0 Original line number Diff line number Diff line o Minor feature (IPv6): - Add ClientUseIPv4, which is set to 1 by default. If set to 0, tor avoids using IPv4 for client OR and directory connections. - Add ClientPreferIPv6DirPort, which is set to 0 by default. If set to 1, tor prefers IPv6 directory addresses. - Try harder to fulfil IP version restrictions ClientUseIPv4 0 and ClientUseIPv6 0; and the preferences ClientPreferIPv6ORPort and ClientPreferIPv6DirPort. Closes ticket 17840; patch by "teor".
doc/tor.1.txt +29 −8 Original line number Diff line number Diff line Loading @@ -390,6 +390,7 @@ GENERAL OPTIONS authorities. By default, the directory authorities are also FallbackDirs. Specifying a FallbackDir replaces Tor's default hard-coded FallbackDirs (if any). (See the **DirAuthority** entry for an explanation of each flag.) [[UseDefaultFallbackDirs]] **UseDefaultFallbackDirs** **0**|**1**:: Use Tor's default hard-coded FallbackDirs (if any). (When a Loading @@ -413,6 +414,10 @@ GENERAL OPTIONS if an "ipv6=__address__:__orport__" flag is present, then the directory authority is listening for IPv6 connections on the indicated IPv6 address and OR Port. + + Tor will contact the authority at __address__:__port__ (the DirPort) to download directory documents. If an IPv6 address is supplied, Tor will also download directory documents at the IPv6 address on the DirPort. + + If no **DirAuthority** line is given, Tor will use the default directory authorities. NOTE: this option is intended for setting up a private Tor Loading Loading @@ -1506,17 +1511,33 @@ The following options are useful only for clients (that is, if If no defaults are available there, these options default to 20, .80, .60, and 100, respectively. [[ClientUseIPv4]] **ClientUseIPv4** **0**|**1**:: If this option is set to 0, Tor will avoid connecting to directory servers and entry nodes over IPv4. Note that clients with an IPv4 address in a **Bridge**, proxy, or pluggable transport line will try connecting over IPv4 even if **ClientUseIPv4** is set to 0. (Default: 1) [[ClientUseIPv6]] **ClientUseIPv6** **0**|**1**:: If this option is set to 1, Tor might connect to entry nodes over IPv6. Note that clients configured with an IPv6 address in a **Bridge** line will try connecting over IPv6 even if **ClientUseIPv6** is set to 0. (Default: 0) If this option is set to 1, Tor might connect to directory servers or entry nodes over IPv6. Note that clients configured with an IPv6 address in a **Bridge**, proxy, or pluggable transport line will try connecting over IPv6 even if **ClientUseIPv6** is set to 0. (Default: 0) [[ClientPreferIPv6DirPort]] **ClientPreferIPv6DirPort** **0**|**1**|**auto**:: If this option is set to 1, Tor prefers a directory port with an IPv6 address over one with IPv4, for direct connections, if a given directory server has both. (Tor also prefers an IPv6 DirPort if IPv4Client is set to 0.) If this option is set to auto, clients prefer IPv4. Other things may influence the choice. This option breaks a tie to the favor of IPv6. (Default: auto) [[ClientPreferIPv6ORPort]] **ClientPreferIPv6ORPort** **0**|**1**:: [[ClientPreferIPv6ORPort]] **ClientPreferIPv6ORPort** **0**|**1**|**auto**:: If this option is set to 1, Tor prefers an OR port with an IPv6 address over one with IPv4 if a given entry node has both. Other things may influence the choice. This option breaks a tie to the favor of IPv6. (Default: 0) address over one with IPv4 if a given entry node has both. (Tor also prefers an IPv6 ORPort if IPv4Client is set to 0.) If this option is set to auto, Tor bridge clients prefer the configured bridge address, and other clients prefer IPv4. Other things may influence the choice. This option breaks a tie to the favor of IPv6. (Default: auto) [[PathsNeededToBuildCircuits]] **PathsNeededToBuildCircuits** __NUM__:: Tor clients don't build circuits for user traffic until they know Loading
src/common/address.c +53 −0 Original line number Diff line number Diff line Loading @@ -910,6 +910,59 @@ tor_addr_is_loopback(const tor_addr_t *addr) } } /* Is addr valid? * Checks that addr is non-NULL and not tor_addr_is_null(). * If for_listening is true, IPv4 addr 0.0.0.0 is allowed. * It means "bind to all addresses on the local machine". */ int tor_addr_is_valid(const tor_addr_t *addr, int for_listening) { /* NULL addresses are invalid regardless of for_listening */ if (addr == NULL) { return 0; } /* Only allow IPv4 0.0.0.0 for_listening. */ if (for_listening && addr->family == AF_INET && tor_addr_to_ipv4h(addr) == 0) { return 1; } /* Otherwise, the address is valid if it's not tor_addr_is_null() */ return !tor_addr_is_null(addr); } /* Is the network-order IPv4 address v4n_addr valid? * Checks that addr is not zero. * Except if for_listening is true, where IPv4 addr 0.0.0.0 is allowed. */ int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening) { /* Any IPv4 address is valid with for_listening. */ if (for_listening) { return 1; } /* Otherwise, zero addresses are invalid. */ return v4n_addr != 0; } /* Is port valid? * Checks that port is not 0. * Except if for_listening is true, where port 0 is allowed. * It means "OS chooses a port". */ int tor_port_is_valid(uint16_t port, int for_listening) { /* Any port value is valid with for_listening. */ if (for_listening) { return 1; } /* Otherwise, zero ports are invalid. */ return port != 0; } /** Set <b>dest</b> to equal the IPv4 address in <b>v4addr</b> (given in * network order). */ void Loading
src/common/address.h +21 −0 Original line number Diff line number Diff line Loading @@ -267,6 +267,27 @@ void tor_addr_from_in6(tor_addr_t *dest, const struct in6_addr *in6); int tor_addr_is_null(const tor_addr_t *addr); int tor_addr_is_loopback(const tor_addr_t *addr); int tor_addr_is_valid(const tor_addr_t *addr, int for_listening); int tor_addr_is_valid_ipv4n(uint32_t v4n_addr, int for_listening); #define tor_addr_is_valid_ipv4h(v4h_addr, for_listening) \ tor_addr_is_valid_ipv4n(htonl(v4h_addr), (for_listening)) int tor_port_is_valid(uint16_t port, int for_listening); /* Are addr and port both valid? */ #define tor_addr_port_is_valid(addr, port, for_listening) \ (tor_addr_is_valid((addr), (for_listening)) && \ tor_port_is_valid((port), (for_listening))) /* Are ap->addr and ap->port both valid? */ #define tor_addr_port_is_valid_ap(ap, for_listening) \ tor_addr_port_is_valid(&(ap)->addr, (ap)->port, (for_listening)) /* Are the network-order v4addr and port both valid? */ #define tor_addr_port_is_valid_ipv4n(v4n_addr, port, for_listening) \ (tor_addr_is_valid_ipv4n((v4n_addr), (for_listening)) && \ tor_port_is_valid((port), (for_listening))) /* Are the host-order v4addr and port both valid? */ #define tor_addr_port_is_valid_ipv4h(v4h_addr, port, for_listening) \ (tor_addr_is_valid_ipv4h((v4h_addr), (for_listening)) && \ tor_port_is_valid((port), (for_listening))) int tor_addr_port_split(int severity, const char *addrport, char **address_out, uint16_t *port_out); Loading
src/or/circuitbuild.c +27 −21 Original line number Diff line number Diff line Loading @@ -1778,7 +1778,7 @@ pick_tor2web_rendezvous_node(router_crn_flags_t flags, router_add_running_nodes_to_smartlist(all_live_nodes, allow_invalid, 0, 0, 0, need_desc); need_desc, 0); /* Filter all_live_nodes to only add live *and* whitelisted RPs to * the list whitelisted_live_rps. */ Loading Loading @@ -2144,7 +2144,9 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state) const node_t *choice; smartlist_t *excluded; const or_options_t *options = get_options(); router_crn_flags_t flags = CRN_NEED_GUARD|CRN_NEED_DESC; /* If possible, choose an entry server with a preferred address, * otherwise, choose one with an allowed address */ router_crn_flags_t flags = CRN_NEED_GUARD|CRN_NEED_DESC|CRN_PREF_ADDR; const node_t *node; if (state && options->UseEntryGuards && Loading @@ -2161,14 +2163,6 @@ choose_good_entry_server(uint8_t purpose, cpath_build_state_t *state) * family. */ nodelist_add_node_and_family(excluded, node); } if (firewall_is_fascist_or()) { /* Exclude all ORs that we can't reach through our firewall */ smartlist_t *nodes = nodelist_get_list(); SMARTLIST_FOREACH(nodes, const node_t *, node, { if (!fascist_firewall_allows_node(node)) smartlist_add(excluded, (void*)node); }); } /* and exclude current entry guards and their families, * unless we're in a test network, and excluding guards * would exclude all nodes (i.e. we're in an incredibly small tor network, Loading Loading @@ -2247,9 +2241,11 @@ onion_extend_cpath(origin_circuit_t *circ) if (r) { /* If we're a client, use the preferred address rather than the primary address, for potentially connecting to an IPv6 OR port. */ info = extend_info_from_node(r, server_mode(get_options()) == 0); tor_assert(info); port. Servers always want the primary (IPv4) address. */ int client = (server_mode(get_options()) == 0); info = extend_info_from_node(r, client); /* Clients can fail to find an allowed address */ tor_assert(info || client); } } else { const node_t *r = Loading Loading @@ -2324,33 +2320,43 @@ extend_info_new(const char *nickname, const char *digest, * <b>for_direct_connect</b> is true, in which case the preferred * address is used instead. May return NULL if there is not enough * info about <b>node</b> to extend to it--for example, if there is no * routerinfo_t or microdesc_t. * routerinfo_t or microdesc_t, or if for_direct_connect is true and none of * the node's addresses are allowed by tor's firewall and IP version config. **/ extend_info_t * extend_info_from_node(const node_t *node, int for_direct_connect) { tor_addr_port_t ap; int valid_addr = 0; if (node->ri == NULL && (node->rs == NULL || node->md == NULL)) return NULL; /* Choose a preferred address first, but fall back to an allowed address. * choose_address returns 1 on success, but get_prim_orport returns 0. */ if (for_direct_connect) node_get_pref_orport(node, &ap); valid_addr = fascist_firewall_choose_address_node(node, FIREWALL_OR_CONNECTION, 0, &ap); else node_get_prim_orport(node, &ap); valid_addr = !node_get_prim_orport(node, &ap); if (valid_addr) log_debug(LD_CIRC, "using %s for %s", fmt_addrport(&ap.addr, ap.port), node->ri ? node->ri->nickname : node->rs->nickname); else log_warn(LD_CIRC, "Could not choose valid address for %s", node->ri ? node->ri->nickname : node->rs->nickname); if (node->ri) if (valid_addr && node->ri) return extend_info_new(node->ri->nickname, node->identity, node->ri->onion_pkey, node->ri->onion_curve25519_pkey, &ap.addr, ap.port); else if (node->rs && node->md) else if (valid_addr && node->rs && node->md) return extend_info_new(node->rs->nickname, node->identity, node->md->onion_pkey, Loading