hosts.go 1.8 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. package dns
  2. import (
  3. "v2ray.com/core/common"
  4. "v2ray.com/core/common/net"
  5. "v2ray.com/core/common/strmatcher"
  6. )
  7. type StaticHosts struct {
  8. ips map[uint32][]net.IP
  9. matchers *strmatcher.MatcherGroup
  10. }
  11. var typeMap = map[DomainMatchingType]strmatcher.Type{
  12. DomainMatchingType_Full: strmatcher.Full,
  13. DomainMatchingType_Subdomain: strmatcher.Domain,
  14. DomainMatchingType_Keyword: strmatcher.Substr,
  15. DomainMatchingType_Regex: strmatcher.Regex,
  16. }
  17. func toStrMatcher(t DomainMatchingType, domain string) (strmatcher.Matcher, error) {
  18. strMType, f := typeMap[t]
  19. if !f {
  20. return nil, newError("unknown mapping type", t).AtWarning()
  21. }
  22. matcher, err := strMType.New(domain)
  23. if err != nil {
  24. return nil, newError("failed to create str matcher").Base(err)
  25. }
  26. return matcher, nil
  27. }
  28. func NewStaticHosts(hosts []*Config_HostMapping, legacy map[string]*net.IPOrDomain) (*StaticHosts, error) {
  29. g := new(strmatcher.MatcherGroup)
  30. sh := &StaticHosts{
  31. ips: make(map[uint32][]net.IP),
  32. matchers: g,
  33. }
  34. if legacy != nil {
  35. for domain, ip := range legacy {
  36. matcher, err := strmatcher.Full.New(domain)
  37. common.Must(err)
  38. id := g.Add(matcher)
  39. address := ip.AsAddress()
  40. if address.Family().IsDomain() {
  41. return nil, newError("ignoring domain address in static hosts: ", address.Domain()).AtWarning()
  42. }
  43. sh.ips[id] = []net.IP{address.IP()}
  44. }
  45. }
  46. for _, mapping := range hosts {
  47. matcher, err := toStrMatcher(mapping.Type, mapping.Domain)
  48. if err != nil {
  49. return nil, newError("failed to create domain matcher").Base(err)
  50. }
  51. id := g.Add(matcher)
  52. ips := make([]net.IP, len(mapping.Ip))
  53. for idx, ip := range mapping.Ip {
  54. ips[idx] = net.IP(ip)
  55. }
  56. sh.ips[id] = ips
  57. }
  58. return sh, nil
  59. }
  60. func (h *StaticHosts) LookupIP(domain string) []net.IP {
  61. id := h.matchers.Match(domain)
  62. if id == 0 {
  63. return nil
  64. }
  65. return h.ips[id]
  66. }