ktimeout_linux_test.go 1.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package ktimeout
  4. import (
  5. "context"
  6. "net"
  7. "testing"
  8. "time"
  9. "golang.org/x/sys/unix"
  10. "tailscale.com/util/must"
  11. )
  12. func TestSetUserTimeout(t *testing.T) {
  13. lc := net.ListenConfig{}
  14. // As of 2025-02-19, MPTCP does not support TCP_USER_TIMEOUT socket option
  15. // set in ktimeout.UserTimeout above.
  16. lc.SetMultipathTCP(false)
  17. ln := must.Get(lc.Listen(context.Background(), "tcp", "localhost:0"))
  18. defer ln.Close()
  19. var err error
  20. if e := must.Get(ln.(*net.TCPListener).SyscallConn()).Control(func(fd uintptr) {
  21. err = SetUserTimeout(fd, 0)
  22. }); e != nil {
  23. t.Fatal(e)
  24. }
  25. if err != nil {
  26. t.Fatal(err)
  27. }
  28. v := must.Get(unix.GetsockoptInt(int(must.Get(ln.(*net.TCPListener).File()).Fd()), unix.SOL_TCP, unix.TCP_USER_TIMEOUT))
  29. if v != 0 {
  30. t.Errorf("TCP_USER_TIMEOUT: got %v; want 0", v)
  31. }
  32. if e := must.Get(ln.(*net.TCPListener).SyscallConn()).Control(func(fd uintptr) {
  33. err = SetUserTimeout(fd, 30*time.Second)
  34. }); e != nil {
  35. t.Fatal(e)
  36. }
  37. if err != nil {
  38. t.Fatal(err)
  39. }
  40. v = must.Get(unix.GetsockoptInt(int(must.Get(ln.(*net.TCPListener).File()).Fd()), unix.SOL_TCP, unix.TCP_USER_TIMEOUT))
  41. if v != 30000 {
  42. t.Errorf("TCP_USER_TIMEOUT: got %v; want 30000", v)
  43. }
  44. }