listener.go 3.7 KB

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