Skip to content

Commit 5bd7e9c

Browse files
CAFxXbradfitz
authored andcommitted
net: enable TCP keepalives by default
This is just the first step in attempting to make all network connection have timeouts as a "safe default". TCP keepalives only protect against certain classes of network and host issues (e.g. server/OS crash), but do nothing against application-level issues (e.g. an application that accepts connections but then fails to serve requests). The actual keep-alive duration (15s) is chosen to cause broken connections to be closed after 2~3 minutes (depending on the OS, see #23549 for details). We don't make the actual default value part of the public API for a number of reasons: - because it's not very useful by itself: as discussed in #23549 the actual "timeout" after which the connection is torn down is duration*(KEEPCNT+1), and we use the OS-wide value for KEEPCNT because there's currently no way to set it from Go. - because it may change in the future: if users need to rely on a specific value they should explicitly set this value instead of relying on the default. Fixes #23459 Change-Id: I348c03be97588d5001e6de0f377e7a93b51957fd Reviewed-on: https://go-review.googlesource.com/c/107196 Run-TryBot: Ian Lance Taylor <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Brad Fitzpatrick <[email protected]>
1 parent 1adbb2b commit 5bd7e9c

File tree

3 files changed

+32
-16
lines changed

3 files changed

+32
-16
lines changed

src/net/dial.go

+10-4
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,10 @@ type Dialer struct {
6565

6666
// KeepAlive specifies the keep-alive period for an active
6767
// network connection.
68-
// If zero, keep-alives are not enabled. Network protocols
68+
// If zero, keep-alives are enabled if supported by the protocol
69+
// and operating system. Network protocols or operating systems
6970
// that do not support keep-alives ignore this field.
71+
// If negative, keep-alives are disabled.
7072
KeepAlive time.Duration
7173

7274
// Resolver optionally specifies an alternate resolver to use.
@@ -418,10 +420,14 @@ func (d *Dialer) DialContext(ctx context.Context, network, address string) (Conn
418420
return nil, err
419421
}
420422

421-
if tc, ok := c.(*TCPConn); ok && d.KeepAlive > 0 {
423+
if tc, ok := c.(*TCPConn); ok && d.KeepAlive >= 0 {
422424
setKeepAlive(tc.fd, true)
423-
setKeepAlivePeriod(tc.fd, d.KeepAlive)
424-
testHookSetKeepAlive()
425+
ka := d.KeepAlive
426+
if d.KeepAlive == 0 {
427+
ka = 15 * time.Second
428+
}
429+
setKeepAlivePeriod(tc.fd, ka)
430+
testHookSetKeepAlive(ka)
425431
}
426432
return c, nil
427433
}

src/net/dial_test.go

+17-10
Original file line numberDiff line numberDiff line change
@@ -729,22 +729,29 @@ func TestDialerKeepAlive(t *testing.T) {
729729
if err := ls.buildup(handler); err != nil {
730730
t.Fatal(err)
731731
}
732-
defer func() { testHookSetKeepAlive = func() {} }()
732+
defer func() { testHookSetKeepAlive = func(time.Duration) {} }()
733733

734-
for _, keepAlive := range []bool{false, true} {
735-
got := false
736-
testHookSetKeepAlive = func() { got = true }
737-
var d Dialer
738-
if keepAlive {
739-
d.KeepAlive = 30 * time.Second
740-
}
734+
tests := []struct {
735+
ka time.Duration
736+
expected time.Duration
737+
}{
738+
{-1, -1},
739+
{0, 15 * time.Second},
740+
{5 * time.Second, 5 * time.Second},
741+
{30 * time.Second, 30 * time.Second},
742+
}
743+
744+
for _, test := range tests {
745+
var got time.Duration = -1
746+
testHookSetKeepAlive = func(d time.Duration) { got = d }
747+
d := Dialer{KeepAlive: test.ka}
741748
c, err := d.Dial("tcp", ls.Listener.Addr().String())
742749
if err != nil {
743750
t.Fatal(err)
744751
}
745752
c.Close()
746-
if got != keepAlive {
747-
t.Errorf("Dialer.KeepAlive = %v: SetKeepAlive called = %v, want %v", d.KeepAlive, got, !got)
753+
if got != test.expected {
754+
t.Errorf("Dialer.KeepAlive = %v: SetKeepAlive set to %v, want %v", d.KeepAlive, got, test.expected)
748755
}
749756
}
750757
}

src/net/hook.go

+5-2
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
package net
66

7-
import "context"
7+
import (
8+
"context"
9+
"time"
10+
)
811

912
var (
1013
// if non-nil, overrides dialTCP.
@@ -19,5 +22,5 @@ var (
1922
) ([]IPAddr, error) {
2023
return fn(ctx, network, host)
2124
}
22-
testHookSetKeepAlive = func() {}
25+
testHookSetKeepAlive = func(time.Duration) {}
2326
)

0 commit comments

Comments
 (0)