listener_udp.go 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. package listener
  2. import (
  3. "context"
  4. "net"
  5. "net/netip"
  6. "os"
  7. "strings"
  8. "syscall"
  9. "github.com/sagernet/sing-box/adapter"
  10. "github.com/sagernet/sing-box/common/redir"
  11. "github.com/sagernet/sing/common/buf"
  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. )
  18. func (l *Listener) ListenUDP() (net.PacketConn, error) {
  19. bindAddr := M.SocksaddrFrom(l.listenOptions.Listen.Build(netip.AddrFrom4([4]byte{127, 0, 0, 1})), l.listenOptions.ListenPort)
  20. var listenConfig net.ListenConfig
  21. if l.listenOptions.BindInterface != "" {
  22. listenConfig.Control = control.Append(listenConfig.Control, control.BindToInterface(service.FromContext[adapter.NetworkManager](l.ctx).InterfaceFinder(), l.listenOptions.BindInterface, -1))
  23. }
  24. if l.listenOptions.RoutingMark != 0 {
  25. listenConfig.Control = control.Append(listenConfig.Control, control.RoutingMark(uint32(l.listenOptions.RoutingMark)))
  26. }
  27. if l.listenOptions.ReuseAddr {
  28. listenConfig.Control = control.Append(listenConfig.Control, control.ReuseAddr())
  29. }
  30. var udpFragment bool
  31. if l.listenOptions.UDPFragment != nil {
  32. udpFragment = *l.listenOptions.UDPFragment
  33. } else {
  34. udpFragment = l.listenOptions.UDPFragmentDefault
  35. }
  36. if !udpFragment {
  37. listenConfig.Control = control.Append(listenConfig.Control, control.DisableUDPFragment())
  38. }
  39. if l.tproxy {
  40. listenConfig.Control = control.Append(listenConfig.Control, func(network, address string, conn syscall.RawConn) error {
  41. return control.Raw(conn, func(fd uintptr) error {
  42. return redir.TProxy(fd, !strings.HasSuffix(network, "4"), true)
  43. })
  44. })
  45. }
  46. udpConn, err := ListenNetworkNamespace[net.PacketConn](l.listenOptions.NetNs, func() (net.PacketConn, error) {
  47. return listenConfig.ListenPacket(l.ctx, M.NetworkFromNetAddr(N.NetworkUDP, bindAddr.Addr), bindAddr.String())
  48. })
  49. if err != nil {
  50. return nil, err
  51. }
  52. l.udpConn = udpConn.(*net.UDPConn)
  53. l.udpAddr = bindAddr
  54. l.logger.Info("udp server started at ", udpConn.LocalAddr())
  55. return udpConn, err
  56. }
  57. func (l *Listener) DialContext(dialer net.Dialer, ctx context.Context, network string, address string) (net.Conn, error) {
  58. return ListenNetworkNamespace[net.Conn](l.listenOptions.NetNs, func() (net.Conn, error) {
  59. if l.listenOptions.BindInterface != "" {
  60. dialer.Control = control.Append(dialer.Control, control.BindToInterface(service.FromContext[adapter.NetworkManager](l.ctx).InterfaceFinder(), l.listenOptions.BindInterface, -1))
  61. }
  62. if l.listenOptions.RoutingMark != 0 {
  63. dialer.Control = control.Append(dialer.Control, control.RoutingMark(uint32(l.listenOptions.RoutingMark)))
  64. }
  65. if l.listenOptions.ReuseAddr {
  66. dialer.Control = control.Append(dialer.Control, control.ReuseAddr())
  67. }
  68. return dialer.DialContext(ctx, network, address)
  69. })
  70. }
  71. func (l *Listener) ListenPacket(listenConfig net.ListenConfig, ctx context.Context, network string, address string) (net.PacketConn, error) {
  72. return ListenNetworkNamespace[net.PacketConn](l.listenOptions.NetNs, func() (net.PacketConn, error) {
  73. if l.listenOptions.BindInterface != "" {
  74. listenConfig.Control = control.Append(listenConfig.Control, control.BindToInterface(service.FromContext[adapter.NetworkManager](l.ctx).InterfaceFinder(), l.listenOptions.BindInterface, -1))
  75. }
  76. if l.listenOptions.RoutingMark != 0 {
  77. listenConfig.Control = control.Append(listenConfig.Control, control.RoutingMark(uint32(l.listenOptions.RoutingMark)))
  78. }
  79. if l.listenOptions.ReuseAddr {
  80. listenConfig.Control = control.Append(listenConfig.Control, control.ReuseAddr())
  81. }
  82. return listenConfig.ListenPacket(ctx, network, address)
  83. })
  84. }
  85. func (l *Listener) UDPAddr() M.Socksaddr {
  86. return l.udpAddr
  87. }
  88. func (l *Listener) PacketWriter() N.PacketWriter {
  89. return (*packetWriter)(l)
  90. }
  91. func (l *Listener) loopUDPIn() {
  92. defer close(l.packetOutboundClosed)
  93. var buffer *buf.Buffer
  94. if !l.threadUnsafePacketWriter {
  95. buffer = buf.NewPacket()
  96. defer buffer.Release()
  97. buffer.IncRef()
  98. defer buffer.DecRef()
  99. }
  100. if l.oobPacketHandler != nil {
  101. oob := make([]byte, 1024)
  102. for {
  103. if l.threadUnsafePacketWriter {
  104. buffer = buf.NewPacket()
  105. } else {
  106. buffer.Reset()
  107. }
  108. n, oobN, _, addr, err := l.udpConn.ReadMsgUDPAddrPort(buffer.FreeBytes(), oob)
  109. if err != nil {
  110. if l.threadUnsafePacketWriter {
  111. buffer.Release()
  112. }
  113. if l.shutdown.Load() && E.IsClosed(err) {
  114. return
  115. }
  116. l.udpConn.Close()
  117. l.logger.Error("udp listener closed: ", err)
  118. return
  119. }
  120. buffer.Truncate(n)
  121. l.oobPacketHandler.NewPacketEx(buffer, oob[:oobN], M.SocksaddrFromNetIP(addr).Unwrap())
  122. }
  123. } else {
  124. for {
  125. if l.threadUnsafePacketWriter {
  126. buffer = buf.NewPacket()
  127. } else {
  128. buffer.Reset()
  129. }
  130. n, addr, err := l.udpConn.ReadFromUDPAddrPort(buffer.FreeBytes())
  131. if err != nil {
  132. if l.threadUnsafePacketWriter {
  133. buffer.Release()
  134. }
  135. if l.shutdown.Load() && E.IsClosed(err) {
  136. return
  137. }
  138. l.udpConn.Close()
  139. l.logger.Error("udp listener closed: ", err)
  140. return
  141. }
  142. buffer.Truncate(n)
  143. l.packetHandler.NewPacketEx(buffer, M.SocksaddrFromNetIP(addr).Unwrap())
  144. }
  145. }
  146. }
  147. func (l *Listener) loopUDPOut() {
  148. for {
  149. select {
  150. case packet := <-l.packetOutbound:
  151. destination := packet.Destination.AddrPort()
  152. _, err := l.udpConn.WriteToUDPAddrPort(packet.Buffer.Bytes(), destination)
  153. packet.Buffer.Release()
  154. N.PutPacketBuffer(packet)
  155. if err != nil {
  156. if l.shutdown.Load() && E.IsClosed(err) {
  157. return
  158. }
  159. l.logger.Error("udp listener write back: ", destination, ": ", err)
  160. continue
  161. }
  162. continue
  163. case <-l.packetOutboundClosed:
  164. }
  165. for {
  166. select {
  167. case packet := <-l.packetOutbound:
  168. packet.Buffer.Release()
  169. N.PutPacketBuffer(packet)
  170. default:
  171. return
  172. }
  173. }
  174. }
  175. }
  176. type packetWriter Listener
  177. func (w *packetWriter) WritePacket(buffer *buf.Buffer, destination M.Socksaddr) error {
  178. packet := N.NewPacketBuffer()
  179. packet.Buffer = buffer
  180. packet.Destination = destination
  181. select {
  182. case w.packetOutbound <- packet:
  183. return nil
  184. default:
  185. buffer.Release()
  186. N.PutPacketBuffer(packet)
  187. if w.shutdown.Load() {
  188. return os.ErrClosed
  189. }
  190. w.logger.Trace("dropped packet to ", destination)
  191. return nil
  192. }
  193. }
  194. func (w *packetWriter) WriteIsThreadUnsafe() {
  195. }