fakednssniffer.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. package dispatcher
  2. import (
  3. "context"
  4. "strings"
  5. "github.com/xtls/xray-core/common"
  6. "github.com/xtls/xray-core/common/net"
  7. "github.com/xtls/xray-core/common/session"
  8. "github.com/xtls/xray-core/core"
  9. "github.com/xtls/xray-core/features/dns"
  10. )
  11. // newFakeDNSSniffer Creates a Fake DNS metadata sniffer
  12. func newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error) {
  13. var fakeDNSEngine dns.FakeDNSEngine
  14. {
  15. fakeDNSEngineFeat := core.MustFromContext(ctx).GetFeature(fakeDNSEngine)
  16. if fakeDNSEngineFeat != nil {
  17. fakeDNSEngine = fakeDNSEngineFeat.(dns.FakeDNSEngine)
  18. }
  19. }
  20. if fakeDNSEngine == nil {
  21. errNotInit := newError("FakeDNSEngine is not initialized, but such a sniffer is used").AtError()
  22. return protocolSnifferWithMetadata{}, errNotInit
  23. }
  24. return protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {
  25. Target := session.OutboundFromContext(ctx).Target
  26. if Target.Network == net.Network_TCP || Target.Network == net.Network_UDP {
  27. domainFromFakeDNS := fakeDNSEngine.GetDomainFromFakeDNS(Target.Address)
  28. if domainFromFakeDNS != "" {
  29. newError("fake dns got domain: ", domainFromFakeDNS, " for ip: ", Target.Address.String()).WriteToLog(session.ExportIDToError(ctx))
  30. return &fakeDNSSniffResult{domainName: domainFromFakeDNS}, nil
  31. }
  32. }
  33. if ipAddressInRangeValueI := ctx.Value(ipAddressInRange); ipAddressInRangeValueI != nil {
  34. ipAddressInRangeValue := ipAddressInRangeValueI.(*ipAddressInRangeOpt)
  35. if fkr0, ok := fakeDNSEngine.(dns.FakeDNSEngineRev0); ok {
  36. inPool := fkr0.IsIPInIPPool(Target.Address)
  37. ipAddressInRangeValue.addressInRange = &inPool
  38. }
  39. }
  40. return nil, common.ErrNoClue
  41. }, metadataSniffer: true}, nil
  42. }
  43. type fakeDNSSniffResult struct {
  44. domainName string
  45. }
  46. func (fakeDNSSniffResult) Protocol() string {
  47. return "fakedns"
  48. }
  49. func (f fakeDNSSniffResult) Domain() string {
  50. return f.domainName
  51. }
  52. type fakeDNSExtraOpts int
  53. const ipAddressInRange fakeDNSExtraOpts = 1
  54. type ipAddressInRangeOpt struct {
  55. addressInRange *bool
  56. }
  57. type DNSThenOthersSniffResult struct {
  58. domainName string
  59. protocolOriginalName string
  60. }
  61. func (f DNSThenOthersSniffResult) IsProtoSubsetOf(protocolName string) bool {
  62. return strings.HasPrefix(protocolName, f.protocolOriginalName)
  63. }
  64. func (DNSThenOthersSniffResult) Protocol() string {
  65. return "fakedns+others"
  66. }
  67. func (f DNSThenOthersSniffResult) Domain() string {
  68. return f.domainName
  69. }
  70. func newFakeDNSThenOthers(ctx context.Context, fakeDNSSniffer protocolSnifferWithMetadata, others []protocolSnifferWithMetadata) (
  71. protocolSnifferWithMetadata, error) { // nolint: unparam
  72. // ctx may be used in the future
  73. _ = ctx
  74. return protocolSnifferWithMetadata{
  75. protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {
  76. ipAddressInRangeValue := &ipAddressInRangeOpt{}
  77. ctx = context.WithValue(ctx, ipAddressInRange, ipAddressInRangeValue)
  78. result, err := fakeDNSSniffer.protocolSniffer(ctx, bytes)
  79. if err == nil {
  80. return result, nil
  81. }
  82. if ipAddressInRangeValue.addressInRange != nil {
  83. if *ipAddressInRangeValue.addressInRange {
  84. for _, v := range others {
  85. if v.metadataSniffer || bytes != nil {
  86. if result, err := v.protocolSniffer(ctx, bytes); err == nil {
  87. return DNSThenOthersSniffResult{domainName: result.Domain(), protocolOriginalName: result.Protocol()}, nil
  88. }
  89. }
  90. }
  91. return nil, common.ErrNoClue
  92. }
  93. newError("ip address not in fake dns range, return as is").AtDebug().WriteToLog()
  94. return nil, common.ErrNoClue
  95. }
  96. newError("fake dns sniffer did not set address in range option, assume false.").AtWarning().WriteToLog()
  97. return nil, common.ErrNoClue
  98. },
  99. metadataSniffer: false,
  100. }, nil
  101. }