• Mikio Hara's avatar
    net: implement TCP connection setup with fast failover · 89b26760
    Mikio Hara authored
    This CL adds minimal support of Happy Eyeballs-like TCP connection
    setup to Dialer API. Happy Eyeballs and derivation techniques are
    described in the following:
    
    - Happy Eyeballs: Success with Dual-Stack Hosts
      http://tools.ietf.org/html/rfc6555
    
    - Analysing Dual Stack Behaviour and IPv6 Quality
      http://www.potaroo.net/presentations/2012-04-17-dual-stack-quality.pdf
    
    Usually, the techniques consist of three components below.
    
    - DNS query racers, that run A and AAAA queries in parallel or series
    - A short list of destination addresses
    - TCP SYN racers, that run IPv4 and IPv6 transport in parallel or series
    
    This CL implements only the latter two. The existing DNS query
    component gathers together A and AAAA records in series, so we don't
    touch it here. This CL just uses extended resolveInternetAddr and makes
    it possible to run multiple Dial racers in parallel.
    
    For example, when the given destination is a DNS name and the name has
    multiple address family A and AAAA records, and it happens on the TCP
    wildcard network "tcp" with DualStack=true like the following:
    
    (&net.Dialer{DualStack: true}).Dial("tcp", "www.example.com:80")
    
    The function will return a first established connection either TCP over
    IPv4 or TCP over IPv6, and close the other connection internally.
    
    Fixes #3610.
    Fixes #5267.
    
    Benchmark results on freebsd/amd64 virtual machine, tip vs. tip+12416043:
    
    benchmark                           old ns/op    new ns/op    delta
    BenchmarkTCP4OneShot                    50696        52141   +2.85%
    BenchmarkTCP4OneShotTimeout             65775        66426   +0.99%
    BenchmarkTCP4Persistent                 10986        10457   -4.82%
    BenchmarkTCP4PersistentTimeout          11207        10445   -6.80%
    BenchmarkTCP6OneShot                    62009        63718   +2.76%
    BenchmarkTCP6OneShotTimeout             78351        79138   +1.00%
    BenchmarkTCP6Persistent                 14695        14659   -0.24%
    BenchmarkTCP6PersistentTimeout          15032        14646   -2.57%
    BenchmarkTCP4ConcurrentReadWrite         7215         6217  -13.83%
    BenchmarkTCP6ConcurrentReadWrite         7528         7493   -0.46%
    
    benchmark                          old allocs   new allocs    delta
    BenchmarkTCP4OneShot                       36           36    0.00%
    BenchmarkTCP4OneShotTimeout                36           36    0.00%
    BenchmarkTCP4Persistent                     0            0     n/a%
    BenchmarkTCP4PersistentTimeout              0            0     n/a%
    BenchmarkTCP6OneShot                       37           37    0.00%
    BenchmarkTCP6OneShotTimeout                37           37    0.00%
    BenchmarkTCP6Persistent                     0            0     n/a%
    BenchmarkTCP6PersistentTimeout              0            0     n/a%
    BenchmarkTCP4ConcurrentReadWrite            0            0     n/a%
    BenchmarkTCP6ConcurrentReadWrite            0            0     n/a%
    
    benchmark                           old bytes    new bytes    delta
    BenchmarkTCP4OneShot                     2500         2503    0.12%
    BenchmarkTCP4OneShotTimeout              2508         2505   -0.12%
    BenchmarkTCP4Persistent                     0            0     n/a%
    BenchmarkTCP4PersistentTimeout              0            0     n/a%
    BenchmarkTCP6OneShot                     2713         2707   -0.22%
    BenchmarkTCP6OneShotTimeout              2722         2720   -0.07%
    BenchmarkTCP6Persistent                     0            0     n/a%
    BenchmarkTCP6PersistentTimeout              0            0     n/a%
    BenchmarkTCP4ConcurrentReadWrite            0            0     n/a%
    BenchmarkTCP6ConcurrentReadWrite            0            0     n/a%
    
    R=golang-dev, bradfitz, nightlyone, rsc
    CC=golang-dev
    https://golang.org/cl/12416043
    89b26760
dialgoogle_test.go 5.83 KB