Opened 3 years ago

Last modified 3 months ago

#17835 assigned enhancement

Make ClientPreferIPv6ORPort smarter

Reported by: teor Owned by: neel
Priority: Medium Milestone: Tor: unspecified
Component: Core Tor/Tor Version:
Severity: Normal Keywords: tor-client, ipv6, 040-deferred-201915
Cc: neel@… Actual Points:
Parent ID: #17811 Points: medium/large
Reviewer: Sponsor:

Description

It's hard for users on dual-stack machines to know whether their IPv4 or IPv6 connections provides better connectivity or censorship-resistance.

Tor could help with this by:

  • Making ClientPreferIPv6ORPort/DirPort into an autobool, and setting the default to auto (infer), rather than 0 (IPv4)
  • Infer initial IPv4/IPv6 preference by looking at the machine's network interfaces, and:
    • Ignoring localhost (tor_addr_is_localhost) and link-local addresses (a new tor_addr_is_link_local)
    • Checking for (other) private addresses (tor currently considers link-local addresses private, this shouldn't change in the rest of the codebase, but it is important to distinguish here, as IPv4/IPv6 hosts with no IPv6 connectivity still auto-configure a link-local IPv6 address)
    • Checking for publicly routable addresses
    • Preferring IP versions that have a public address, over those that have a private address
    • (I'd also say to avoid IP versions that only have localhost or link-local addresses, and don't use IP versions that have no addresses, but that might cause issues with proxies, or with machines that prohibit enumeration of local addresses.)
    • Repeat these checks every N minutes in case the network interfaces have changed (relays do this every 20 minutes at the moment)
  • Infer a preference for IPv4 or IPv6 based on the number of failed connections
    • Globally track counts of attempted IPv4 and IPv6 connections
    • Globally track failures of attempted IPv4 and IPv6 connections
    • If there have been at least M attempts (2? 3?) on (one? each?) IP version, then:
      • If an IP version has 100% failure, avoid it
      • IP an IP version has a significantly (2x?) larger failure rate, avoid it

I'm deferring this to 0.2.9 because:

  • IPv4/IPv6 Tor clients might work fine without any of these changes.
  • It's complex code, and it's not clear that it's the best way to determine preferred IP versions. (Let's get some experience with dual-stack clients first.)
  • We only have 4/9 authorities and ~25% of fallback directory mirrors on IPv6, so let's prefer IPv4 by default at the moment for load-balancing reasons. (For similar reasons, ClientUseIPv6 could default to 1 in future, but now might not be a good time to do that. However, Tor Browser sets it to 1 at the moment.)

Child Tickets

TicketTypeStatusOwnerSummary
#6772enhancementnewFall back to alternative OR or Dir port if the current fails
#24322defectclosedmake IPv6-only clients bootstrap without needing config changes.
#27490enhancementclosedneelWhen ClientPreferIPv6ORPort is set to auto, and a relay is being chosen for a directory or orport connection, prefer IPv4 or IPv6 at random
#27491enhancementassignedneelPrefer IPv4 or IPv6 based on the number of failures
#27492enhancementassignedneelTry IPv4 or IPv6 more often based on public or private IP addresses
#27647enhancementassignedneelWhen randomly choosing IPv4 or IPv6, set IPv6 probability based on IPv6 weight
#27648enhancementassignedneelStop setting the IPv6 preferred flag on nodes
#27736defectassignedMake sure that Tor doesn't build an IPv4 and an IPv6 connection to the same relay
#28057enhancementnewWhen randomly choosing IPv4 or IPv6, log better IPv6 preference info
#28962defectnewcircuits are not both ready. Stalling conn.

Change History (23)

comment:1 in reply to:  description Changed 3 years ago by teor

Replying to teor:

However, Tor Browser sets it to 1 at the moment.

Tor Browser 5.0.4 doesn't have ClientUseIPv6 set.

comment:2 Changed 3 years ago by teor

We could just switch preferred address families on (purportedly) dual-stack clients when a connection fails. That seems simpler.

As long as we connect to 4 authorities in the authority-only schedule, it's no worse than 0.2.7 for single-stack clients.

comment:3 Changed 3 years ago by nickm

Points: medium

comment:4 Changed 3 years ago by nickm

Points: mediummedium/large

comment:5 Changed 3 years ago by isabela

Keywords: isaremoved added
Milestone: Tor: 0.2.9.x-finalTor: 0.2.???

comment:6 Changed 2 years ago by teor

Milestone: Tor: 0.2.???Tor: 0.3.???

Milestone renamed

comment:7 Changed 2 years ago by nickm

Keywords: tor-03-unspecified-201612 added
Milestone: Tor: 0.3.???Tor: unspecified

