fakednssniffer.go 3.8 KB

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