diff --git a/outbound/selector.go b/outbound/selector.go index 7326f58f..6caf8747 100644 --- a/outbound/selector.go +++ b/outbound/selector.go @@ -157,6 +157,9 @@ func (s *Selector) NewPacketConnection(ctx context.Context, conn N.PacketConn, m } func RealTag(detour adapter.Outbound) string { + if s, ok := detour.(*Selector); ok { + return RealTag(s.selected) + } if group, isGroup := detour.(adapter.OutboundGroup); isGroup { return group.Now() } diff --git a/route/router.go b/route/router.go index 110809f0..35533e02 100644 --- a/route/router.go +++ b/route/router.go @@ -21,16 +21,17 @@ import ( "github.com/sagernet/sing-box/common/process" "github.com/sagernet/sing-box/common/sniff" "github.com/sagernet/sing-box/common/taskmonitor" + "github.com/sagernet/sing-box/constant" C "github.com/sagernet/sing-box/constant" "github.com/sagernet/sing-box/experimental/libbox/platform" "github.com/sagernet/sing-box/log" "github.com/sagernet/sing-box/option" "github.com/sagernet/sing-box/outbound" "github.com/sagernet/sing-box/transport/fakeip" - "github.com/sagernet/sing-dns" - "github.com/sagernet/sing-mux" - "github.com/sagernet/sing-tun" - "github.com/sagernet/sing-vmess" + dns "github.com/sagernet/sing-dns" + mux "github.com/sagernet/sing-mux" + tun "github.com/sagernet/sing-tun" + vmess "github.com/sagernet/sing-vmess" "github.com/sagernet/sing/common" "github.com/sagernet/sing/common/buf" "github.com/sagernet/sing/common/bufio" @@ -1124,6 +1125,10 @@ func (r *Router) match(ctx context.Context, metadata *adapter.InboundContext, de } } ctx = outbound.ContextWithTag(ctx, matchOutbound.Tag()) + if matchOutbound.Type() == constant.TypeSelector { + tag := outbound.RealTag(matchOutbound) + metadata.Outbound = tag + } return ctx, matchRule, matchOutbound, nil } diff --git a/route/router_dns.go b/route/router_dns.go index ead8c289..5c4e1710 100644 --- a/route/router_dns.go +++ b/route/router_dns.go @@ -8,7 +8,9 @@ import ( "time" "github.com/sagernet/sing-box/adapter" - "github.com/sagernet/sing-dns" + "github.com/sagernet/sing-box/constant" + "github.com/sagernet/sing-box/outbound" + dns "github.com/sagernet/sing-dns" "github.com/sagernet/sing/common/cache" E "github.com/sagernet/sing/common/exceptions" F "github.com/sagernet/sing/common/format" @@ -127,6 +129,26 @@ func (r *Router) Exchange(ctx context.Context, message *mDNS.Msg) (*mDNS.Msg, er dnsCtx context.Context addressLimit bool ) + mOutbound := r.defaultOutboundForConnection + for i, rule := range r.rules { + metadata.ResetRuleCache() + if rule.Match(metadata) { + detour := rule.Outbound() + r.logger.DebugContext(ctx, "match[", i, "] ", rule.String(), " => ", detour) + if matchOutbound, loaded := r.Outbound(detour); loaded { + if matchOutbound.Type() != constant.TypeDNS { + mOutbound = matchOutbound + break + } else { + r.logger.DebugContext(ctx, "skip the dns outbound ", detour, matchOutbound.Type(), matchOutbound.Tag(), rule.String()) + continue + } + } + r.logger.ErrorContext(ctx, "outbound not found: ", detour) + } + } + tag := outbound.RealTag(mOutbound) + metadata.Outbound = tag dnsCtx, transport, strategy, rule, ruleIndex = r.matchDNS(ctx, true, ruleIndex, isAddressQuery(message)) dnsCtx = adapter.OverrideContext(dnsCtx) if rule != nil && rule.WithAddressLimit() {