-
Notifications
You must be signed in to change notification settings - Fork 18.5k
Description
Was: net.Dialer.Dial() doesn't respect .KeepAlive
What version of Go are you using (go version)?
$ go version go version go1.12 linux/amd64
Does this issue reproduce with the latest release?
Haven't tried 1.12.1+
What operating system and processor architecture are you using (go env)?
go env Output
$ go env GOARCH="amd64" GOBIN="" GOCACHE="/root/.cache/go-build" GOEXE="" GOFLAGS="" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPATH="/root/go" GOPROXY="" GORACE="" GOROOT="/usr/lib/go" GOTMPDIR="" GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64" GCCGO="gccgo" CC="gcc" CXX="g++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build601953146=/tmp/go-build -gno-record-gcc-switches"
What did you do/see?
For a TLS connection that's been dropped, c.Read() returns a net.Error with e.Timeout()==true after ~18 minutes, apparently due to KeepAlive failure. The connection is closed by the server while the client (laptop running VMWare with Linux) is suspended. Error string:
"read tcp n.n.n.n:p->n.n.n.n:p: read: connection timed out"
The note on 5bd7e9c5 (discussed in #23459) says the default for net.Dialer keepalive failure is just 2-3min. With an explicit KeepAlive, I also see odd waits:
net.Dialer{KeepAlive: 30 * time.Second} 18min
net.Dialer{KeepAlive: 25 * time.Second} 18min
net.Dialer{KeepAlive: 10 * time.Second} 16min
net.Dialer{KeepAlive: 5 * time.Second} <1min, but at least once 18min
Measurements aren't precise; 16-18 minutes could be 1000 or 1024 seconds. Code has:
aDlr := net.Dialer{Timeout: 3*time.Second} // default KeepAlive
aCfgTls := tls.Config{InsecureSkipVerify: true}
aConn, err := tls.DialWithDialer(&aDlr, "tcp", "host:port", &aCfgTls)
if err != nil { return err }
err = aConn.Write(...) // <256 bytes
// brief exchange of short messages
aLen, err := aConn.Read(...)
Also filed #31449 to report that the error due to keepalive doesn't comply with the docs re connection timeout.