listener_tcp.go 2.7 KB

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