aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMartin Polden <mpolden@mpolden.no>2019-12-31 14:40:23 +0100
committerMartin Polden <mpolden@mpolden.no>2019-12-31 14:44:56 +0100
commitdb5514374114d4d4c1341dd19531425ef9c5de6d (patch)
tree47af90dc6bd4eb8503619f21cbe269f84b4a7f6a
parentc6e8a378544c055721ead3557c1de21bf30e4ab3 (diff)
Fix race in Exchange
-rw-r--r--dns/dnsutil/dnsutil.go14
1 files changed, 9 insertions, 5 deletions
diff --git a/dns/dnsutil/dnsutil.go b/dns/dnsutil/dnsutil.go
index c7b52f0..d66594b 100644
--- a/dns/dnsutil/dnsutil.go
+++ b/dns/dnsutil/dnsutil.go
@@ -1,7 +1,6 @@
package dnsutil
import (
- "errors"
"fmt"
"sync"
"time"
@@ -47,13 +46,13 @@ func (c *Client) Exchange(msg *dns.Msg) (*dns.Msg, error) {
ch := make(chan *dns.Msg, len(c.Addresses))
var wg sync.WaitGroup
wg.Add(len(c.Addresses))
- err := errors.New("addr is empty")
+ errs := make(chan error, len(c.Addresses))
for _, a := range c.Addresses {
go func(addr string) {
defer wg.Done()
- r, _, err1 := c.Exchanger.Exchange(msg, addr)
- if err1 != nil {
- err = fmt.Errorf("resolver %s failed: %w", addr, err1)
+ r, _, err := c.Exchanger.Exchange(msg, addr)
+ if err != nil {
+ errs <- fmt.Errorf("resolver %s failed: %w", addr, err)
return
}
ch <- r
@@ -62,10 +61,15 @@ func (c *Client) Exchange(msg *dns.Msg) (*dns.Msg, error) {
go func() {
wg.Wait()
done <- true
+ close(errs)
}()
for {
select {
case <-done:
+ err := <-errs
+ if err == nil {
+ err = fmt.Errorf("addresses is empty")
+ }
return nil, err
case rr := <-ch:
return rr, nil