Filename: 306-ipv6-happy-eyeballs.txt Title: A Tor Implementation of IPv6 Happy Eyeballs Author: Neel Chauhan Created: 25-Jun-2019 Supercedes: 299 Status: Open Ticket: https://trac.torproject.org/projects/tor/ticket/29801 1. Introduction As IPv4 address space becomes scarce, ISPs and organizations will deploy IPv6 in their networks. Right now, Tor clients connect to guards using IPv4 connectivity by default. When networks first transition to IPv6, both IPv4 and IPv6 will be enabled on most networks in a so-called "dual-stack" configuration. This is to not break existing IPv4-only applications while enabling IPv6 connectivity. However, IPv6 connectivity may be unreliable and clients should be able to connect to the guard using the most reliable technology, whether IPv4 or IPv6. In ticket #27490, we introduced the option ClientAutoIPv6ORPort which lets a client randomly choose between IPv4 or IPv6. However, this random decision does not take into account unreliable connectivity or falling back to the competing IP version should one be unreliable or unavailable. One way to select between IPv4 and IPv6 on a dual-stack network is a so-called "Happy Eyeballs" algorithm as per RFC 8305. In one, a client attempts the preferred IP family, whether IPv4 or IPv6. Should it work, the client sticks with the preferred IP family. Otherwise, the client attempts the alternate version. This means if a dual-stack client has both IPv4 and IPv6, and IPv6 is unreliable, preferred or not, the client uses IPv4, and vice versa. However, if IPv4 and IPv6 are both equally reliable, and IPv6 is preferred, we use IPv6. In Proposal 299, we have attempted a IP fallback mechanism using failure counters and preferring IPv4 and IPv6 based on the state of the counters. However, Prop299 was not standard Happy Eyeballs and an alternative, standards-compliant proposal was requested in [P299-TRAC] to avoid issues from complexity caused by randomness. This proposal describes a Tor implementation of Happy Eyeballs and is intended as a successor to Proposal 299. 2. Address/Relay Selection This section describes the necessary changes for address selection to implement Prop306. 2.1. Extend Info Structure Changes To be able to handle Happy Eyeballs in Tor, we will need to modify the data structures used for connections to guards, namely the extend info structure. The extend info structure should contain both an IPv4 and an IPv6 address. This will allow us to try IPv4 and the IPv6 addresses should both be available on a relay and the client is dual-stack. When parsing relay descriptors and filling in the extend info data structure, we need to fill in both the IPv4 and IPv6 address if they both are available. If only one family is available for a relay (IPv4 or IPv6), we should fill in the address for preferred family and leave the alternate family null. 2.2. Relay Selection Changes In Proposal 283, we have allowed microdescriptor consensus documents to contain IPv6 addresses. As clients download microdescriptors, Prop283 makes it possible to implement Prop306. When we select candidates for the entry guard, we should select at least one relay with an IPv6 address. This makes it possible for an IPv6-only client to bootstrap. Otherwise we would have failures if all the selected guard candidates only have IPv4 addresses. 3. Relay Connections If there is an existing authenticated connection, we should use it similar to how we used it pre-Prop306. If there is no existing authenticated connection for an extend info, we should attempt to connect using the first available, allowed, and preferred address. We should also allow falling back to the alternate address. For this, three alternate designs will be given. 3.1. Proposed Designs This subsection will have three proposed designs for connecting to relays via IPv4 and IPv6 in a Tor implementation of Happy Eyeballs. These proposed designs will have some tradeoffs, including: * Launching multiple TCP connections places up to 2x extra socket load on dual-stack relays and authorities, because both connections may succeed. * Launching multiple TLS connections places up to 2x the CPU load on dual-stack relays and authorities, because both connections may succeed. * Increasing the delay between connections mitigates the above issues, but reduces perceived performance, particularly at bootstrap time (pre-emptive circuits hide these delays after bootstrap). The proposed designs are as listed as follows: * Section 3.1.1: First Successful Authentication * Section 3.1.2: TCP Connection to Preferred Address On First Authenticated Connection * Section 3.1.3: TCP Connection to Preferred Address On First TCP Success 3.1.1. First Successful Authentication In this design, Tor will first connect to the preferred address and attempt to authenticate. After a 1.5 second delay (based on Onionperf data), Tor will connect to the alternate address and try to authenticate. On the first successful authenticated connection, we close the other connection. This design places the least connection load on the network, but might add extra TLS load. 3.1.2. TCP Connection to Preferred Address On First Authenticated Connection This design attempts a TCP connection to a preferred address. On a failure or a 1.5 second delay, we try the alternative address. On the first successful TCP connection Tor attempts to authenticate immediately. On the first authentication success, Tor closes the other connection. This design is the most reliable for clients, but increases the connection load on dual-stack guards and authorities. For instance, this can be used to amplify a DoS attack on the Tor network. 3.1.3. TCP Connection to Preferred Address On First TCP Success In this design, we will connect via TCP to the first preferred address. On a failure or after a 1.5 second delay, we attempt to connect via TCP to the alternate address. On a success, Tor attempts to authenticate and closes the other connection. This design is the closest to RFC 8305 and is similar to how Happy Eyeballs is implemented in a web browser. 3.2. Recommendations for Implementation of Section 3.1 Proposals We should start with implementing and testing the implementation as described in Section 3.1.1 (First Successful Authentication), and then doing the same for the implementations described in 3.1.2 and 3.1.3 if desired or required. 3.3. Handling Connection Successes And Failures Should a connection to a guard succeed and is authenticated via TLS, we can then use the connection. In this case, we should cancel all other connection timers and in-progress connections. Cancelling the timers is necessary so we don't attempt new unnecessary connections when our existing connection is successful, preventing denial-of-service risks. However, if we fail all available and allowed connections, we should tell the rest of Tor that the connection has failed. This is so we can attempt another guard relay. 3.4. Connection Attempt Delays As mentioned in [TEOR-P306-REP], initially, clients should prefer IPv4 by default. The Connection Attempt Delay, or delay between IPv4 and IPv6 connections should be 1.5 seconds. This is to avoid the overhead from tunneled IPv6 connections. The Minimum Connection Attempt Delay should not be dynamically adjusted as it adds privacy risks. This value should be fixed at 10 ms as per RFC 8305 and could be adjusted using a proposed consensus parameter called ConnectionAttemptDelay. ConnectionAttemptDelay should be in milliseconds. The Maximum Connection Attempt Delay should also not be dynamically adjusted for privacy reasons, but the maximum should be higher than the RFC 8305 recommendation of 2 seconds. For Tor, we should make this timeout value 30 seconds to match Tor's existing timeout. We should also make it possible for users to set the Maximum Connection Attempt value higher for slower and higher-latency networks such as dial-up and satellite. 4. Option Changes As we enable IPv6-enabled clients to connect out of the box, we should adjust the default options to enable IPv6 while not breaking IPv4-only clients. 4.1. New Default Options for Prop306 The new default options should be: * ClientUseIPv4 as 1 (to enable IPv4) * ClientUseIPv6 as 1 (to enable IPv6) * ClientPreferIPv6ORPort as 0 (for load-balancing reasons so we don't overload IPv6-only guards) One thing to note is that clients should be able to connect with the above options on IPv4-only, dual-stack, and IPv6-only networks, and they should also work if ClientPreferIPv6ORPort is 1. This means we shouldn't expect IPv4 or IPv6 to work if ClientUseIPv4 or ClientUseIPv6 is set. When the majority of clients are IPv6-capable, we could set the default value of ClientPreferIPv6ORPort to 1 in order to take advantage of IPv6. 4.2. Prop306 Consensus Parameters We could have the following consensus parameters: * ClientUseIPv6 * ClientPreferIPv6ORPort (when most of the guards have IPv6 and it is fast) Should we have the consenus parameters, the values for these options should be set to the values of the similarly-named options as described in Section 4.1 including the consideration for ClientPreferIPv6ORPort. 5. Statistics 5.1. Relay Statistics Relays could measure the number of successful IPv4 and IPv6 connections. We could also send this information to directory authorities. However, should we implement Section 5.1, we should consider the privacy implications of these statistics, and whether they should be public or not. 5.2. Client Heartbeat Messages In a Tor session, we should count the number of IPv4 and IPv6 connections to ORPorts, and distinguish between authenticated (relay, authority reachability) and unauthenticated (client, bridge) connections. These statistics should be included in the Heartbeat logs. 6. Deploying Prop306 This section describes the information necessary for deployment of Prop306 on Tor clients and in Tor Browser. 6.1. Initial Feasibility Testing We should test this proposal with the following scenarios: * Different combinations of values for the options ClientUseIPv4, ClientUseIPv6, and ClientPreferIPv6ORPort on IPv4-only, IPv6-only, and dual-stack connections * Dual-stack connections of different technologies, including high-bandwidth and low-latency (e.g. fiber), moderate-bandwidth and moderate-latency (e.g. DSL, LTE), and high-latency and low-bandwidth (e.g. satellite, dial-up) to see if Prop306 is reliable and feasible 6.2. Minimum Viable Prop306 Product The mimumum viable product for Prop306 must include the following: * Implementation of one of the algorithms in Section 3.1 along with the changes described in Sections 2.1 and 2.2 * The Connection Success/Failure mechanism in Section 3.3 and Connection Delay mechanism in Section 3.4 (the consensus parameter is optional) * A default setup capable of both IPv4 and IPv6 connections with the options described in Section 4.1 6.3. Optional Features Some features which are optional include: * Consensus Parameter ConnectionAttemptDelay (Section 3.4) - We will need this if the Minimum Connection Attempt Delay needs to be dynamically adjusted * Consensus Parameters ClientUseIPv6 (Section 4.2), and ClientPreferIPv6ORPort (Section 4.2) - We will need this if we desire the ability for clients to prefer IPv6 when the majority of clients and relays are IPv6-capable without changing the configuration * Prop306 Statistics (Section 5) - While optional, this may be useful for debugging and reliability testing, and metrics on IPv4 vs. IPv6 7. Acknowledgments Thank you so much to teor for the discussion of the happy eyeballs proposal. I wouldn't have been able to do this has it not been for your help. 8. Refrences [P299-TRAC]: https://trac.torproject.org/projects/tor/ticket/29801 [TEOR-P306-REP]: https://lists.torproject.org/pipermail/tor-dev/2019-July/013919.html