context.go 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748
  1. package dns
  2. //go:generate go run github.com/v2fly/v2ray-core/v4/common/errors/errorgen
  3. import (
  4. "github.com/v2fly/v2ray-core/v4/common/net"
  5. "github.com/v2fly/v2ray-core/v4/features/dns"
  6. "github.com/v2fly/v2ray-core/v4/features/routing"
  7. )
  8. // ResolvableContext is an implementation of routing.Context, with domain resolving capability.
  9. type ResolvableContext struct {
  10. routing.Context
  11. dnsClient dns.Client
  12. resolvedIPs []net.IP
  13. }
  14. // GetTargetIPs overrides original routing.Context's implementation.
  15. func (ctx *ResolvableContext) GetTargetIPs() []net.IP {
  16. if ips := ctx.Context.GetTargetIPs(); len(ips) != 0 {
  17. return ips
  18. }
  19. if len(ctx.resolvedIPs) > 0 {
  20. return ctx.resolvedIPs
  21. }
  22. if domain := ctx.GetTargetDomain(); len(domain) != 0 {
  23. ips, err := ctx.dnsClient.LookupIP(domain, dns.IPOption{
  24. IPv4Enable: true,
  25. IPv6Enable: true,
  26. FakeEnable: false,
  27. })
  28. if err == nil {
  29. ctx.resolvedIPs = ips
  30. return ips
  31. }
  32. newError("resolve ip for ", domain).Base(err).WriteToLog()
  33. }
  34. return nil
  35. }
  36. // ContextWithDNSClient creates a new routing context with domain resolving capability.
  37. // Resolved domain IPs can be retrieved by GetTargetIPs().
  38. func ContextWithDNSClient(ctx routing.Context, client dns.Client) routing.Context {
  39. return &ResolvableContext{Context: ctx, dnsClient: client}
  40. }