123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121 |
- package dispatcher
- import (
- "context"
- "strings"
- "github.com/xtls/xray-core/common"
- "github.com/xtls/xray-core/common/errors"
- "github.com/xtls/xray-core/common/net"
- "github.com/xtls/xray-core/common/session"
- "github.com/xtls/xray-core/core"
- "github.com/xtls/xray-core/features/dns"
- )
- // newFakeDNSSniffer Creates a Fake DNS metadata sniffer
- func newFakeDNSSniffer(ctx context.Context) (protocolSnifferWithMetadata, error) {
- var fakeDNSEngine dns.FakeDNSEngine
- {
- fakeDNSEngineFeat := core.MustFromContext(ctx).GetFeature((*dns.FakeDNSEngine)(nil))
- if fakeDNSEngineFeat != nil {
- fakeDNSEngine = fakeDNSEngineFeat.(dns.FakeDNSEngine)
- }
- }
- if fakeDNSEngine == nil {
- errNotInit := errors.New("FakeDNSEngine is not initialized, but such a sniffer is used").AtError()
- return protocolSnifferWithMetadata{}, errNotInit
- }
- return protocolSnifferWithMetadata{protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {
- outbounds := session.OutboundsFromContext(ctx)
- ob := outbounds[len(outbounds)-1]
- if ob.Target.Network == net.Network_TCP || ob.Target.Network == net.Network_UDP {
- domainFromFakeDNS := fakeDNSEngine.GetDomainFromFakeDNS(ob.Target.Address)
- if domainFromFakeDNS != "" {
- errors.LogInfo(ctx, "fake dns got domain: ", domainFromFakeDNS, " for ip: ", ob.Target.Address.String())
- return &fakeDNSSniffResult{domainName: domainFromFakeDNS}, nil
- }
- }
- if ipAddressInRangeValueI := ctx.Value(ipAddressInRange); ipAddressInRangeValueI != nil {
- ipAddressInRangeValue := ipAddressInRangeValueI.(*ipAddressInRangeOpt)
- if fkr0, ok := fakeDNSEngine.(dns.FakeDNSEngineRev0); ok {
- inPool := fkr0.IsIPInIPPool(ob.Target.Address)
- ipAddressInRangeValue.addressInRange = &inPool
- }
- }
- return nil, common.ErrNoClue
- }, metadataSniffer: true}, nil
- }
- type fakeDNSSniffResult struct {
- domainName string
- }
- func (fakeDNSSniffResult) Protocol() string {
- return "fakedns"
- }
- func (f fakeDNSSniffResult) Domain() string {
- return f.domainName
- }
- type fakeDNSExtraOpts int
- const ipAddressInRange fakeDNSExtraOpts = 1
- type ipAddressInRangeOpt struct {
- addressInRange *bool
- }
- type DNSThenOthersSniffResult struct {
- domainName string
- protocolOriginalName string
- }
- func (f DNSThenOthersSniffResult) IsProtoSubsetOf(protocolName string) bool {
- return strings.HasPrefix(protocolName, f.protocolOriginalName)
- }
- func (DNSThenOthersSniffResult) Protocol() string {
- return "fakedns+others"
- }
- func (f DNSThenOthersSniffResult) Domain() string {
- return f.domainName
- }
- func newFakeDNSThenOthers(ctx context.Context, fakeDNSSniffer protocolSnifferWithMetadata, others []protocolSnifferWithMetadata) (
- protocolSnifferWithMetadata, error,
- ) { // nolint: unparam
- // ctx may be used in the future
- _ = ctx
- return protocolSnifferWithMetadata{
- protocolSniffer: func(ctx context.Context, bytes []byte) (SniffResult, error) {
- ipAddressInRangeValue := &ipAddressInRangeOpt{}
- ctx = context.WithValue(ctx, ipAddressInRange, ipAddressInRangeValue)
- result, err := fakeDNSSniffer.protocolSniffer(ctx, bytes)
- if err == nil {
- return result, nil
- }
- if ipAddressInRangeValue.addressInRange != nil {
- if *ipAddressInRangeValue.addressInRange {
- for _, v := range others {
- if v.metadataSniffer || bytes != nil {
- if result, err := v.protocolSniffer(ctx, bytes); err == nil {
- return DNSThenOthersSniffResult{domainName: result.Domain(), protocolOriginalName: result.Protocol()}, nil
- }
- }
- }
- return nil, common.ErrNoClue
- }
- errors.LogDebug(ctx, "ip address not in fake dns range, return as is")
- return nil, common.ErrNoClue
- }
- errors.LogWarning(ctx, "fake dns sniffer did not set address in range option, assume false.")
- return nil, common.ErrNoClue
- },
- metadataSniffer: false,
- }, nil
- }
|