|
@@ -85,6 +85,10 @@ func (t *Transport) exchangeParallel(ctx context.Context, systemConfig *dnsConfi
|
|
results := make(chan queryResult)
|
|
results := make(chan queryResult)
|
|
startRacer := func(ctx context.Context, fqdn string) {
|
|
startRacer := func(ctx context.Context, fqdn string) {
|
|
response, err := t.tryOneName(ctx, systemConfig, fqdn, message)
|
|
response, err := t.tryOneName(ctx, systemConfig, fqdn, message)
|
|
|
|
+ addresses, _ := dns.MessageToAddresses(response)
|
|
|
|
+ if len(addresses) == 0 {
|
|
|
|
+ err = E.New(fqdn, ": empty result")
|
|
|
|
+ }
|
|
select {
|
|
select {
|
|
case results <- queryResult{response, err}:
|
|
case results <- queryResult{response, err}:
|
|
case <-returned:
|
|
case <-returned:
|
|
@@ -92,14 +96,25 @@ func (t *Transport) exchangeParallel(ctx context.Context, systemConfig *dnsConfi
|
|
}
|
|
}
|
|
queryCtx, queryCancel := context.WithCancel(ctx)
|
|
queryCtx, queryCancel := context.WithCancel(ctx)
|
|
defer queryCancel()
|
|
defer queryCancel()
|
|
|
|
+ var nameCount int
|
|
for _, fqdn := range systemConfig.nameList(domain) {
|
|
for _, fqdn := range systemConfig.nameList(domain) {
|
|
|
|
+ nameCount++
|
|
go startRacer(queryCtx, fqdn)
|
|
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 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) {
|
|
func (t *Transport) exchangeOne(ctx context.Context, server M.Socksaddr, question mDNS.Question, timeout time.Duration, useTCP, ad bool) (*mDNS.Msg, error) {
|