listener_tcp.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109
  1. package listener
  2. import (
  3. "net"
  4. "net/netip"
  5. "strings"
  6. "syscall"
  7. "time"
  8. "github.com/sagernet/sing-box/adapter"
  9. "github.com/sagernet/sing-box/common/redir"
  10. C "github.com/sagernet/sing-box/constant"
  11. "github.com/sagernet/sing-box/log"
  12. "github.com/sagernet/sing/common/control"
  13. E "github.com/sagernet/sing/common/exceptions"
  14. M "github.com/sagernet/sing/common/metadata"
  15. N "github.com/sagernet/sing/common/network"
  16. "github.com/sagernet/sing/service"
  17. "github.com/metacubex/tfo-go"
  18. )
  19. func (l *Listener) ListenTCP() (net.Listener, error) {
  20. //nolint:staticcheck
  21. if l.listenOptions.ProxyProtocol || l.listenOptions.ProxyProtocolAcceptNoHeader {
  22. return nil, E.New("Proxy Protocol is deprecated and removed in sing-box 1.6.0")
  23. }
  24. var err error
  25. bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(netip.AddrFrom4([4]byte{127, 0, 0, 1})), l.listenOptions.ListenPort)
  26. var listenConfig net.ListenConfig
  27. if l.listenOptions.BindInterface != "" {
  28. listenConfig.Control = control.Append(listenConfig.Control, control.BindToInterface(service.FromContext[adapter.NetworkManager](l.ctx).InterfaceFinder(), l.listenOptions.BindInterface, -1))
  29. }
  30. if l.listenOptions.RoutingMark != 0 {
  31. listenConfig.Control = control.Append(listenConfig.Control, control.RoutingMark(uint32(l.listenOptions.RoutingMark)))
  32. }
  33. if l.listenOptions.ReuseAddr {
  34. listenConfig.Control = control.Append(listenConfig.Control, control.ReuseAddr())
  35. }
  36. if l.listenOptions.TCPKeepAlive >= 0 {
  37. keepIdle := time.Duration(l.listenOptions.TCPKeepAlive)
  38. if keepIdle == 0 {
  39. keepIdle = C.TCPKeepAliveInitial
  40. }
  41. keepInterval := time.Duration(l.listenOptions.TCPKeepAliveInterval)
  42. if keepInterval == 0 {
  43. keepInterval = C.TCPKeepAliveInterval
  44. }
  45. setKeepAliveConfig(&listenConfig, keepIdle, keepInterval)
  46. }
  47. if l.listenOptions.TCPMultiPath {
  48. if !go121Available {
  49. return nil, E.New("MultiPath TCP requires go1.21, please recompile your binary.")
  50. }
  51. setMultiPathTCP(&listenConfig)
  52. }
  53. if l.tproxy {
  54. listenConfig.Control = control.Append(listenConfig.Control, func(network, address string, conn syscall.RawConn) error {
  55. return control.Raw(conn, func(fd uintptr) error {
  56. return redir.TProxy(fd, !strings.HasSuffix(network, "4"), false)
  57. })
  58. })
  59. }
  60. tcpListener, err := ListenNetworkNamespace[net.Listener](l.listenOptions.NetNs, func() (net.Listener, error) {
  61. if l.listenOptions.TCPFastOpen {
  62. var tfoConfig tfo.ListenConfig
  63. tfoConfig.ListenConfig = listenConfig
  64. return tfoConfig.Listen(l.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
  65. } else {
  66. return listenConfig.Listen(l.ctx, M.NetworkFromNetAddr(N.NetworkTCP, bindAddr.Addr), bindAddr.String())
  67. }
  68. })
  69. if err != nil {
  70. return nil, err
  71. }
  72. l.logger.Info("tcp server started at ", tcpListener.Addr())
  73. l.tcpListener = tcpListener
  74. return tcpListener, err
  75. }
  76. func (l *Listener) loopTCPIn() {
  77. tcpListener := l.tcpListener
  78. var metadata adapter.InboundContext
  79. for {
  80. conn, err := tcpListener.Accept()
  81. if err != nil {
  82. //nolint:staticcheck
  83. if netError, isNetError := err.(net.Error); isNetError && netError.Temporary() {
  84. l.logger.Error(err)
  85. continue
  86. }
  87. if l.shutdown.Load() && E.IsClosed(err) {
  88. return
  89. }
  90. l.tcpListener.Close()
  91. l.logger.Error("tcp listener closed: ", err)
  92. continue
  93. }
  94. //nolint:staticcheck
  95. metadata.InboundDetour = l.listenOptions.Detour
  96. //nolint:staticcheck
  97. metadata.InboundOptions = l.listenOptions.InboundOptions
  98. metadata.Source = M.SocksaddrFromNet(conn.RemoteAddr()).Unwrap()
  99. metadata.OriginDestination = M.SocksaddrFromNet(conn.LocalAddr()).Unwrap()
  100. ctx := log.ContextWithNewID(l.ctx)
  101. l.logger.InfoContext(ctx, "inbound connection from ", metadata.Source)
  102. go l.connHandler.NewConnectionEx(ctx, conn, metadata, nil)
  103. }
  104. }