diff --git a/dns/transport/local/local.go b/dns/transport/local/local.go index 66a220e8..1e823185 100644 --- a/dns/transport/local/local.go +++ b/dns/transport/local/local.go @@ -85,6 +85,10 @@ func (t *Transport) exchangeParallel(ctx context.Context, systemConfig *dnsConfi results := make(chan queryResult) startRacer := func(ctx context.Context, fqdn string) { response, err := t.tryOneName(ctx, systemConfig, fqdn, message) + addresses, _ := dns.MessageToAddresses(response) + if len(addresses) == 0 { + err = E.New(fqdn, ": empty result") + } select { case results <- queryResult{response, err}: case <-returned: @@ -92,14 +96,25 @@ func (t *Transport) exchangeParallel(ctx context.Context, systemConfig *dnsConfi } queryCtx, queryCancel := context.WithCancel(ctx) defer queryCancel() + var nameCount int for _, fqdn := range systemConfig.nameList(domain) { + nameCount++ go startRacer(queryCtx, fqdn) } - select { - case <-ctx.Done(): - return nil, ctx.Err() - case result := <-results: - return result.response, result.err + var errors []error + for { + select { + case <-ctx.Done(): + return nil, ctx.Err() + case result := <-results: + if result.err == nil { + return result.response, nil + } + errors = append(errors, result.err) + if len(errors) == nameCount { + return nil, E.Errors(errors...) + } + } } } @@ -120,7 +135,7 @@ func (t *Transport) tryOneName(ctx context.Context, config *dnsConfig, fqdn stri return response, nil } } - return nil, lastErr + return nil, E.Cause(lastErr, fqdn) } func (t *Transport) exchangeOne(ctx context.Context, server M.Socksaddr, question mDNS.Question, timeout time.Duration, useTCP, ad bool) (*mDNS.Msg, error) {