From dba80e614eb6a31b6866e9c0bc5f23bff6c9b40a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 29 Jul 2026 13:51:47 +0800 Subject: [PATCH] Fix local DNS transport blocking on canceled queries --- experimental/libbox/dns.go | 59 ++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 31 deletions(-) diff --git a/experimental/libbox/dns.go b/experimental/libbox/dns.go index b7b3b0f6..75472188 100644 --- a/experimental/libbox/dns.go +++ b/experimental/libbox/dns.go @@ -13,7 +13,6 @@ import ( "github.com/sagernet/sing/common" E "github.com/sagernet/sing/common/exceptions" M "github.com/sagernet/sing/common/metadata" - "github.com/sagernet/sing/common/task" mDNS "github.com/miekg/dns" ) @@ -58,24 +57,23 @@ func (p *platformTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*m if err != nil { return nil, err } - var responseMessage *mDNS.Msg - var group task.Group - group.Append0(func(ctx context.Context) error { - err = p.iif.Exchange(response, messageBytes) + done := make(chan error, 1) + go func() { + exchangeErr := p.iif.Exchange(response, messageBytes) + if exchangeErr == nil { + exchangeErr = response.error + } + done <- exchangeErr + }() + select { + case err = <-done: if err != nil { - return err + return nil, err } - if response.error != nil { - return response.error - } - responseMessage = &response.message - return nil - }) - err = group.Run(ctx) - if err != nil { - return nil, err + return &response.message, nil + case <-ctx.Done(): + return nil, ctx.Err() } - return responseMessage, nil } else { question := message.Question[0] var network string @@ -87,24 +85,23 @@ func (p *platformTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*m default: return nil, E.New("only IP queries are supported by current version of Android") } - var responseAddrs []netip.Addr - var group task.Group - group.Append0(func(ctx context.Context) error { - err := p.iif.Lookup(response, network, question.Name) + done := make(chan error, 1) + go func() { + lookupErr := p.iif.Lookup(response, network, question.Name) + if lookupErr == nil { + lookupErr = response.error + } + done <- lookupErr + }() + select { + case err := <-done: if err != nil { - return err + return nil, err } - if response.error != nil { - return response.error - } - responseAddrs = response.addresses - return nil - }) - err := group.Run(ctx) - if err != nil { - return nil, err + return dns.FixedResponse(message.Id, question, response.addresses, C.DefaultDNSTTL), nil + case <-ctx.Done(): + return nil, ctx.Err() } - return dns.FixedResponse(message.Id, question, responseAddrs, C.DefaultDNSTTL), nil } }