context.go 1.3 KB

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