resolver.go 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267
  1. package resolver
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "net"
  7. "net/netip"
  8. "strings"
  9. "time"
  10. "github.com/metacubex/mihomo/common/utils"
  11. "github.com/metacubex/mihomo/component/trie"
  12. "github.com/metacubex/randv2"
  13. "github.com/miekg/dns"
  14. )
  15. var (
  16. // DefaultResolver aim to resolve ip
  17. DefaultResolver Resolver
  18. // ProxyServerHostResolver resolve ip to proxies server host
  19. ProxyServerHostResolver Resolver
  20. // DisableIPv6 means don't resolve ipv6 host
  21. // default value is true
  22. DisableIPv6 = true
  23. // DefaultHosts aim to resolve hosts
  24. DefaultHosts = NewHosts(trie.New[HostValue]())
  25. // DefaultDNSTimeout defined the default dns request timeout
  26. DefaultDNSTimeout = time.Second * 5
  27. )
  28. var (
  29. ErrIPNotFound = errors.New("couldn't find ip")
  30. ErrIPVersion = errors.New("ip version error")
  31. ErrIPv6Disabled = errors.New("ipv6 disabled")
  32. )
  33. type Resolver interface {
  34. LookupIP(ctx context.Context, host string) (ips []netip.Addr, err error)
  35. LookupIPv4(ctx context.Context, host string) (ips []netip.Addr, err error)
  36. LookupIPv6(ctx context.Context, host string) (ips []netip.Addr, err error)
  37. ExchangeContext(ctx context.Context, m *dns.Msg) (msg *dns.Msg, err error)
  38. Invalid() bool
  39. }
  40. // LookupIPv4WithResolver same as LookupIPv4, but with a resolver
  41. func LookupIPv4WithResolver(ctx context.Context, host string, r Resolver) ([]netip.Addr, error) {
  42. if node, ok := DefaultHosts.Search(host, false); ok {
  43. if addrs := utils.Filter(node.IPs, func(ip netip.Addr) bool {
  44. return ip.Is4()
  45. }); len(addrs) > 0 {
  46. return addrs, nil
  47. }
  48. }
  49. ip, err := netip.ParseAddr(host)
  50. if err == nil {
  51. if ip.Is4() || ip.Is4In6() {
  52. return []netip.Addr{ip}, nil
  53. }
  54. return []netip.Addr{}, ErrIPVersion
  55. }
  56. if r != nil && r.Invalid() {
  57. return r.LookupIPv4(ctx, host)
  58. }
  59. ipAddrs, err := net.DefaultResolver.LookupNetIP(ctx, "ip4", host)
  60. if err != nil {
  61. return nil, err
  62. } else if len(ipAddrs) == 0 {
  63. return nil, ErrIPNotFound
  64. }
  65. return ipAddrs, nil
  66. }
  67. // LookupIPv4 with a host, return ipv4 list
  68. func LookupIPv4(ctx context.Context, host string) ([]netip.Addr, error) {
  69. return LookupIPv4WithResolver(ctx, host, DefaultResolver)
  70. }
  71. // ResolveIPv4WithResolver same as ResolveIPv4, but with a resolver
  72. func ResolveIPv4WithResolver(ctx context.Context, host string, r Resolver) (netip.Addr, error) {
  73. ips, err := LookupIPv4WithResolver(ctx, host, r)
  74. if err != nil {
  75. return netip.Addr{}, err
  76. } else if len(ips) == 0 {
  77. return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host)
  78. }
  79. return ips[randv2.IntN(len(ips))], nil
  80. }
  81. // ResolveIPv4 with a host, return ipv4
  82. func ResolveIPv4(ctx context.Context, host string) (netip.Addr, error) {
  83. return ResolveIPv4WithResolver(ctx, host, DefaultResolver)
  84. }
  85. // LookupIPv6WithResolver same as LookupIPv6, but with a resolver
  86. func LookupIPv6WithResolver(ctx context.Context, host string, r Resolver) ([]netip.Addr, error) {
  87. if DisableIPv6 {
  88. return nil, ErrIPv6Disabled
  89. }
  90. if node, ok := DefaultHosts.Search(host, false); ok {
  91. if addrs := utils.Filter(node.IPs, func(ip netip.Addr) bool {
  92. return ip.Is6()
  93. }); len(addrs) > 0 {
  94. return addrs, nil
  95. }
  96. }
  97. if ip, err := netip.ParseAddr(host); err == nil {
  98. if strings.Contains(host, ":") {
  99. return []netip.Addr{ip}, nil
  100. }
  101. return nil, ErrIPVersion
  102. }
  103. if r != nil && r.Invalid() {
  104. return r.LookupIPv6(ctx, host)
  105. }
  106. ipAddrs, err := net.DefaultResolver.LookupNetIP(ctx, "ip6", host)
  107. if err != nil {
  108. return nil, err
  109. } else if len(ipAddrs) == 0 {
  110. return nil, ErrIPNotFound
  111. }
  112. return ipAddrs, nil
  113. }
  114. // LookupIPv6 with a host, return ipv6 list
  115. func LookupIPv6(ctx context.Context, host string) ([]netip.Addr, error) {
  116. return LookupIPv6WithResolver(ctx, host, DefaultResolver)
  117. }
  118. // ResolveIPv6WithResolver same as ResolveIPv6, but with a resolver
  119. func ResolveIPv6WithResolver(ctx context.Context, host string, r Resolver) (netip.Addr, error) {
  120. ips, err := LookupIPv6WithResolver(ctx, host, r)
  121. if err != nil {
  122. return netip.Addr{}, err
  123. } else if len(ips) == 0 {
  124. return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host)
  125. }
  126. return ips[randv2.IntN(len(ips))], nil
  127. }
  128. func ResolveIPv6(ctx context.Context, host string) (netip.Addr, error) {
  129. return ResolveIPv6WithResolver(ctx, host, DefaultResolver)
  130. }
  131. // LookupIPWithResolver same as LookupIP, but with a resolver
  132. func LookupIPWithResolver(ctx context.Context, host string, r Resolver) ([]netip.Addr, error) {
  133. if node, ok := DefaultHosts.Search(host, false); ok {
  134. return node.IPs, nil
  135. }
  136. if r != nil && r.Invalid() {
  137. if DisableIPv6 {
  138. return r.LookupIPv4(ctx, host)
  139. }
  140. return r.LookupIP(ctx, host)
  141. } else if DisableIPv6 {
  142. return LookupIPv4WithResolver(ctx, host, r)
  143. }
  144. if ip, err := netip.ParseAddr(host); err == nil {
  145. return []netip.Addr{ip}, nil
  146. }
  147. ips, err := net.DefaultResolver.LookupNetIP(ctx, "ip", host)
  148. if err != nil {
  149. return nil, err
  150. } else if len(ips) == 0 {
  151. return nil, ErrIPNotFound
  152. }
  153. return ips, nil
  154. }
  155. // LookupIP with a host, return ip
  156. func LookupIP(ctx context.Context, host string) ([]netip.Addr, error) {
  157. return LookupIPWithResolver(ctx, host, DefaultResolver)
  158. }
  159. // ResolveIPWithResolver same as ResolveIP, but with a resolver
  160. func ResolveIPWithResolver(ctx context.Context, host string, r Resolver) (netip.Addr, error) {
  161. ips, err := LookupIPWithResolver(ctx, host, r)
  162. if err != nil {
  163. return netip.Addr{}, err
  164. } else if len(ips) == 0 {
  165. return netip.Addr{}, fmt.Errorf("%w: %s", ErrIPNotFound, host)
  166. }
  167. ipv4s, ipv6s := SortationAddr(ips)
  168. if len(ipv4s) > 0 {
  169. return ipv4s[randv2.IntN(len(ipv4s))], nil
  170. }
  171. return ipv6s[randv2.IntN(len(ipv6s))], nil
  172. }
  173. // ResolveIP with a host, return ip and priority return TypeA
  174. func ResolveIP(ctx context.Context, host string) (netip.Addr, error) {
  175. return ResolveIPWithResolver(ctx, host, DefaultResolver)
  176. }
  177. // ResolveIPv4ProxyServerHost proxies server host only
  178. func ResolveIPv4ProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
  179. if ProxyServerHostResolver != nil {
  180. return ResolveIPv4WithResolver(ctx, host, ProxyServerHostResolver)
  181. }
  182. return ResolveIPv4(ctx, host)
  183. }
  184. // ResolveIPv6ProxyServerHost proxies server host only
  185. func ResolveIPv6ProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
  186. if ProxyServerHostResolver != nil {
  187. return ResolveIPv6WithResolver(ctx, host, ProxyServerHostResolver)
  188. }
  189. return ResolveIPv6(ctx, host)
  190. }
  191. // ResolveProxyServerHost proxies server host only
  192. func ResolveProxyServerHost(ctx context.Context, host string) (netip.Addr, error) {
  193. if ProxyServerHostResolver != nil {
  194. return ResolveIPWithResolver(ctx, host, ProxyServerHostResolver)
  195. }
  196. return ResolveIP(ctx, host)
  197. }
  198. func LookupIPv6ProxyServerHost(ctx context.Context, host string) ([]netip.Addr, error) {
  199. if ProxyServerHostResolver != nil {
  200. return LookupIPv6WithResolver(ctx, host, ProxyServerHostResolver)
  201. }
  202. return LookupIPv6(ctx, host)
  203. }
  204. func LookupIPv4ProxyServerHost(ctx context.Context, host string) ([]netip.Addr, error) {
  205. if ProxyServerHostResolver != nil {
  206. return LookupIPv4WithResolver(ctx, host, ProxyServerHostResolver)
  207. }
  208. return LookupIPv4(ctx, host)
  209. }
  210. func LookupIPProxyServerHost(ctx context.Context, host string) ([]netip.Addr, error) {
  211. if ProxyServerHostResolver != nil {
  212. return LookupIPWithResolver(ctx, host, ProxyServerHostResolver)
  213. }
  214. return LookupIP(ctx, host)
  215. }
  216. func SortationAddr(ips []netip.Addr) (ipv4s, ipv6s []netip.Addr) {
  217. for _, v := range ips {
  218. if v.Unmap().Is4() {
  219. ipv4s = append(ipv4s, v)
  220. } else {
  221. ipv6s = append(ipv6s, v)
  222. }
  223. }
  224. return
  225. }