listener.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  1. package listener
  2. import (
  3. "context"
  4. "net"
  5. "net/netip"
  6. "sync/atomic"
  7. "github.com/sagernet/sing-box/adapter"
  8. "github.com/sagernet/sing-box/common/settings"
  9. "github.com/sagernet/sing-box/option"
  10. "github.com/sagernet/sing/common"
  11. E "github.com/sagernet/sing/common/exceptions"
  12. "github.com/sagernet/sing/common/logger"
  13. M "github.com/sagernet/sing/common/metadata"
  14. N "github.com/sagernet/sing/common/network"
  15. )
  16. type Listener struct {
  17. ctx context.Context
  18. logger logger.ContextLogger
  19. network []string
  20. listenOptions option.ListenOptions
  21. connHandler adapter.ConnectionHandlerEx
  22. packetHandler adapter.PacketHandlerEx
  23. oobPacketHandler adapter.OOBPacketHandlerEx
  24. threadUnsafePacketWriter bool
  25. disablePacketOutput bool
  26. setSystemProxy bool
  27. systemProxySOCKS bool
  28. tcpListener net.Listener
  29. systemProxy settings.SystemProxy
  30. udpConn *net.UDPConn
  31. udpAddr M.Socksaddr
  32. packetOutbound chan *N.PacketBuffer
  33. packetOutboundClosed chan struct{}
  34. shutdown atomic.Bool
  35. }
  36. type Options struct {
  37. Context context.Context
  38. Logger logger.ContextLogger
  39. Network []string
  40. Listen option.ListenOptions
  41. ConnectionHandler adapter.ConnectionHandlerEx
  42. PacketHandler adapter.PacketHandlerEx
  43. OOBPacketHandler adapter.OOBPacketHandlerEx
  44. ThreadUnsafePacketWriter bool
  45. DisablePacketOutput bool
  46. SetSystemProxy bool
  47. SystemProxySOCKS bool
  48. }
  49. func New(
  50. options Options,
  51. ) *Listener {
  52. return &Listener{
  53. ctx: options.Context,
  54. logger: options.Logger,
  55. network: options.Network,
  56. listenOptions: options.Listen,
  57. connHandler: options.ConnectionHandler,
  58. packetHandler: options.PacketHandler,
  59. oobPacketHandler: options.OOBPacketHandler,
  60. threadUnsafePacketWriter: options.ThreadUnsafePacketWriter,
  61. disablePacketOutput: options.DisablePacketOutput,
  62. setSystemProxy: options.SetSystemProxy,
  63. systemProxySOCKS: options.SystemProxySOCKS,
  64. }
  65. }
  66. func (l *Listener) Start() error {
  67. if common.Contains(l.network, N.NetworkTCP) {
  68. _, err := l.ListenTCP()
  69. if err != nil {
  70. return err
  71. }
  72. go l.loopTCPIn()
  73. }
  74. if common.Contains(l.network, N.NetworkUDP) {
  75. _, err := l.ListenUDP()
  76. if err != nil {
  77. return err
  78. }
  79. l.packetOutboundClosed = make(chan struct{})
  80. l.packetOutbound = make(chan *N.PacketBuffer, 64)
  81. go l.loopUDPIn()
  82. if !l.disablePacketOutput {
  83. go l.loopUDPOut()
  84. }
  85. }
  86. if l.setSystemProxy {
  87. listenPort := M.SocksaddrFromNet(l.tcpListener.Addr()).Port
  88. var listenAddrString string
  89. listenAddr := l.listenOptions.Listen.Build(netip.IPv4Unspecified())
  90. if listenAddr.IsUnspecified() {
  91. listenAddrString = "127.0.0.1"
  92. } else {
  93. listenAddrString = listenAddr.String()
  94. }
  95. systemProxy, err := settings.NewSystemProxy(l.ctx, M.ParseSocksaddrHostPort(listenAddrString, listenPort), l.systemProxySOCKS)
  96. if err != nil {
  97. return E.Cause(err, "initialize system proxy")
  98. }
  99. err = systemProxy.Enable()
  100. if err != nil {
  101. return E.Cause(err, "set system proxy")
  102. }
  103. l.systemProxy = systemProxy
  104. }
  105. return nil
  106. }
  107. func (l *Listener) Close() error {
  108. l.shutdown.Store(true)
  109. var err error
  110. if l.systemProxy != nil && l.systemProxy.IsEnabled() {
  111. err = l.systemProxy.Disable()
  112. }
  113. return E.Errors(err, common.Close(
  114. l.tcpListener,
  115. common.PtrOrNil(l.udpConn),
  116. ))
  117. }
  118. func (l *Listener) TCPListener() net.Listener {
  119. return l.tcpListener
  120. }
  121. func (l *Listener) UDPConn() *net.UDPConn {
  122. return l.udpConn
  123. }
  124. func (l *Listener) ListenOptions() option.ListenOptions {
  125. return l.listenOptions
  126. }