diff options
author | Martin Polden <mpolden@mpolden.no> | 2019-12-31 14:40:23 +0100 |
---|---|---|
committer | Martin Polden <mpolden@mpolden.no> | 2019-12-31 14:44:56 +0100 |
commit | db5514374114d4d4c1341dd19531425ef9c5de6d (patch) | |
tree | 47af90dc6bd4eb8503619f21cbe269f84b4a7f6a | |
parent | c6e8a378544c055721ead3557c1de21bf30e4ab3 (diff) |
Fix race in Exchange
-rw-r--r-- | dns/dnsutil/dnsutil.go | 14 |
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 |