hosts.go 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package hosts
  2. import (
  3. "context"
  4. "github.com/sagernet/sing-box/adapter"
  5. C "github.com/sagernet/sing-box/constant"
  6. "github.com/sagernet/sing-box/dns"
  7. "github.com/sagernet/sing-box/log"
  8. "github.com/sagernet/sing-box/option"
  9. mDNS "github.com/miekg/dns"
  10. )
  11. func RegisterTransport(registry *dns.TransportRegistry) {
  12. dns.RegisterTransport[option.HostsDNSServerOptions](registry, C.DNSTypeHosts, NewTransport)
  13. }
  14. var _ adapter.DNSTransport = (*Transport)(nil)
  15. type Transport struct {
  16. dns.TransportAdapter
  17. files []*File
  18. }
  19. func NewTransport(ctx context.Context, logger log.ContextLogger, tag string, options option.HostsDNSServerOptions) (adapter.DNSTransport, error) {
  20. var files []*File
  21. if len(options.Path) == 0 {
  22. files = append(files, NewFile(DefaultPath))
  23. } else {
  24. for _, path := range options.Path {
  25. files = append(files, NewFile(path))
  26. }
  27. }
  28. return &Transport{
  29. TransportAdapter: dns.NewTransportAdapter(C.DNSTypeHosts, tag, nil),
  30. files: files,
  31. }, nil
  32. }
  33. func (t *Transport) Reset() {
  34. }
  35. func (t *Transport) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, error) {
  36. question := message.Question[0]
  37. domain := dns.FqdnToDomain(question.Name)
  38. if question.Qtype == mDNS.TypeA || question.Qtype == mDNS.TypeAAAA {
  39. for _, file := range t.files {
  40. addresses := file.Lookup(domain)
  41. if len(addresses) > 0 {
  42. return dns.FixedResponse(message.Id, question, addresses, C.DefaultDNSTTL), nil
  43. }
  44. }
  45. }
  46. return &mDNS.Msg{
  47. MsgHdr: mDNS.MsgHdr{
  48. Id: message.Id,
  49. Rcode: mDNS.RcodeNameError,
  50. Response: true,
  51. },
  52. Question: []mDNS.Question{question},
  53. }, nil
  54. }