1
0

dns.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  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) Start(stage adapter.StartStage) error {
  34. return nil
  35. }
  36. func (p *platformTransport) Close() error {
  37. return nil
  38. }
  39. func (p *platformTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
  40. response := &ExchangeContext{
  41. context: ctx,
  42. }
  43. if p.iif.Raw() {
  44. messageBytes, err := message.Pack()
  45. if err != nil {
  46. return nil, err
  47. }
  48. var responseMessage *mDNS.Msg
  49. var group task.Group
  50. group.Append0(func(ctx context.Context) error {
  51. err = p.iif.Exchange(response, messageBytes)
  52. if err != nil {
  53. return err
  54. }
  55. if response.error != nil {
  56. return response.error
  57. }
  58. responseMessage = &response.message
  59. return nil
  60. })
  61. err = group.Run(ctx)
  62. if err != nil {
  63. return nil, err
  64. }
  65. return responseMessage, nil
  66. } else {
  67. question := message.Question[0]
  68. var network string
  69. switch question.Qtype {
  70. case mDNS.TypeA:
  71. network = "ip4"
  72. case mDNS.TypeAAAA:
  73. network = "ip6"
  74. default:
  75. return nil, E.New("only IP queries are supported by current version of Android")
  76. }
  77. var responseAddrs []netip.Addr
  78. var group task.Group
  79. group.Append0(func(ctx context.Context) error {
  80. err := p.iif.Lookup(response, network, question.Name)
  81. if err != nil {
  82. return err
  83. }
  84. if response.error != nil {
  85. return response.error
  86. }
  87. responseAddrs = response.addresses
  88. return nil
  89. })
  90. err := group.Run(ctx)
  91. if err != nil {
  92. return nil, err
  93. }
  94. return dns.FixedResponse(message.Id, question, responseAddrs, C.DefaultDNSTTL), nil
  95. }
  96. }
  97. type Func interface {
  98. Invoke() error
  99. }
  100. type ExchangeContext struct {
  101. context context.Context
  102. message mDNS.Msg
  103. addresses []netip.Addr
  104. error error
  105. }
  106. func (c *ExchangeContext) OnCancel(callback Func) {
  107. go func() {
  108. <-c.context.Done()
  109. callback.Invoke()
  110. }()
  111. }
  112. func (c *ExchangeContext) Success(result string) {
  113. c.addresses = common.Map(common.Filter(strings.Split(result, "\n"), func(it string) bool {
  114. return !common.IsEmpty(it)
  115. }), func(it string) netip.Addr {
  116. return M.ParseSocksaddrHostPort(it, 0).Unwrap().Addr
  117. })
  118. }
  119. func (c *ExchangeContext) RawSuccess(result []byte) {
  120. err := c.message.Unpack(result)
  121. if err != nil {
  122. c.error = E.Cause(err, "parse response")
  123. }
  124. }
  125. func (c *ExchangeContext) ErrorCode(code int32) {
  126. c.error = dns.RcodeError(code)
  127. }
  128. func (c *ExchangeContext) ErrnoCode(code int32) {
  129. c.error = syscall.Errno(code)
  130. }