From 6629d331fa7c291c8dd73f1781ee244333ab8ea7 Mon Sep 17 00:00:00 2001 From: xqzr <34030394+xqzr@users.noreply.github.com> Date: Tue, 1 Apr 2025 02:27:06 +0800 Subject: [PATCH] Sockopt: Add Windows `TCP_KEEPINTVL` & `TCP_KEEPIDLE` --- transport/internet/sockopt_windows.go | 32 ++++++++++++++++++++------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/transport/internet/sockopt_windows.go b/transport/internet/sockopt_windows.go index cbd3b41e..57b15c47 100644 --- a/transport/internet/sockopt_windows.go +++ b/transport/internet/sockopt_windows.go @@ -16,6 +16,8 @@ const ( IP_MULTICAST_IF = 9 IPV6_MULTICAST_IF = 9 IPV6_V6ONLY = 27 + TCP_KEEPIDLE = 3 + TCP_KEEPINTVL = 17 ) func setTFO(fd syscall.Handle, tfo int) error { @@ -61,11 +63,18 @@ func applyOutboundSocketOptions(network string, address string, fd uintptr, conf if err := setTFO(syscall.Handle(fd), config.ParseTFOValue()); err != nil { return err } - if config.TcpKeepAliveIdle > 0 { - if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { - return errors.New("failed to set SO_KEEPALIVE", err) + if config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 { + if config.TcpKeepAliveInterval > 0 { + if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_TCP, TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { + return errors.New("failed to set TCP_KEEPINTVL", err) + } } - } else if config.TcpKeepAliveIdle < 0 { + if config.TcpKeepAliveIdle > 0 { + if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_TCP, TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil { + return errors.New("failed to set TCP_KEEPIDLE", err) + } + } + } else if config.TcpKeepAliveInterval < 0 || config.TcpKeepAliveIdle < 0 { if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 0); err != nil { return errors.New("failed to unset SO_KEEPALIVE", err) } @@ -80,11 +89,18 @@ func applyInboundSocketOptions(network string, fd uintptr, config *SocketConfig) if err := setTFO(syscall.Handle(fd), config.ParseTFOValue()); err != nil { return err } - if config.TcpKeepAliveIdle > 0 { - if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 1); err != nil { - return errors.New("failed to set SO_KEEPALIVE", err) + if config.TcpKeepAliveInterval > 0 || config.TcpKeepAliveIdle > 0 { + if config.TcpKeepAliveInterval > 0 { + if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_TCP, TCP_KEEPINTVL, int(config.TcpKeepAliveInterval)); err != nil { + return errors.New("failed to set TCP_KEEPINTVL", err) + } } - } else if config.TcpKeepAliveIdle < 0 { + if config.TcpKeepAliveIdle > 0 { + if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.IPPROTO_TCP, TCP_KEEPIDLE, int(config.TcpKeepAliveIdle)); err != nil { + return errors.New("failed to set TCP_KEEPIDLE", err) + } + } + } else if config.TcpKeepAliveInterval < 0 || config.TcpKeepAliveIdle < 0 { if err := syscall.SetsockoptInt(syscall.Handle(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE, 0); err != nil { return errors.New("failed to unset SO_KEEPALIVE", err) }