libnetwork: extract DNS client exchange to method
forwardExtDNS() will now continue with the next external DNS sever if co.ReadMsg() returns (nil, nil). Previously it would abort resolving the query and not reply to the container client. The implementation of ReadMsg() in the currently- vendored version of miekg/dns cannot return (nil, nil) so the difference is immaterial in practice. Signed-off-by: Cory Snider <csnider@mirantis.com>
This commit is contained in:
parent
854ec3ffb3
commit
9cf8c4f689
1 changed files with 45 additions and 38 deletions
|
@ -452,58 +452,26 @@ func (r *resolver) dialExtDNS(proto string, server extDNSEntry) (net.Conn, error
|
|||
|
||||
func (r *resolver) forwardExtDNS(proto string, maxSize int, query *dns.Msg) *dns.Msg {
|
||||
queryName, queryType := query.Question[0].Name, query.Question[0].Qtype
|
||||
var resp *dns.Msg
|
||||
for i, extDNS := range r.extDNSList {
|
||||
for _, extDNS := range r.extDNSList {
|
||||
if extDNS.IPStr == "" {
|
||||
break
|
||||
}
|
||||
extConn, err := r.dialExtDNS(proto, extDNS)
|
||||
if err != nil {
|
||||
logrus.WithField("retries", i).WithError(err).Warn("[resolver] connect failed")
|
||||
continue
|
||||
}
|
||||
logrus.Debugf("[resolver] query %s (%s) from %s, forwarding to %s:%s", queryName, dns.TypeToString[queryType],
|
||||
extConn.LocalAddr().String(), proto, extDNS.IPStr)
|
||||
|
||||
// Timeout has to be set for every IO operation.
|
||||
if err := extConn.SetDeadline(time.Now().Add(extIOTimeout)); err != nil {
|
||||
logrus.WithError(err).Error("[resolver] error setting conn deadline")
|
||||
}
|
||||
co := &dns.Conn{
|
||||
Conn: extConn,
|
||||
UDPSize: uint16(maxSize),
|
||||
}
|
||||
defer co.Close()
|
||||
|
||||
// limits the number of outstanding concurrent queries.
|
||||
if !r.forwardQueryStart() {
|
||||
old := r.tStamp
|
||||
r.tStamp = time.Now()
|
||||
if r.tStamp.Sub(old) > logInterval {
|
||||
logrus.Errorf("[resolver] more than %v concurrent queries from %s", maxConcurrent, extConn.LocalAddr().String())
|
||||
logrus.Errorf("[resolver] more than %v concurrent queries", maxConcurrent)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
err = co.WriteMsg(query)
|
||||
if err != nil {
|
||||
r.forwardQueryEnd()
|
||||
logrus.Debugf("[resolver] send to DNS server failed, %s", err)
|
||||
continue
|
||||
}
|
||||
|
||||
resp, err = co.ReadMsg()
|
||||
if err != nil {
|
||||
r.forwardQueryEnd()
|
||||
logrus.WithError(err).Warnf("[resolver] failed to read from DNS server: %s, query: %s", extConn.RemoteAddr().String(), query.Question[0].String())
|
||||
continue
|
||||
}
|
||||
resp := r.exchange(proto, extDNS, maxSize, query)
|
||||
r.forwardQueryEnd()
|
||||
|
||||
if resp == nil {
|
||||
logrus.Debugf("[resolver] external DNS %s:%s returned empty response for %q", proto, extDNS.IPStr, queryName)
|
||||
break
|
||||
continue
|
||||
}
|
||||
|
||||
switch resp.Rcode {
|
||||
case dns.RcodeServerFailure, dns.RcodeRefused:
|
||||
// Server returned FAILURE: continue with the next external DNS server
|
||||
|
@ -544,7 +512,46 @@ func (r *resolver) forwardExtDNS(proto string, maxSize int, query *dns.Msg) *dns
|
|||
logrus.Debugf("[resolver] external DNS %s:%s did not return any %s records for %q", proto, extDNS.IPStr, dns.TypeToString[queryType], queryName)
|
||||
}
|
||||
resp.Compress = true
|
||||
break
|
||||
return resp
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *resolver) exchange(proto string, extDNS extDNSEntry, maxSize int, query *dns.Msg) *dns.Msg {
|
||||
queryName, queryType := query.Question[0].Name, query.Question[0].Qtype
|
||||
extConn, err := r.dialExtDNS(proto, extDNS)
|
||||
if err != nil {
|
||||
logrus.WithError(err).Warn("[resolver] connect failed")
|
||||
return nil
|
||||
}
|
||||
logrus.Debugf("[resolver] query %s (%s) from %s, forwarding to %s:%s", queryName, dns.TypeToString[queryType],
|
||||
extConn.LocalAddr().String(), proto, extDNS.IPStr)
|
||||
|
||||
// Timeout has to be set for every IO operation.
|
||||
if err := extConn.SetDeadline(time.Now().Add(extIOTimeout)); err != nil {
|
||||
logrus.WithError(err).Error("[resolver] error setting conn deadline")
|
||||
}
|
||||
co := &dns.Conn{
|
||||
Conn: extConn,
|
||||
UDPSize: uint16(maxSize),
|
||||
}
|
||||
defer co.Close()
|
||||
|
||||
err = co.WriteMsg(query)
|
||||
if err != nil {
|
||||
logrus.Debugf("[resolver] send to DNS server failed, %s", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
resp, err := co.ReadMsg()
|
||||
if err != nil {
|
||||
logrus.WithError(err).Warnf("[resolver] failed to read from DNS server: %s, query: %s", extConn.RemoteAddr().String(), query.Question[0].String())
|
||||
return nil
|
||||
}
|
||||
|
||||
if resp == nil {
|
||||
logrus.Debugf("[resolver] external DNS %s:%s returned empty response for %q", proto, extDNS.IPStr, queryName)
|
||||
}
|
||||
return resp
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue