diff --git a/network/sockopts.go b/network/sockopts.go index 7d537e4..1b6c32c 100644 --- a/network/sockopts.go +++ b/network/sockopts.go @@ -20,7 +20,7 @@ func SetServerSocketOptions(conn net.Conn, bufferSize int) error { } func setCommonSocketOptions(conn *net.TCPConn) error { - if err := conn.SetKeepAliveConfig(net.KeepAliveConfig{ + if err := applyKeepAlive(conn, net.KeepAliveConfig{ Enable: true, Idle: DefaultKeepAliveIdle, Interval: DefaultKeepAliveInterval, diff --git a/network/sockopts_keepalive.go b/network/sockopts_keepalive.go new file mode 100644 index 0000000..0f8cb42 --- /dev/null +++ b/network/sockopts_keepalive.go @@ -0,0 +1,11 @@ +//go:build !openbsd + +package network + +import "net" + +// applyKeepAlive enables TCP keepalive on conn and applies the per-socket +// idle/interval/count tuning from cfg. +func applyKeepAlive(conn *net.TCPConn, cfg net.KeepAliveConfig) error { + return conn.SetKeepAliveConfig(cfg) //nolint: wrapcheck +} diff --git a/network/sockopts_keepalive_openbsd.go b/network/sockopts_keepalive_openbsd.go new file mode 100644 index 0000000..6c12f7d --- /dev/null +++ b/network/sockopts_keepalive_openbsd.go @@ -0,0 +1,20 @@ +package network + +import "net" + +// applyKeepAlive enables (or disables) TCP keepalive on conn. +// +// OpenBSD has no user-settable per-socket TCP keepalive options: TCP_KEEPIDLE, +// TCP_KEEPINTVL and TCP_KEEPCNT do not exist on OpenBSD, and Go's +// (*TCPConn).SetKeepAliveConfig therefore returns ENOPROTOOPT ("protocol not +// available") for any non-negative Idle/Interval/Count value (see +// src/net/tcpsockopt_openbsd.go in the Go source tree). Calling +// SetKeepAliveConfig with mtg's defaults (zero values) breaks every accepted +// listener connection and every outbound dial on OpenBSD. +// +// On OpenBSD we only flip SO_KEEPALIVE on or off; the keepalive timing is +// controlled system-wide via the sysctl knobs net.inet.tcp.keepidle and +// net.inet.tcp.keepintvl. +func applyKeepAlive(conn *net.TCPConn, cfg net.KeepAliveConfig) error { + return conn.SetKeepAlive(cfg.Enable) //nolint: wrapcheck +} diff --git a/network/v2/sockopts.go b/network/v2/sockopts.go index 933c76f..edbc47a 100644 --- a/network/v2/sockopts.go +++ b/network/v2/sockopts.go @@ -6,7 +6,7 @@ import ( ) func setCommonSocketOptions(conn *net.TCPConn, keepAliveConfig net.KeepAliveConfig) error { - if err := conn.SetKeepAliveConfig(keepAliveConfig); err != nil { + if err := applyKeepAlive(conn, keepAliveConfig); err != nil { return fmt.Errorf("cannot configure TCP keepalive: %w", err) } diff --git a/network/v2/sockopts_keepalive.go b/network/v2/sockopts_keepalive.go new file mode 100644 index 0000000..0f8cb42 --- /dev/null +++ b/network/v2/sockopts_keepalive.go @@ -0,0 +1,11 @@ +//go:build !openbsd + +package network + +import "net" + +// applyKeepAlive enables TCP keepalive on conn and applies the per-socket +// idle/interval/count tuning from cfg. +func applyKeepAlive(conn *net.TCPConn, cfg net.KeepAliveConfig) error { + return conn.SetKeepAliveConfig(cfg) //nolint: wrapcheck +} diff --git a/network/v2/sockopts_keepalive_openbsd.go b/network/v2/sockopts_keepalive_openbsd.go new file mode 100644 index 0000000..6c12f7d --- /dev/null +++ b/network/v2/sockopts_keepalive_openbsd.go @@ -0,0 +1,20 @@ +package network + +import "net" + +// applyKeepAlive enables (or disables) TCP keepalive on conn. +// +// OpenBSD has no user-settable per-socket TCP keepalive options: TCP_KEEPIDLE, +// TCP_KEEPINTVL and TCP_KEEPCNT do not exist on OpenBSD, and Go's +// (*TCPConn).SetKeepAliveConfig therefore returns ENOPROTOOPT ("protocol not +// available") for any non-negative Idle/Interval/Count value (see +// src/net/tcpsockopt_openbsd.go in the Go source tree). Calling +// SetKeepAliveConfig with mtg's defaults (zero values) breaks every accepted +// listener connection and every outbound dial on OpenBSD. +// +// On OpenBSD we only flip SO_KEEPALIVE on or off; the keepalive timing is +// controlled system-wide via the sysctl knobs net.inet.tcp.keepidle and +// net.inet.tcp.keepintvl. +func applyKeepAlive(conn *net.TCPConn, cfg net.KeepAliveConfig) error { + return conn.SetKeepAlive(cfg.Enable) //nolint: wrapcheck +}