CARVIEW |
Navigation Menu
-
Notifications
You must be signed in to change notification settings - Fork 18.3k
Description
TCP keep-alives are enabled by setting the SO_KEEPALIVE
socket option. When keep-alives are enabled, the operating system will probe idle connections and close connections with an unresponsive peer.
Linux, FreeBSD, and Windows permit configuring keep-alive probes with the TCP_KEEPIDLE
, TCP_KEEPINTVL
, and TCP_KEEPCNT
socket options. (Darwin appears to call TCP_KEEPIDLE
TCP_KEEPALIVE
.) These options set the idle duration before the first probe is sent, the interval between probes, and the maximum number of probes to send before declaring a connection dead, respectively.
The net
package permits configuring TCP keepalive behavior with:
Setting the keep-alive period sets both TCP_KEEPIDLE
and TCP_KEEPINTVL
. There is no way in the net
package to set TCP_KEEPCNT
or otherwise configure how long it takes to declare a connection dead. There is no way to set different values for the idle period and the probe interval.
Since Go 1.12 (https://go.dev/cl/107196), the net
package has set TCP_KEEPIDLE
and TCP_KEEPINTVL
on all new sockets to 15 seconds by default.
This 15 second value is not appropriate for all uses. For example, #48622 complains that the default keep-alive settings cause excessive CPU consumption on mobile devices due to frequent probes. Reducing the time until the first keep-alive probe is sent with Dialer.KeepAlive
also reduces the time between probes; setting the period to five minutes will cause the kernel to take ~50 minutes to detect a dead connection.
I propose that we change the net
package functions which set the keep-alive period to set TCP_KEEPIDLE
, but not TCP_KEEPINTVL
. It is surprising and not useful for a "keep-alive period" of ten minutes to translate into a connection being declared dead only after several hours of unresponsiveness.
I propose that we also add a finer-grained API for configuring keep-alive behavior. I haven't exhaustively surveyed the operating systems we support, but Linux, Windows, Darwin, and at least one BSD all appear to support the same three settings. It's possible to set these via golang.org/x/sys
, but providing a common way to configure them in the net
package seems reasonable.
The following API also permits for enabling keep-alives on a connection while using the operating system default keep-alive configuration (set KeepAliveConfig.Enable
, set the other fields to -1).
package net
// KeepAliveConfig contains TCP keep-alive options.
//
// If the Idle, Interval, or Count fields are zero, a default value is chosen.
// If a field is negative, the operating system default is used.
type KeepAliveConfig struct {
// If Enable is true, keep-alive probes are enabled.
Enable bool
// Idle is the time that the connection must be idle before
// the first keep-alive probe is sent.
Idle time.Duration
// Interval is the time between keep-alive probes.
Interval time.Duration
// Count is the maximum number of keep-alive probes that
// should be sent before dropping a connection.
Count int
}
type Dialer { // contains existing unchanged fields
// KeepAlive specifies the interval between keep-alive
// probes for an active network connection.
//
// KeepAlive is ignored if KeepAliveConfig.Enable is true.
//
// If zero, keep-alive probes are sent with a default value
// (currently 15 seconds), if supported by the protocol and operating
// system. Network protocols or operating systems that do
// not support keep-alives ignore this field.
// If negative and KeepAliveConfig.Enable is false, keep-alive probes are disabled.
KeepAlive time.Duration
// KeepAliveConfig specifies the keep-alive probe configuration
// for an active network connection, when supported by the
// protocol and operating system.
//
// If KeepAliveConfig.Enable is true, keep-alives probes are enabled.
// If KeepAliveConfig.Enable is false and KeepAlive is negative,
// keep-alive probes are disabled.
KeepAliveConfig KeepAliveConfig
}
type ListenConfig {
// same fields as Dialer above
}
// SetKeepAliveConfig configures keep-alive messages sent by the operating system.
func (c *TCPConn) SetKeepAliveConfig(config KeepAliveConfig) error {}