dns.go 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package libbox
  2. import (
  3. "context"
  4. "net/netip"
  5. "strings"
  6. "syscall"
  7. "github.com/sagernet/sing-box/adapter"
  8. C "github.com/sagernet/sing-box/constant"
  9. "github.com/sagernet/sing-box/dns"
  10. "github.com/sagernet/sing-box/option"
  11. "github.com/sagernet/sing/common"
  12. E "github.com/sagernet/sing/common/exceptions"
  13. M "github.com/sagernet/sing/common/metadata"
  14. "github.com/sagernet/sing/common/task"
  15. mDNS "github.com/miekg/dns"
  16. )
  17. type LocalDNSTransport interface {
  18. Raw() bool
  19. Lookup(ctx *ExchangeContext, network string, domain string) error
  20. Exchange(ctx *ExchangeContext, message []byte) error
  21. }
  22. var _ adapter.DNSTransport = (*platformTransport)(nil)
  23. type platformTransport struct {
  24. dns.TransportAdapter
  25. iif LocalDNSTransport
  26. }
  27. func newPlatformTransport(iif LocalDNSTransport, tag string, options option.LocalDNSServerOptions) *platformTransport {
  28. return &platformTransport{
  29. TransportAdapter: dns.NewTransportAdapterWithLocalOptions(C.DNSTypeLocal, tag, options),
  30. iif: iif,
  31. }
  32. }
  33. func (p *platformTransport) Reset() {
  34. }
  35. func (p *platformTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
  36. response := &ExchangeContext{
  37. context: ctx,
  38. }
  39. if p.iif.Raw() {
  40. messageBytes, err := message.Pack()
  41. if err != nil {
  42. return nil, err
  43. }
  44. var responseMessage *mDNS.Msg
  45. var group task.Group
  46. group.Append0(func(ctx context.Context) error {
  47. err = p.iif.Exchange(response, messageBytes)
  48. if err != nil {
  49. return err
  50. }
  51. if response.error != nil {
  52. return response.error
  53. }
  54. responseMessage = &response.message
  55. return nil
  56. })
  57. err = group.Run(ctx)
  58. if err != nil {
  59. return nil, err
  60. }
  61. return responseMessage, nil
  62. } else {
  63. question := message.Question[0]
  64. var network string
  65. switch question.Qtype {
  66. case mDNS.TypeA:
  67. network = "ip4"
  68. case mDNS.TypeAAAA:
  69. network = "ip6"
  70. default:
  71. return nil, E.New("only IP queries are supported by current version of Android")
  72. }
  73. var responseAddrs []netip.Addr
  74. var group task.Group
  75. group.Append0(func(ctx context.Context) error {
  76. err := p.iif.Lookup(response, network, question.Name)
  77. if err != nil {
  78. return err
  79. }
  80. if response.error != nil {
  81. return response.error
  82. }
  83. responseAddrs = response.addresses
  84. return nil
  85. })
  86. err := group.Run(ctx)
  87. if err != nil {
  88. return nil, err
  89. }
  90. return dns.FixedResponse(message.Id, question, responseAddrs, C.DefaultDNSTTL), nil
  91. }
  92. }
  93. type Func interface {
  94. Invoke() error
  95. }
  96. type ExchangeContext struct {
  97. context context.Context
  98. message mDNS.Msg
  99. addresses []netip.Addr
  100. error error
  101. }
  102. func (c *ExchangeContext) OnCancel(callback Func) {
  103. go func() {
  104. <-c.context.Done()
  105. callback.Invoke()
  106. }()
  107. }
  108. func (c *ExchangeContext) Success(result string) {
  109. c.addresses = common.Map(common.Filter(strings.Split(result, "\n"), func(it string) bool {
  110. return !common.IsEmpty(it)
  111. }), func(it string) netip.Addr {
  112. return M.ParseSocksaddrHostPort(it, 0).Unwrap().Addr
  113. })
  114. }
  115. func (c *ExchangeContext) RawSuccess(result []byte) {
  116. err := c.message.Unpack(result)
  117. if err != nil {
  118. c.error = E.Cause(err, "parse response")
  119. }
  120. }
  121. func (c *ExchangeContext) ErrorCode(code int32) {
  122. c.error = dns.RCodeError(code)
  123. }
  124. func (c *ExchangeContext) ErrnoCode(code int32) {
  125. c.error = syscall.Errno(code)
  126. }