mirror of https://github.com/golang/go.git
181 lines
3.8 KiB
Go
181 lines
3.8 KiB
Go
// Copyright 2023 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
//go:build aix || darwin || dragonfly || freebsd || linux || netbsd || solaris || windows
|
|
|
|
package net
|
|
|
|
import "testing"
|
|
|
|
func TestTCPConnKeepAliveConfigDialer(t *testing.T) {
|
|
maybeSkipKeepAliveTest(t)
|
|
|
|
t.Cleanup(func() {
|
|
testPreHookSetKeepAlive = func(*netFD) {}
|
|
})
|
|
var (
|
|
errHook error
|
|
oldCfg KeepAliveConfig
|
|
)
|
|
testPreHookSetKeepAlive = func(nfd *netFD) {
|
|
oldCfg, errHook = getCurrentKeepAliveSettings(fdType(nfd.pfd.Sysfd))
|
|
}
|
|
|
|
handler := func(ls *localServer, ln Listener) {
|
|
for {
|
|
c, err := ln.Accept()
|
|
if err != nil {
|
|
return
|
|
}
|
|
c.Close()
|
|
}
|
|
}
|
|
ln := newLocalListener(t, "tcp", &ListenConfig{
|
|
KeepAlive: -1, // prevent calling hook from accepting
|
|
})
|
|
ls := (&streamListener{Listener: ln}).newLocalServer()
|
|
defer ls.teardown()
|
|
if err := ls.buildup(handler); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
for _, cfg := range testConfigs {
|
|
d := Dialer{
|
|
KeepAlive: defaultTCPKeepAliveIdle, // should be ignored
|
|
KeepAliveConfig: cfg}
|
|
c, err := d.Dial("tcp", ls.Listener.Addr().String())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer c.Close()
|
|
|
|
if errHook != nil {
|
|
t.Fatal(errHook)
|
|
}
|
|
|
|
sc, err := c.(*TCPConn).SyscallConn()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := sc.Control(func(fd uintptr) {
|
|
verifyKeepAliveSettings(t, fdType(fd), oldCfg, cfg)
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTCPConnKeepAliveConfigListener(t *testing.T) {
|
|
maybeSkipKeepAliveTest(t)
|
|
|
|
t.Cleanup(func() {
|
|
testPreHookSetKeepAlive = func(*netFD) {}
|
|
})
|
|
var (
|
|
errHook error
|
|
oldCfg KeepAliveConfig
|
|
)
|
|
testPreHookSetKeepAlive = func(nfd *netFD) {
|
|
oldCfg, errHook = getCurrentKeepAliveSettings(fdType(nfd.pfd.Sysfd))
|
|
}
|
|
|
|
ch := make(chan Conn, 1)
|
|
handler := func(ls *localServer, ln Listener) {
|
|
c, err := ln.Accept()
|
|
if err != nil {
|
|
return
|
|
}
|
|
ch <- c
|
|
}
|
|
for _, cfg := range testConfigs {
|
|
ln := newLocalListener(t, "tcp", &ListenConfig{
|
|
KeepAlive: defaultTCPKeepAliveIdle, // should be ignored
|
|
KeepAliveConfig: cfg})
|
|
ls := (&streamListener{Listener: ln}).newLocalServer()
|
|
defer ls.teardown()
|
|
if err := ls.buildup(handler); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
d := Dialer{KeepAlive: -1} // prevent calling hook from dialing
|
|
c, err := d.Dial("tcp", ls.Listener.Addr().String())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer c.Close()
|
|
|
|
cc := <-ch
|
|
defer cc.Close()
|
|
if errHook != nil {
|
|
t.Fatal(errHook)
|
|
}
|
|
sc, err := cc.(*TCPConn).SyscallConn()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := sc.Control(func(fd uintptr) {
|
|
verifyKeepAliveSettings(t, fdType(fd), oldCfg, cfg)
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestTCPConnKeepAliveConfig(t *testing.T) {
|
|
maybeSkipKeepAliveTest(t)
|
|
|
|
handler := func(ls *localServer, ln Listener) {
|
|
for {
|
|
c, err := ln.Accept()
|
|
if err != nil {
|
|
return
|
|
}
|
|
c.Close()
|
|
}
|
|
}
|
|
ls := newLocalServer(t, "tcp")
|
|
defer ls.teardown()
|
|
if err := ls.buildup(handler); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
ra, err := ResolveTCPAddr("tcp", ls.Listener.Addr().String())
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, cfg := range testConfigs {
|
|
c, err := DialTCP("tcp", nil, ra)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer c.Close()
|
|
|
|
sc, err := c.SyscallConn()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
var (
|
|
errHook error
|
|
oldCfg KeepAliveConfig
|
|
)
|
|
if err := sc.Control(func(fd uintptr) {
|
|
oldCfg, errHook = getCurrentKeepAliveSettings(fdType(fd))
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if errHook != nil {
|
|
t.Fatal(errHook)
|
|
}
|
|
|
|
if err := c.SetKeepAliveConfig(cfg); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
if err := sc.Control(func(fd uintptr) {
|
|
verifyKeepAliveSettings(t, fdType(fd), oldCfg, cfg)
|
|
}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|