dns.go 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254
  1. package outbound
  2. import (
  3. "context"
  4. "encoding/binary"
  5. "net"
  6. "os"
  7. "github.com/sagernet/sing-box/adapter"
  8. C "github.com/sagernet/sing-box/constant"
  9. "github.com/sagernet/sing-dns"
  10. "github.com/sagernet/sing/common"
  11. "github.com/sagernet/sing/common/buf"
  12. "github.com/sagernet/sing/common/bufio"
  13. "github.com/sagernet/sing/common/canceler"
  14. M "github.com/sagernet/sing/common/metadata"
  15. N "github.com/sagernet/sing/common/network"
  16. "github.com/sagernet/sing/common/task"
  17. mDNS "github.com/miekg/dns"
  18. )
  19. var _ adapter.Outbound = (*DNS)(nil)
  20. type DNS struct {
  21. myOutboundAdapter
  22. }
  23. func NewDNS(router adapter.Router, tag string) *DNS {
  24. return &DNS{
  25. myOutboundAdapter{
  26. protocol: C.TypeDNS,
  27. network: []string{N.NetworkTCP, N.NetworkUDP},
  28. router: router,
  29. tag: tag,
  30. },
  31. }
  32. }
  33. func (d *DNS) DialContext(ctx context.Context, network string, destination M.Socksaddr) (net.Conn, error) {
  34. return nil, os.ErrInvalid
  35. }
  36. func (d *DNS) ListenPacket(ctx context.Context, destination M.Socksaddr) (net.PacketConn, error) {
  37. return nil, os.ErrInvalid
  38. }
  39. func (d *DNS) NewConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  40. metadata.Destination = M.Socksaddr{}
  41. defer conn.Close()
  42. for {
  43. err := d.handleConnection(ctx, conn, metadata)
  44. if err != nil {
  45. return err
  46. }
  47. }
  48. }
  49. func (d *DNS) handleConnection(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  50. var queryLength uint16
  51. err := binary.Read(conn, binary.BigEndian, &queryLength)
  52. if err != nil {
  53. return err
  54. }
  55. if queryLength == 0 {
  56. return dns.RCodeFormatError
  57. }
  58. buffer := buf.NewSize(int(queryLength))
  59. defer buffer.Release()
  60. _, err = buffer.ReadFullFrom(conn, int(queryLength))
  61. if err != nil {
  62. return err
  63. }
  64. var message mDNS.Msg
  65. err = message.Unpack(buffer.Bytes())
  66. if err != nil {
  67. return err
  68. }
  69. metadataInQuery := metadata
  70. go func() error {
  71. response, err := d.router.Exchange(adapter.WithContext(ctx, &metadataInQuery), &message)
  72. if err != nil {
  73. return err
  74. }
  75. responseBuffer := buf.NewPacket()
  76. defer responseBuffer.Release()
  77. responseBuffer.Resize(2, 0)
  78. n, err := response.PackBuffer(responseBuffer.FreeBytes())
  79. if err != nil {
  80. return err
  81. }
  82. responseBuffer.Truncate(len(n))
  83. binary.BigEndian.PutUint16(responseBuffer.ExtendHeader(2), uint16(len(n)))
  84. _, err = conn.Write(responseBuffer.Bytes())
  85. return err
  86. }()
  87. return nil
  88. }
  89. func (d *DNS) NewPacketConnection(ctx context.Context, conn N.PacketConn, metadata adapter.InboundContext) error {
  90. metadata.Destination = M.Socksaddr{}
  91. var reader N.PacketReader = conn
  92. var counters []N.CountFunc
  93. var cachedPackets []*N.PacketBuffer
  94. for {
  95. reader, counters = N.UnwrapCountPacketReader(reader, counters)
  96. if cachedReader, isCached := reader.(N.CachedPacketReader); isCached {
  97. packet := cachedReader.ReadCachedPacket()
  98. if packet != nil {
  99. cachedPackets = append(cachedPackets, packet)
  100. continue
  101. }
  102. }
  103. if readWaiter, created := bufio.CreatePacketReadWaiter(reader); created {
  104. readWaiter.InitializeReadWaiter(N.ReadWaitOptions{})
  105. return d.newPacketConnection(ctx, conn, readWaiter, counters, cachedPackets, metadata)
  106. }
  107. break
  108. }
  109. fastClose, cancel := common.ContextWithCancelCause(ctx)
  110. timeout := canceler.New(fastClose, cancel, C.DNSTimeout)
  111. var group task.Group
  112. group.Append0(func(_ context.Context) error {
  113. for {
  114. var message mDNS.Msg
  115. var destination M.Socksaddr
  116. var err error
  117. if len(cachedPackets) > 0 {
  118. packet := cachedPackets[0]
  119. cachedPackets = cachedPackets[1:]
  120. for _, counter := range counters {
  121. counter(int64(packet.Buffer.Len()))
  122. }
  123. err = message.Unpack(packet.Buffer.Bytes())
  124. packet.Buffer.Release()
  125. if err != nil {
  126. cancel(err)
  127. return err
  128. }
  129. destination = packet.Destination
  130. } else {
  131. buffer := buf.NewPacket()
  132. destination, err = conn.ReadPacket(buffer)
  133. if err != nil {
  134. buffer.Release()
  135. cancel(err)
  136. return err
  137. }
  138. for _, counter := range counters {
  139. counter(int64(buffer.Len()))
  140. }
  141. err = message.Unpack(buffer.Bytes())
  142. buffer.Release()
  143. if err != nil {
  144. cancel(err)
  145. return err
  146. }
  147. timeout.Update()
  148. }
  149. metadataInQuery := metadata
  150. go func() error {
  151. response, err := d.router.Exchange(adapter.WithContext(ctx, &metadataInQuery), &message)
  152. if err != nil {
  153. cancel(err)
  154. return err
  155. }
  156. timeout.Update()
  157. responseBuffer, err := dns.TruncateDNSMessage(&message, response, 1024)
  158. if err != nil {
  159. cancel(err)
  160. return err
  161. }
  162. err = conn.WritePacket(responseBuffer, destination)
  163. if err != nil {
  164. cancel(err)
  165. }
  166. return err
  167. }()
  168. }
  169. })
  170. group.Cleanup(func() {
  171. conn.Close()
  172. })
  173. return group.Run(fastClose)
  174. }
  175. func (d *DNS) newPacketConnection(ctx context.Context, conn N.PacketConn, readWaiter N.PacketReadWaiter, readCounters []N.CountFunc, cached []*N.PacketBuffer, metadata adapter.InboundContext) error {
  176. fastClose, cancel := common.ContextWithCancelCause(ctx)
  177. timeout := canceler.New(fastClose, cancel, C.DNSTimeout)
  178. var group task.Group
  179. group.Append0(func(_ context.Context) error {
  180. for {
  181. var (
  182. message mDNS.Msg
  183. destination M.Socksaddr
  184. err error
  185. buffer *buf.Buffer
  186. )
  187. if len(cached) > 0 {
  188. packet := cached[0]
  189. cached = cached[1:]
  190. for _, counter := range readCounters {
  191. counter(int64(packet.Buffer.Len()))
  192. }
  193. err = message.Unpack(packet.Buffer.Bytes())
  194. packet.Buffer.Release()
  195. if err != nil {
  196. cancel(err)
  197. return err
  198. }
  199. destination = packet.Destination
  200. } else {
  201. buffer, destination, err = readWaiter.WaitReadPacket()
  202. if err != nil {
  203. cancel(err)
  204. return err
  205. }
  206. for _, counter := range readCounters {
  207. counter(int64(buffer.Len()))
  208. }
  209. err = message.Unpack(buffer.Bytes())
  210. buffer.Release()
  211. if err != nil {
  212. cancel(err)
  213. return err
  214. }
  215. timeout.Update()
  216. }
  217. metadataInQuery := metadata
  218. go func() error {
  219. response, err := d.router.Exchange(adapter.WithContext(ctx, &metadataInQuery), &message)
  220. if err != nil {
  221. cancel(err)
  222. return err
  223. }
  224. timeout.Update()
  225. responseBuffer, err := dns.TruncateDNSMessage(&message, response, 1024)
  226. if err != nil {
  227. cancel(err)
  228. return err
  229. }
  230. err = conn.WritePacket(responseBuffer, destination)
  231. if err != nil {
  232. cancel(err)
  233. }
  234. return err
  235. }()
  236. }
  237. })
  238. group.Cleanup(func() {
  239. conn.Close()
  240. })
  241. return group.Run(fastClose)
  242. }