mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
Merge pull request #1039 from sanimej/fixes
Avoid V6 queries in docker domain going to external nameservers
This commit is contained in:
commit
f552ceccf0
3 changed files with 51 additions and 25 deletions
|
@ -1216,8 +1216,8 @@ func (f *fakeSandbox) SetKey(key string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func (f *fakeSandbox) ResolveName(name string, ipType int) []net.IP {
|
||||
return nil
|
||||
func (f *fakeSandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (f *fakeSandbox) ResolveIP(ip string) string {
|
||||
|
|
|
@ -186,18 +186,29 @@ func shuffleAddr(addr []net.IP) []net.IP {
|
|||
return addr
|
||||
}
|
||||
|
||||
func createRespMsg(query *dns.Msg) *dns.Msg {
|
||||
resp := new(dns.Msg)
|
||||
resp.SetReply(query)
|
||||
setCommonFlags(resp)
|
||||
|
||||
return resp
|
||||
}
|
||||
|
||||
func (r *resolver) handleIPQuery(name string, query *dns.Msg, ipType int) (*dns.Msg, error) {
|
||||
addr := r.sb.ResolveName(name, ipType)
|
||||
addr, ipv6Miss := r.sb.ResolveName(name, ipType)
|
||||
if addr == nil && ipv6Miss {
|
||||
// Send a reply without any Answer sections
|
||||
log.Debugf("Lookup name %s present without IPv6 address", name)
|
||||
resp := createRespMsg(query)
|
||||
return resp, nil
|
||||
}
|
||||
if addr == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
log.Debugf("Lookup for %s: IP %v", name, addr)
|
||||
|
||||
resp := new(dns.Msg)
|
||||
resp.SetReply(query)
|
||||
setCommonFlags(resp)
|
||||
|
||||
resp := createRespMsg(query)
|
||||
if len(addr) > 1 {
|
||||
addr = shuffleAddr(addr)
|
||||
}
|
||||
|
|
|
@ -37,9 +37,11 @@ type Sandbox interface {
|
|||
Rename(name string) error
|
||||
// Delete destroys this container after detaching it from all connected endpoints.
|
||||
Delete() error
|
||||
// ResolveName resolves a service name to an IPv4 or IPv6 address by searching the
|
||||
// networks the sandbox is connected to.
|
||||
ResolveName(name string, iplen int) []net.IP
|
||||
// ResolveName resolves a service name to an IPv4 or IPv6 address by searching
|
||||
// the networks the sandbox is connected to. For IPv6 queries, second return
|
||||
// value will be true if the name exists in docker domain but doesn't have an
|
||||
// IPv6 address. Such queries shouldn't be forwarded to external nameservers.
|
||||
ResolveName(name string, iplen int) ([]net.IP, bool)
|
||||
// ResolveIP returns the service name for the passed in IP. IP is in reverse dotted
|
||||
// notation; the format used for DNS PTR records
|
||||
ResolveIP(name string) string
|
||||
|
@ -419,9 +421,7 @@ func (sb *sandbox) execFunc(f func()) {
|
|||
sb.osSbox.InvokeFunc(f)
|
||||
}
|
||||
|
||||
func (sb *sandbox) ResolveName(name string, ipType int) []net.IP {
|
||||
var ip []net.IP
|
||||
|
||||
func (sb *sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
|
||||
// Embedded server owns the docker network domain. Resolution should work
|
||||
// for both container_name and container_name.network_name
|
||||
// We allow '.' in service name and network name. For a name a.b.c.d the
|
||||
|
@ -454,21 +454,29 @@ func (sb *sandbox) ResolveName(name string, ipType int) []net.IP {
|
|||
log.Debugf("To resolve: %v in %v", reqName[i], networkName[i])
|
||||
|
||||
// First check for local container alias
|
||||
ip = sb.resolveName(reqName[i], networkName[i], epList, true, ipType)
|
||||
ip, ipv6Miss := sb.resolveName(reqName[i], networkName[i], epList, true, ipType)
|
||||
if ip != nil {
|
||||
return ip
|
||||
return ip, false
|
||||
}
|
||||
if ipv6Miss {
|
||||
return ip, ipv6Miss
|
||||
}
|
||||
|
||||
// Resolve the actual container name
|
||||
ip = sb.resolveName(reqName[i], networkName[i], epList, false, ipType)
|
||||
ip, ipv6Miss = sb.resolveName(reqName[i], networkName[i], epList, false, ipType)
|
||||
if ip != nil {
|
||||
return ip
|
||||
return ip, false
|
||||
}
|
||||
if ipv6Miss {
|
||||
return ip, ipv6Miss
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil, false
|
||||
}
|
||||
|
||||
func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoint, alias bool, ipType int) []net.IP {
|
||||
func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoint, alias bool, ipType int) ([]net.IP, bool) {
|
||||
var ipv6Miss bool
|
||||
|
||||
for _, ep := range epList {
|
||||
name := req
|
||||
n := ep.getNetwork()
|
||||
|
@ -507,17 +515,24 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin
|
|||
|
||||
var ip []net.IP
|
||||
n.Lock()
|
||||
ip, ok = sr.svcMap[name]
|
||||
|
||||
if ipType == netutils.IPv6 {
|
||||
ip, ok = sr.svcIPv6Map[name]
|
||||
} else {
|
||||
ip, ok = sr.svcMap[name]
|
||||
// If the name resolved to v4 address then its a valid name in
|
||||
// the docker network domain. If the network is not v6 enabled
|
||||
// set ipv6Miss to filter the DNS query from going to external
|
||||
// resolvers.
|
||||
if ok && n.enableIPv6 == false {
|
||||
ipv6Miss = true
|
||||
}
|
||||
ip = sr.svcIPv6Map[name]
|
||||
}
|
||||
n.Unlock()
|
||||
if ok {
|
||||
return ip
|
||||
if ip != nil {
|
||||
return ip, false
|
||||
}
|
||||
}
|
||||
return nil
|
||||
return nil, ipv6Miss
|
||||
}
|
||||
|
||||
func (sb *sandbox) SetKey(basePath string) error {
|
||||
|
|
Loading…
Add table
Reference in a new issue