From 7dda322cfcf6efde1116aa7ad8fdcd705d2ce3cb Mon Sep 17 00:00:00 2001 From: ValdikSS Date: Thu, 23 Dec 2021 14:02:47 +0300 Subject: [PATCH 1/2] 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 f57693f488..f9b583ecc3 100644 --- a/transport/internet/sockopt_darwin.go +++ b/transport/internet/sockopt_darwin.go @@ -9,6 +9,8 @@ const ( TCP_FASTOPEN_SERVER = 0x01 // nolint: revive,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 98e8d11eee..b90a0fc72c 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 d1739cdc1c..c9aa01c5ef 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").Base(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").Base(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").Base(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 e63c7790f1..0fed34db7b 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) } From 406e0f7ac6614e53870687725dfc8e48a142be95 Mon Sep 17 00:00:00 2001 From: Shelikhoo Date: Sun, 16 Jan 2022 13:17:46 +0000 Subject: [PATCH 2/2] adapt style recommendations for keep alive control From: https://github.com/v2fly/v2ray-core/pull/1484#discussion_r777456773 https://github.com/v2fly/v2ray-core/pull/1484#discussion_r777270291 --- transport/internet/sockopt_darwin.go | 39 ++++++++++++++-------------- 1 file changed, 19 insertions(+), 20 deletions(-) diff --git a/transport/internet/sockopt_darwin.go b/transport/internet/sockopt_darwin.go index f9b583ecc3..ba253e9827 100644 --- a/transport/internet/sockopt_darwin.go +++ b/transport/internet/sockopt_darwin.go @@ -9,8 +9,6 @@ const ( TCP_FASTOPEN_SERVER = 0x01 // nolint: revive,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 { @@ -26,17 +24,18 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf } } - 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.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 config.TcpKeepAliveInterval > 0 { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.TCP_KEEPINTVL, int(config.TcpKeepAliveIdle)); err != nil { + return newError("failed to set TCP_KEEPIDLE", err) } + } + + if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) } @@ -58,17 +57,17 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) return 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.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 config.TcpKeepAliveInterval > 0 { + if err := unix.SetsockoptInt(int(fd), unix.IPPROTO_TCP, unix.SO_KEEPALIVE, int(config.TcpKeepAliveIdle)); err != nil { + return newError("failed to set TCP_KEEPIDLE", err) } + } + if config.TcpKeepAliveIdle > 0 || config.TcpKeepAliveInterval > 0 { if err := unix.SetsockoptInt(int(fd), unix.SOL_SOCKET, unix.SO_KEEPALIVE, 1); err != nil { return newError("failed to set SO_KEEPALIVE", err) }