Fix local DNS transport blocking on canceled queries

This commit is contained in:
世界
2026-07-29 13:51:47 +08:00
parent c8f76760be
commit dba80e614e

View File

@@ -13,7 +13,6 @@ import (
"github.com/sagernet/sing/common" "github.com/sagernet/sing/common"
E "github.com/sagernet/sing/common/exceptions" E "github.com/sagernet/sing/common/exceptions"
M "github.com/sagernet/sing/common/metadata" M "github.com/sagernet/sing/common/metadata"
"github.com/sagernet/sing/common/task"
mDNS "github.com/miekg/dns" mDNS "github.com/miekg/dns"
) )
@@ -58,24 +57,23 @@ func (p *platformTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*m
if err != nil { if err != nil {
return nil, err return nil, err
} }
var responseMessage *mDNS.Msg done := make(chan error, 1)
var group task.Group go func() {
group.Append0(func(ctx context.Context) error { exchangeErr := p.iif.Exchange(response, messageBytes)
err = p.iif.Exchange(response, messageBytes) if exchangeErr == nil {
if err != nil { exchangeErr = response.error
return err
} }
if response.error != nil { done <- exchangeErr
return response.error }()
} select {
responseMessage = &response.message case err = <-done:
return nil
})
err = group.Run(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return responseMessage, nil return &response.message, nil
case <-ctx.Done():
return nil, ctx.Err()
}
} else { } else {
question := message.Question[0] question := message.Question[0]
var network string var network string
@@ -87,24 +85,23 @@ func (p *platformTransport) Exchange(ctx context.Context, message *mDNS.Msg) (*m
default: default:
return nil, E.New("only IP queries are supported by current version of Android") return nil, E.New("only IP queries are supported by current version of Android")
} }
var responseAddrs []netip.Addr done := make(chan error, 1)
var group task.Group go func() {
group.Append0(func(ctx context.Context) error { lookupErr := p.iif.Lookup(response, network, question.Name)
err := p.iif.Lookup(response, network, question.Name) if lookupErr == nil {
if err != nil { lookupErr = response.error
return err
} }
if response.error != nil { done <- lookupErr
return response.error }()
} select {
responseAddrs = response.addresses case err := <-done:
return nil
})
err := group.Run(ctx)
if err != nil { if err != nil {
return nil, err return nil, err
} }
return dns.FixedResponse(message.Id, question, responseAddrs, C.DefaultDNSTTL), nil return dns.FixedResponse(message.Id, question, response.addresses, C.DefaultDNSTTL), nil
case <-ctx.Done():
return nil, ctx.Err()
}
} }
} }