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