From d0c6f86848f257f38d0cfd1e371ea789e7bc9081 Mon Sep 17 00:00:00 2001 From: ValdikSS Date: Thu, 23 Dec 2021 14:02:47 +0300 Subject: [PATCH] Separate TcpKeepAliveIdle and TcpKeepAliveInterval check logic --- transport/internet/sockopt_darwin.go | 28 +++++++++++++++++++++------ transport/internet/sockopt_freebsd.go | 26 +++++++++++++++++++------ transport/internet/sockopt_linux.go | 28 +++++++++++++++++---------- transport/internet/sockopt_windows.go | 4 ++-- 4 files changed, 62 insertions(+), 24 deletions(-) diff --git a/transport/internet/sockopt_darwin.go b/transport/internet/sockopt_darwin.go index 556c8c675b1..22225ce8506 100644 --- a/transport/internet/sockopt_darwin.go +++ b/transport/internet/sockopt_darwin.go @@ -9,6 +9,8 @@ const ( TCP_FASTOPEN_SERVER = 0x01 // nolint: golint,stylecheck // TCP_FASTOPEN_CLIENT is the value to enable TCP fast open on darwin for client connections. TCP_FASTOPEN_CLIENT = 0x02 // nolint: revive,stylecheck + // syscall.TCP_KEEPINTVL is missing on some darwin architectures. + sysTCP_KEEPINTVL = 0x101 // nolint: revive,stylecheck ) func applyOutboundSocketOptions(network string, address string, fd uintptr, config *SocketConfig) error { @@ -24,9 +26,16 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf } } - if config.TcpKeepAliveInterval > 0 { - if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { - return newError("failed to set TCP_KEEPINTVL", err) + if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { + if config.TcpKeepAliveIdle > 0 { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, int(config.TcpKeepAliveInterval)); err != nil { + return newError("failed to set TCP_KEEPINTVL", err) + } + } + if config.TcpKeepAliveInterval > 0 { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, sysTCP_KEEPINTVL, int(config.TcpKeepAliveIdle)); err != nil { + return newError("failed to set TCP_KEEPIDLE", err) + } } if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) @@ -49,9 +58,16 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) return err } } - if config.TcpKeepAliveInterval > 0 { - if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { - return newError("failed to set TCP_KEEPINTVL", err) + if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { + if config.TcpKeepAliveIdle > 0 { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPALIVE, int(config.TcpKeepAliveInterval)); err != nil { + return newError("failed to set TCP_KEEPINTVL", err) + } + } + if config.TcpKeepAliveInterval > 0 { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, sysTCP_KEEPINTVL, int(config.TcpKeepAliveIdle)); err != nil { + return newError("failed to set TCP_KEEPIDLE", err) + } } if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) diff --git a/transport/internet/sockopt_freebsd.go b/transport/internet/sockopt_freebsd.go index 98e8d11eee7..b90a0fc72cf 100644 --- a/transport/internet/sockopt_freebsd.go +++ b/transport/internet/sockopt_freebsd.go @@ -141,9 +141,16 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf return newError("failed to set TCP_FASTOPEN_CONNECT=0").Base(err) } } - if config.TcpKeepAliveInterval > 0 { - if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { - return newError("failed to set TCP_KEEPINTVL", err) + if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { + if config.TcpKeepAliveIdle > 0 { + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil { + return newError("failed to set TCP_KEEPIDLE", err) + } + } + if config.TcpKeepAliveInterval > 0 { + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { + return newError("failed to set TCP_KEEPINTVL", err) + } } if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) @@ -183,9 +190,16 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) return newError("failed to set TCP_FASTOPEN=0").Base(err) } } - if config.TcpKeepAliveInterval > 0 { - if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { - return newError("failed to set TCP_KEEPINTVL", err) + if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { + if config.TcpKeepAliveIdle > 0 { + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil { + return newError("failed to set TCP_KEEPIDLE", err) + } + } + if config.TcpKeepAliveInterval > 0 { + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { + return newError("failed to set TCP_KEEPINTVL", err) + } } if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) diff --git a/transport/internet/sockopt_linux.go b/transport/internet/sockopt_linux.go index 0c00b927a05..6d7f2e94dbf 100644 --- a/transport/internet/sockopt_linux.go +++ b/transport/internet/sockopt_linux.go @@ -59,12 +59,16 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf } } - if config.TcpKeepAliveInterval > 0 { - if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { - return newError("failed to set TCP_KEEPINTVL", err) + if config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 { + if config.TcpKeepAliveInterval > 0 { + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { + return newError("failed to set TCP_KEEPINTVL", err) + } } - if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil { - return newError("failed to set TCP_KEEPIDLE", err) + if config.TcpKeepAliveIdle > 0 { + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil { + return newError("failed to set TCP_KEEPIDLE", err) + } } if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) @@ -99,12 +103,16 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) } } - if config.TcpKeepAliveInterval > 0 { - if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { - return newError("failed to set TCP_KEEPINTVL", err) + if config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 { + if config.TcpKeepAliveInterval > 0 { + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { + return newError("failed to set TCP_KEEPINTVL", err) + } } - if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil { - return newError("failed to set TCP_KEEPIDLE", err) + if config.TcpKeepAliveIdle > 0 { + if err := syscall.SetsockoptInt(int(fd), syscall.IPPROTO_TCP, syscall.TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil { + return newError("failed to set TCP_KEEPIDLE", err) + } } if err := syscall.SetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) diff --git a/transport/internet/sockopt_windows.go b/transport/internet/sockopt_windows.go index c69cb173633..a076700734f 100644 --- a/transport/internet/sockopt_windows.go +++ b/transport/internet/sockopt_windows.go @@ -25,7 +25,7 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf if err := setTFO(syscall.Handle(fd), config.Tfo); err != nil { return err } - if config.TcpKeepAliveInterval > 0 { + if config.TcpKeepAliveIdle > 0 { if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) } @@ -40,7 +40,7 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) if err := setTFO(syscall.Handle(fd), config.Tfo); err != nil { return err } - if config.TcpKeepAliveInterval > 0 { + if config.TcpKeepAliveIdle > 0 { if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) }