1
0
Fork 0
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:
Alessandro Boch 2016-03-21 15:39:15 -07:00
commit f552ceccf0
3 changed files with 51 additions and 25 deletions

View file

@ -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 {

View file

@ -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)
}

View file

@ -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 {