Highly-opinionated (ex-bullshit-free) MTPROTO proxy for Telegram. If you use v1.0 or upgrade broke you proxy, please read the chapter Version 2
您最多选择25个主题 主题必须以字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符

sockopts_test.go 2.2KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293
  1. //go:build linux || darwin
  2. // +build linux darwin
  3. package network_test
  4. import (
  5. "net"
  6. "runtime"
  7. "syscall"
  8. "testing"
  9. "time"
  10. "github.com/9seconds/mtg/v2/network"
  11. "github.com/stretchr/testify/require"
  12. "golang.org/x/sys/unix"
  13. )
  14. func tcpKeepIdleOption() int {
  15. if runtime.GOOS == "darwin" {
  16. return 0x10 // TCP_KEEPALIVE on macOS
  17. }
  18. return 0x4 // TCP_KEEPIDLE on Linux
  19. }
  20. func TestSetClientSocketOptionsKeepAlive(t *testing.T) {
  21. t.Parallel()
  22. listener, err := net.Listen("tcp", "127.0.0.1:0")
  23. require.NoError(t, err)
  24. defer func() {
  25. err := listener.Close()
  26. require.NoError(t, err)
  27. }()
  28. type dialResult struct {
  29. conn net.Conn
  30. err error
  31. }
  32. dialDone := make(chan dialResult, 1)
  33. go func() {
  34. c, err := net.Dial("tcp", listener.Addr().String())
  35. dialDone <- dialResult{conn: c, err: err}
  36. }()
  37. tcpListener, ok := listener.(*net.TCPListener)
  38. require.True(t, ok, "listener must be a *net.TCPListener")
  39. require.NoError(t, tcpListener.SetDeadline(time.Now().Add(5*time.Second)))
  40. accepted, err := listener.Accept()
  41. require.NoError(t, err)
  42. defer func() {
  43. err := accepted.Close()
  44. require.NoError(t, err)
  45. }()
  46. dr := <-dialDone
  47. require.NoError(t, dr.err)
  48. defer func() {
  49. err := dr.conn.Close()
  50. require.NoError(t, err)
  51. }()
  52. err = network.SetClientSocketOptions(accepted, 0)
  53. require.NoError(t, err)
  54. tcpConn := accepted.(*net.TCPConn)
  55. rawConn, err := tcpConn.SyscallConn()
  56. require.NoError(t, err)
  57. err = rawConn.Control(func(fd uintptr) {
  58. val, err := unix.GetsockoptInt(int(fd), syscall.SOL_SOCKET, syscall.SO_KEEPALIVE)
  59. require.NoError(t, err)
  60. require.NotEqual(t, 0, val, "SO_KEEPALIVE should be enabled")
  61. idle, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, tcpKeepIdleOption())
  62. require.NoError(t, err)
  63. require.Equal(t, int(network.DefaultKeepAliveIdle.Seconds()), idle)
  64. interval, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPINTVL)
  65. require.NoError(t, err)
  66. require.Equal(t, int(network.DefaultKeepAliveInterval.Seconds()), interval)
  67. count, err := unix.GetsockoptInt(int(fd), syscall.IPPROTO_TCP, unix.TCP_KEEPCNT)
  68. require.NoError(t, err)
  69. require.Equal(t, network.DefaultKeepAliveCount, count)
  70. })
  71. require.NoError(t, err)
  72. }