dns.go 2.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. package route
  2. import (
  3. "context"
  4. "errors"
  5. "net"
  6. "time"
  7. "github.com/sagernet/sing-box/adapter"
  8. C "github.com/sagernet/sing-box/constant"
  9. dnsOutbound "github.com/sagernet/sing-box/protocol/dns"
  10. "github.com/sagernet/sing-dns"
  11. "github.com/sagernet/sing-tun"
  12. "github.com/sagernet/sing/common/buf"
  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/common/udpnat2"
  17. mDNS "github.com/miekg/dns"
  18. )
  19. func (r *Router) hijackDNSStream(ctx context.Context, conn net.Conn, metadata adapter.InboundContext) error {
  20. metadata.Destination = M.Socksaddr{}
  21. for {
  22. conn.SetReadDeadline(time.Now().Add(C.DNSTimeout))
  23. err := dnsOutbound.HandleStreamDNSRequest(ctx, r, conn, metadata)
  24. if err != nil {
  25. return err
  26. }
  27. }
  28. }
  29. func (r *Router) hijackDNSPacket(ctx context.Context, conn N.PacketConn, packetBuffers []*N.PacketBuffer, metadata adapter.InboundContext) {
  30. if uConn, isUDPNAT2 := conn.(*udpnat.Conn); isUDPNAT2 {
  31. metadata.Destination = M.Socksaddr{}
  32. for _, packet := range packetBuffers {
  33. buffer := packet.Buffer
  34. destination := packet.Destination
  35. N.PutPacketBuffer(packet)
  36. go ExchangeDNSPacket(ctx, r, uConn, buffer, metadata, destination)
  37. }
  38. uConn.SetHandler(&dnsHijacker{
  39. router: r,
  40. conn: conn,
  41. ctx: ctx,
  42. metadata: metadata,
  43. })
  44. return
  45. }
  46. err := dnsOutbound.NewDNSPacketConnection(ctx, r, conn, packetBuffers, metadata)
  47. if err != nil && !E.IsClosedOrCanceled(err) {
  48. r.dnsLogger.ErrorContext(ctx, E.Cause(err, "process packet connection"))
  49. }
  50. }
  51. func ExchangeDNSPacket(ctx context.Context, router *Router, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext, destination M.Socksaddr) {
  52. err := exchangeDNSPacket(ctx, router, conn, buffer, metadata, destination)
  53. if err != nil && !errors.Is(err, tun.ErrDrop) && !E.IsClosedOrCanceled(err) {
  54. router.dnsLogger.ErrorContext(ctx, E.Cause(err, "process packet connection"))
  55. }
  56. }
  57. func exchangeDNSPacket(ctx context.Context, router *Router, conn N.PacketConn, buffer *buf.Buffer, metadata adapter.InboundContext, destination M.Socksaddr) error {
  58. var message mDNS.Msg
  59. err := message.Unpack(buffer.Bytes())
  60. buffer.Release()
  61. if err != nil {
  62. return E.Cause(err, "unpack request")
  63. }
  64. response, err := router.Exchange(adapter.WithContext(ctx, &metadata), &message)
  65. if err != nil {
  66. return err
  67. }
  68. responseBuffer, err := dns.TruncateDNSMessage(&message, response, 1024)
  69. if err != nil {
  70. return err
  71. }
  72. err = conn.WritePacket(responseBuffer, destination)
  73. return err
  74. }
  75. type dnsHijacker struct {
  76. router *Router
  77. conn N.PacketConn
  78. ctx context.Context
  79. metadata adapter.InboundContext
  80. }
  81. func (h *dnsHijacker) NewPacketEx(buffer *buf.Buffer, destination M.Socksaddr) {
  82. go ExchangeDNSPacket(h.ctx, h.router, h.conn, buffer, h.metadata, destination)
  83. }