fakednssniffer.go 3.7 KB

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