Finally admitting that 0.3.??? was a euphemism for Tor: unspecified all along.

comment:8 Changed 2 years ago by nickm

Keywords: tor-03-unspecified-201612 removed

Remove an old triaging keyword.

comment:9 Changed 2 years ago by nickm

Keywords: isaremoved removed

comment:10 Changed 22 months ago by nickm

Keywords: tor-client ipv6 added

comment:11 Changed 19 months ago by teor

Summary: Make ClientPreferIPv6ORPort/DirPort smarterMake ClientPreferIPv6ORPort smarter

There are no IPv6 DirPorts (any more).

comment:12 Changed 9 months ago by neel

Cc: neel@… added

comment:13 Changed 9 months ago by neel

Owner: set to neel
Status: newassigned

comment:14 Changed 8 months ago by neel

I am interested in this bug.

About this line in this bug report's message:

Ignoring localhost (tor_addr_is_localhost) and link-local addresses (a new tor_addr_is_link_local)

I know that the Tor codebase has diverged significantly since the time the report was posted. But with today's codebase, I know we have this function: tor_addr_is_internal_() and tor_addr_is_internal().

Would it be okay for me to create a function like tor_addr_is_local() which checks if the address given is either (a) localhost or (b) local link?

Also, when we scan the addresses, is it okay for me to skip the proposed tor_addr_is_local() if ClientRejectInternalAddresses is 0 (such as a testing network or chutney)?

comment:15 Changed 8 months ago by neel

Also, I am thinking about making tor_addr_is_local() a macro for tor_addr_is_internal_() like we do with tor_addr_is_internal(), but add a flag for tor_addr_is_internal_() that determines whether we should only check local networks (where tor_addr_is_local() would use 1 and tor_addr_is_internal() would use 0). Is this okay? Or should I just make a tor_addr_is_local_()?

comment:16 Changed 8 months ago by teor

Checking local addresses is optional, and it might be unreliable.

Here are the things that must happen for this code to work:

  1. Work out how to test the new code, and run those tests on the master branch
  2. Make ClientPreferIPv6ORPort into an autobool
  3. When ClientPreferIPv6ORPort is set to auto, and a relay is being chosen for a directory or orport connection, prefer IPv4 or IPv6 at random

Here are the things that must happen so that users can enable auto without warnings or disconnections:

  1. If the machine instantly fails IPv4 or IPv6 connections, stop those connections for a while
  2. When there are a lot more IPv4 than IPv6 failures, don't try IPv4 as much
  3. When there are a lot more IPv6 than IPv4 failures, don't try IPv6 as much
  4. After a while, forget old failures

Here are the things that we can do to make bootstrap faster:

  1. If the machine has public IPv4 addresses, try IPv4 a lot more often
  2. If the machine has public IPv6 addresses, try IPv6 a lot more often
  3. If the machine has private IPv4 addresses, try IPv4 a little bit more often
  4. If the machine has private IPv6 addresses (excluding link-local addresses), try IPv6 a little bit more often

When we've tested the code in a few releases, we can:

  1. Set the default for ClientPreferIPv6ORPort to auto (infer), rather than 0 (IPv4)

I suggest that you open child tickets for 0, 1-2, 3, 4-6, 7-10, and 11.

comment:17 Changed 7 months ago by teor

I also opened #27647 to adjust the initial IPv6 weight. We need to do it before most clients use this feature (before step 11). It seems to fit with steps 7-10.

comment:18 Changed 7 months ago by teor

I also opened #27648 to remove the IPv6 preferred flag from nodes. For relays, we can just choose at random. For bridges, we should choose the configured address more often. It also fits well with steps 7-10.

comment:19 Changed 7 months ago by teor

Milestone: Tor: unspecifiedTor: 0.3.6.x-final

Let's look at this for merge in 0.3.6, if enough of the child tickets have been completed.

comment:20 Changed 6 months ago by neel

I have one more question: should I finish #27491 and #27492 (and base it on #27490) before #27490 will get merged, or will #27490 get merged without #27491 or #27492?

comment:21 Changed 5 months ago by nickm

Milestone: Tor: 0.3.6.x-finalTor: 0.4.0.x-final

Tor 0.3.6.x has been renamed to 0.4.0.x.

comment:22 Changed 5 months ago by teor

Type: defectenhancement

comment:23 Changed 3 months ago by nickm

Keywords: 040-deferred-201915 added
Milestone: Tor: 0.4.0.x-finalTor: unspecified

Deferring some tickets from 0.4.0 without proposing them for later. Please tag with 041-proposed if you want to do them.

Note: See TracTickets for help on using tickets.