listener_udp.go 6.2 KB

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