| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192 |
- //go:build linux || darwin
- // +build linux darwin
-
- package network
-
- import (
- "net"
- "runtime"
- "syscall"
- "testing"
- "time"
-
- "github.com/stretchr/testify/require"
- "golang.org/x/sys/unix"
- )
-
- func tcpKeepIdleOption() int {
- if runtime.GOOS == "darwin" {
- return 0x10 // TCP_KEEPALIVE on macOS
- }
-
- return 0x4 // TCP_KEEPIDLE on Linux
- }
-
- func TestSetCommonSocketOptionsKeepAlive(t *testing.T) {
- t.Parallel()
-
- listener, err := net.Listen("tcp", "127.0.0.1:0")
- require.NoError(t, err)
- defer func() {
- err := listener.Close()
- require.NoError(t, err)
- }()
-
- type dialResult struct {
- conn net.Conn
- err error
- }
-
- dialDone := make(chan dialResult, 1)
-
- go func() {
- c, err := net.Dial("tcp", listener.Addr().String())
- dialDone <- dialResult{conn: c, err: err}
- }()
-
- tcpListener, ok := listener.(*net.TCPListener)
- require.True(t, ok, "listener must be a *net.TCPListener")
-
- require.NoError(t, tcpListener.SetDeadline(time.Now().Add(5*time.Second)))
-
- accepted, err := listener.Accept()
- require.NoError(t, err)
- defer func() {
- err := accepted.Close()
- require.NoError(t, err)
- }()
-
- dr := <-dialDone
- require.NoError(t, dr.err)
- defer func() {
- err := dr.conn.Close()
- require.NoError(t, err)
- }()
-
- tcpConn := accepted.(*net.TCPConn)
-
- err = setCommonSocketOptions(tcpConn, DefaultKeepAliveConfig)
- require.NoError(t, err)
-
- rawConn, err := tcpConn.SyscallConn()
- require.NoError(t, err)
-
- err = rawConn.Control(func(fd uintptr) {
- val, err := unix.GetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE)
- require.NoError(t, err)
- require.NotEqual(t, 0, val, "SO_KEEPALIVE should be enabled")
-
- idle, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, tcpKeepIdleOption())
- require.NoError(t, err)
- require.Equal(t, 15, idle, "keepalive idle should match DefaultKeepAliveIdle")
-
- interval, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPINTVL)
- require.NoError(t, err)
- require.Equal(t, 15, interval, "keepalive interval should match DefaultKeepAliveInterval")
-
- count, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPCNT)
- require.NoError(t, err)
- require.Equal(t, 9, count, "keepalive count should match DefaultKeepAliveCount")
- })
- require.NoError(t, err)
- }
|