Filename: xxx-ip-failure-count.txt Title: Preferring IPv4 or IPv6 based on IP Version Failure Count Author: Neel Chauhan Created: 25-Jan-2019 Status: Draft Ticket: https://trac.torproject.org/projects/tor/ticket/27491 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 adds preliminary "happy eyeballs" support. If set, this lets a client randomly choose between IPv4 or IPv6. However, this random decision does not take into account unreliable connectivity or network failures of an IP family. A successful Tor implementation of the happy eyeballs algorithm requires that unreliable connectivity on IPv4 and IPv6 are taken into consideration. This proposal describes an algorithm to take into account network failures in the random decision used for choosing an IP family and the data fields used by the algorithm. 2. Failure Counter Design I propose that the failure counter uses the following fields: * IPv4 failure count * IPv4 failure count from no route (autofail) * IPv6 failure count * IPv6 failure count from no route (autofail) These entries will exist as internal counters for the current session, and as a list of the previous counts of these counters from previous sessions in the state file. These values will be stored as 32-bit unsigned integers for the current session, and as comma seperated values in the statefile. The list capacity will be the 4 most recent sessions for each field above stored in the state file with the least recent first. This is for the following reasons: * We can forget about the oldest sessions without having to keep the exact timestamp when a client failed. This prevents an attacker from getting detailed failure information from the state file. * Some clients (mobile phones, laptops) may switch between networks of which may be more or less reliable than the previous in terms of IPv4 or IPv6. In this case, it makes less sense to remember old failures caused on a different network from the current one. When Tor is being closed, and there are less than four entries for each field, we will append the current session at the end. If there are four entries, we will remove the oldest entry and then add the current session's values at Tor's shutdown. 3. Failure Probability Calculation The failure count of one IP version will increase the probability of the other IP version. For instance, a failure of IPv4 will increase the IPv6 probability, and vice versa. When the IP version is being chosen, I propose that these values will be included in the guard selection code: * IPv4 failure points * IPv6 failure points * Total failure points These values will be stored as 32-bit unsigned integers. A generic failure of an IP version will add one point to the failure point count values of the particular IP version which failed. A failure of an IP version from a "no route" error which happens when connections automatically fail will be counted as two failure points for the automatically failed version. The failure points for both IPv4 and IPv6 is sum of the values in the state file plus the current session's failure values. The total failure points is a sum of the IPv4 and IPv6 failure points. The probability of a particular IP version is the failure points of the other version divided by the total number of failure points, multiplied by 8 and stored as an integer. We will call this value the summarized failure point value (SFPV). The reason for this summarization is to emulate a probability in 1/8 intervals by the random number generator. In the random number generator, we will choose a random number between 0 and 8. If the random number is less than the IPv6 SFPV, we will choose IPv4. If it is equal or greater, we will choose IPv6. If the probability is 0/8 with a SFPV value of 0, it will be rounded to 1/8 with a SFPV of 1. Also, if the probability is 8/8 with a SFPV of 8, it will be rounded to 7/8 with a SFPV of 7. The reason for this is to accomodate mobile clients which could change networks at any time (e.g. WiFi to cellular) which may be more or less reliable in terms of a particular IP family when compared to the previous network of the client. 4. Acknowledgements Thank you teor for aiding me with the implementation of Happy Eyeballs in Tor. This would not have been possible if it weren't for you.