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