diff --git a/app/dispatcher/default.go b/app/dispatcher/default.go index 53c5774ed..ef00f533e 100644 --- a/app/dispatcher/default.go +++ b/app/dispatcher/default.go @@ -186,6 +186,11 @@ func shouldOverride(result SniffResult, domainOverride []string) bool { if strings.HasPrefix(protocolString, p) { return true } + if resultSubset, ok := result.(SnifferIsProtoSubsetOf); ok { + if resultSubset.IsProtoSubsetOf(p) { + return true + } + } } return false } diff --git a/app/dispatcher/fakednssniffer.go b/app/dispatcher/fakednssniffer.go index 56e65f5e8..0bc632472 100644 --- a/app/dispatcher/fakednssniffer.go +++ b/app/dispatcher/fakednssniffer.go @@ -4,6 +4,7 @@ package dispatcher import ( "context" + "strings" core "github.com/v2fly/v2ray-core/v4" "github.com/v2fly/v2ray-core/v4/common" @@ -68,7 +69,15 @@ type ipAddressInRangeOpt struct { } type DNSThenOthersSniffResult struct { - domainName string + domainName string + protocolOriginalName string +} + +func (f DNSThenOthersSniffResult) IsProtoSubsetOf(protocolName string) bool { + if strings.HasPrefix(protocolName, f.protocolOriginalName) { + return true + } + return false } func (DNSThenOthersSniffResult) Protocol() string { @@ -93,7 +102,7 @@ func newFakeDNSThenOthers(ctx context.Context, fakeDNSSniffer protocolSnifferWit for _, v := range others { if v.metadataSniffer || bytes != nil { if result, err := v.protocolSniffer(ctx, bytes); err == nil { - return DNSThenOthersSniffResult{result.Domain()}, nil + return DNSThenOthersSniffResult{domainName: result.Domain(), protocolOriginalName: result.Protocol()}, nil } } } @@ -107,6 +116,6 @@ func newFakeDNSThenOthers(ctx context.Context, fakeDNSSniffer protocolSnifferWit return nil, common.ErrNoClue } }, - metadataSniffer: true, + metadataSniffer: false, }, nil } diff --git a/app/dispatcher/sniffer.go b/app/dispatcher/sniffer.go index 57fcae063..a0d35015e 100644 --- a/app/dispatcher/sniffer.go +++ b/app/dispatcher/sniffer.go @@ -42,8 +42,8 @@ func NewSniffer(ctx context.Context) *Sniffer { others := ret.sniffer ret.sniffer = append(ret.sniffer, sniffer) fakeDNSThenOthers, err := newFakeDNSThenOthers(ctx, sniffer, others) - if err != nil { - ret.sniffer = append(ret.sniffer, fakeDNSThenOthers) + if err == nil { + ret.sniffer = append([]protocolSnifferWithMetadata{fakeDNSThenOthers}, ret.sniffer...) } } return ret @@ -128,3 +128,7 @@ func (c compositeResult) ProtocolForDomainResult() string { type SnifferResultComposite interface { ProtocolForDomainResult() string } + +type SnifferIsProtoSubsetOf interface { + IsProtoSubsetOf(protocolName string) bool +} diff --git a/infra/conf/v2ray.go b/infra/conf/v2ray.go index 9a6f2e0c7..f3e7b485c 100644 --- a/infra/conf/v2ray.go +++ b/infra/conf/v2ray.go @@ -75,6 +75,8 @@ func (c *SniffingConfig) Build() (*proxyman.SniffingConfig, error) { p = append(p, "tls") case "fakedns": p = append(p, "fakedns") + case "fakedns+others": + p = append(p, "fakedns+others") default: return nil, newError("unknown protocol: ", domainOverride) }