plugin/{forward,proxy}: check for truncated (#1644)

Check for trunacted in the lookup function as well and use the Match
function here as well.
This commit is contained in:
Miek Gieben
2018-03-31 15:31:03 +01:00
committed by GitHub
parent f19a3b24ca
commit fd1501e918
4 changed files with 40 additions and 16 deletions

View File

@@ -92,20 +92,7 @@ func (f *Forward) ServeDNS(ctx context.Context, w dns.ResponseWriter, r *dns.Msg
child.Finish() child.Finish()
} }
// If you query for instance ANY isc.org; you get a truncated query back which miekg/dns fails to unpack ret, err = truncated(ret, err)
// because the RRs are not finished. The returned message can be useful or useless. Return the original
// query with some header bits set that they should retry with TCP.
if err == dns.ErrTruncated {
// We may or may not have something sensible... if not reassemble something to send to the client.
if ret == nil {
ret = new(dns.Msg)
ret.SetReply(r)
ret.Truncated = true
ret.Authoritative = true
ret.Rcode = dns.RcodeSuccess
}
err = nil // and reset err to pass this back to the client.
}
if err != nil { if err != nil {
// Kick off health check to see if *our* upstream is broken. // Kick off health check to see if *our* upstream is broken.

View File

@@ -31,15 +31,22 @@ func (f *Forward) Forward(state request.Request) (*dns.Msg, error) {
} }
ret, err := proxy.connect(context.Background(), state, f.forceTCP, true) ret, err := proxy.connect(context.Background(), state, f.forceTCP, true)
ret, err = truncated(ret, err)
if err != nil { if err != nil {
if fails < len(f.proxies) { if fails < len(f.proxies) {
continue continue
} }
break break
} }
return ret, nil // Check if the reply is correct; if not return FormErr.
if !state.Match(ret) {
return state.ErrorMessage(dns.RcodeFormatError), nil
}
return ret, err
} }
return nil, errNoHealthy return nil, errNoHealthy
} }

View File

@@ -0,0 +1,25 @@
package forward
import "github.com/miekg/dns"
// truncated looks at the error and if truncated return a nil errror
// and a possible reconstructed dns message if that was nil.
func truncated(ret *dns.Msg, err error) (*dns.Msg, error) {
// If you query for instance ANY isc.org; you get a truncated query back which miekg/dns fails to unpack
// because the RRs are not finished. The returned message can be useful or useless. Return the original
// query with some header bits set that they should retry with TCP.
if err != dns.ErrTruncated {
return ret, err
}
// We may or may not have something sensible... if not reassemble something to send to the client.
m := ret
if ret == nil {
m = new(dns.Msg)
m.SetReply(ret)
m.Truncated = true
m.Authoritative = true
m.Rcode = dns.RcodeSuccess
}
return m, nil
}

View File

@@ -92,6 +92,11 @@ func (p Proxy) lookup(state request.Request) (*dns.Msg, error) {
atomic.AddInt64(&host.Conns, -1) atomic.AddInt64(&host.Conns, -1)
if backendErr == nil { if backendErr == nil {
if !state.Match(reply) {
return state.ErrorMessage(dns.RcodeFormatError), nil
}
return reply, nil return reply, nil
} }