Skip to content

Commit

Permalink
Allow dns query to fail when set "spray" option.
Browse files Browse the repository at this point in the history
When the "spray" parameter is set, dnsredir will retry indefinitely
when it encounters an error. When the network is temporarily
interrupted or misconfigured, dnsredir will eat all the CPU.

This patch fixes this issue.

Signed-off-by: yuguorui <[email protected]>
  • Loading branch information
yuguorui committed Dec 23, 2021
1 parent 3c328f6 commit e21d020
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
5 changes: 4 additions & 1 deletion dnsredir.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,15 @@ func (r *Dnsredir) ServeDNS(ctx context.Context, w dns.ResponseWriter, req *dns.

var reply *dns.Msg
var upstreamErr error
var tryCount int32
deadline := time.Now().Add(defaultTimeout)
tryCount = 0
for time.Now().Before(deadline) {
tryCount += 1
start := time.Now()

host := upstream.Select()
if host == nil {
if host == nil || tryCount > upstream.maxRetry {
log.Debug(errNoHealthy)
return dns.RcodeServerFailure, errNoHealthy
}
Expand Down
14 changes: 12 additions & 2 deletions upstream.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ type reloadableUpstream struct {
ipset interface{}
pf interface{}
noIPv6 bool
maxRetry int32
}

// reloadableUpstream implements Upstream interface
Expand Down Expand Up @@ -124,8 +125,9 @@ func newReloadableUpstream(c *caddy.Controller) (Upstream, error) {
urlReadTimeout: defaultUrlReadTimeout,
stopUrlReload: make(chan struct{}),
},
ignored: make(domainSet),
inline: make(domainSet),
ignored: make(domainSet),
inline: make(domainSet),
maxRetry: defaultMaxRetry,
HealthCheck: &HealthCheck{
stop: make(chan struct{}),
maxFails: defaultMaxFails,
Expand Down Expand Up @@ -362,6 +364,13 @@ func parseBlock(c *caddy.Controller, u *reloadableUpstream) error {
}
u.maxFails = n
log.Infof("%v: %v", dir, n)
case "max_retry":
n, err := parseInt32(c)
if err != nil {
return err
}
u.maxRetry = n
log.Infof("%v: %v", dir, n)
case "health_check":
args := c.RemainingArgs()
n := len(args)
Expand Down Expand Up @@ -585,6 +594,7 @@ func parseBootstrap(c *caddy.Controller, u *reloadableUpstream) error {

const (
defaultMaxFails = 3
defaultMaxRetry = 10

defaultPathReloadInterval = 2 * time.Second
defaultUrlReloadInterval = 30 * time.Minute
Expand Down

0 comments on commit e21d020

Please sign in to comment.