Commit 0d8366e2 authored by Paul Marks's avatar Paul Marks

net: add sequential and RFC 6555-compliant TCP dialing.

dialSerial connects to a list of addresses in sequence.  If a
timeout is specified, then each address gets an equal fraction of the
remaining time, with a magic constant (2 seconds) to prevent
"dial a million addresses" from allotting zero time to each.

Normally, net.Dial passes the DNS stub resolver's output to dialSerial.
If an error occurs (like destination/port unreachable), it quickly skips
to the next address, but a blackhole in the network will cause the
connection to hang until the timeout elapses.  This is how UNIXy clients
traditionally behave, and is usually sufficient for non-broken networks.

The DualStack flag enables dialParallel, which implements Happy Eyeballs
by racing two dialSerial goroutines, giving the preferred family a
head start (300ms by default).  This allows clients to avoid long
timeouts when the network blackholes IPv4 xor IPv6.

Fixes #8453
Fixes #8455
Fixes #8847

Change-Id: Ie415809c9226a1f7342b0217dcdd8f224ae19058
Reviewed-on: https://go-review.googlesource.com/8768Reviewed-by: 's avatarMikio Hara <mikioh.mikioh@gmail.com>
Reviewed-by: 's avatarBrad Fitzpatrick <bradfitz@golang.org>
parent 12b05bf8
This diff is collapsed.
This diff is collapsed.
......@@ -5,6 +5,7 @@
package net
var (
testHookDialTCP = dialTCP
testHookHostsPath = "/etc/hosts"
testHookLookupIP = func(fn func(string) ([]IPAddr, error), host string) ([]IPAddr, error) { return fn(host) }
testHookSetKeepAlive = func() {}
......
......@@ -321,6 +321,7 @@ var (
// For both read and write operations.
errTimeout error = &timeoutError{}
errCanceled = errors.New("operation was canceled")
errClosing = errors.New("use of closed network connection")
ErrWriteToConnected = errors.New("use of WriteTo with pre-connected connection")
)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment