Signed-off-by: Alessandro Boch <aboch@docker.com>
| ... | ... |
@@ -29,7 +29,7 @@ clone git github.com/RackSec/srslog 259aed10dfa74ea2961eddd1d9847619f6e98837 |
| 29 | 29 |
clone git github.com/imdario/mergo 0.2.1 |
| 30 | 30 |
|
| 31 | 31 |
#get libnetwork packages |
| 32 |
-clone git github.com/docker/libnetwork v0.7.0-dev.9 |
|
| 32 |
+clone git github.com/docker/libnetwork v0.7.0-dev.10 |
|
| 33 | 33 |
clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec |
| 34 | 34 |
clone git github.com/hashicorp/go-msgpack 71c2886f5a673a35f909803f38ece5810165097b |
| 35 | 35 |
clone git github.com/hashicorp/memberlist 9a1e242e454d2443df330bdd51a436d5a9058fc4 |
| ... | ... |
@@ -1144,10 +1144,10 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectDisconnectToStoppedContaine |
| 1144 | 1144 |
|
| 1145 | 1145 |
func (s *DockerNetworkSuite) TestDockerNetworkConnectPreferredIP(c *check.C) {
|
| 1146 | 1146 |
// create two networks |
| 1147 |
- dockerCmd(c, "network", "create", "--subnet=172.28.0.0/16", "--subnet=2001:db8:1234::/64", "n0") |
|
| 1147 |
+ dockerCmd(c, "network", "create", "--ipv6", "--subnet=172.28.0.0/16", "--subnet=2001:db8:1234::/64", "n0") |
|
| 1148 | 1148 |
assertNwIsAvailable(c, "n0") |
| 1149 | 1149 |
|
| 1150 |
- dockerCmd(c, "network", "create", "--subnet=172.30.0.0/16", "--ip-range=172.30.5.0/24", "--subnet=2001:db8:abcd::/64", "--ip-range=2001:db8:abcd::/80", "n1") |
|
| 1150 |
+ dockerCmd(c, "network", "create", "--ipv6", "--subnet=172.30.0.0/16", "--ip-range=172.30.5.0/24", "--subnet=2001:db8:abcd::/64", "--ip-range=2001:db8:abcd::/80", "n1") |
|
| 1151 | 1151 |
assertNwIsAvailable(c, "n1") |
| 1152 | 1152 |
|
| 1153 | 1153 |
// run a container on first network specifying the ip addresses |
| ... | ... |
@@ -1183,7 +1183,7 @@ func (s *DockerNetworkSuite) TestDockerNetworkConnectPreferredIPStoppedContainer |
| 1183 | 1183 |
dockerCmd(c, "create", "--name", "c0", "busybox", "top") |
| 1184 | 1184 |
|
| 1185 | 1185 |
// create a network |
| 1186 |
- dockerCmd(c, "network", "create", "--subnet=172.30.0.0/16", "--subnet=2001:db8:abcd::/64", "n0") |
|
| 1186 |
+ dockerCmd(c, "network", "create", "--ipv6", "--subnet=172.30.0.0/16", "--subnet=2001:db8:abcd::/64", "n0") |
|
| 1187 | 1187 |
assertNwIsAvailable(c, "n0") |
| 1188 | 1188 |
|
| 1189 | 1189 |
// connect the container to the network specifying an ip addresses |
| ... | ... |
@@ -1,5 +1,10 @@ |
| 1 | 1 |
# Changelog |
| 2 | 2 |
|
| 3 |
+## 0.7.0-dev.10 (2016-03-21) |
|
| 4 |
+- Add IPv6 service discovery (AAAA records) in embedded DNS server |
|
| 5 |
+- Honor enableIPv6 flag in network create for the IP allocation |
|
| 6 |
+- Avoid V6 queries in docker domain going to external nameservers |
|
| 7 |
+ |
|
| 3 | 8 |
## 0.7.0-dev.9 (2016-03-18) |
| 4 | 9 |
- Support labels on networks |
| 5 | 10 |
|
| ... | ... |
@@ -71,8 +71,9 @@ type NetworkInfo interface {
|
| 71 | 71 |
type EndpointWalker func(ep Endpoint) bool |
| 72 | 72 |
|
| 73 | 73 |
type svcInfo struct {
|
| 74 |
- svcMap map[string][]net.IP |
|
| 75 |
- ipMap map[string]string |
|
| 74 |
+ svcMap map[string][]net.IP |
|
| 75 |
+ svcIPv6Map map[string][]net.IP |
|
| 76 |
+ ipMap map[string]string |
|
| 76 | 77 |
} |
| 77 | 78 |
|
| 78 | 79 |
// IpamConf contains all the ipam related configurations for a network |
| ... | ... |
@@ -489,6 +490,10 @@ func (n *network) UnmarshalJSON(b []byte) (err error) {
|
| 489 | 489 |
if v, ok := netMap["inDelete"]; ok {
|
| 490 | 490 |
n.inDelete = v.(bool) |
| 491 | 491 |
} |
| 492 |
+ // Reconcile old networks with the recently added `--ipv6` flag |
|
| 493 |
+ if !n.enableIPv6 {
|
|
| 494 |
+ n.enableIPv6 = len(n.ipamV6Info) > 0 |
|
| 495 |
+ } |
|
| 492 | 496 |
return nil |
| 493 | 497 |
} |
| 494 | 498 |
|
| ... | ... |
@@ -779,7 +784,7 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi |
| 779 | 779 |
ep.ipamOptions[netlabel.MacAddress] = ep.iface.mac.String() |
| 780 | 780 |
} |
| 781 | 781 |
|
| 782 |
- if err = ep.assignAddress(ipam.driver, true, !n.postIPv6); err != nil {
|
|
| 782 |
+ if err = ep.assignAddress(ipam.driver, true, n.enableIPv6 && !n.postIPv6); err != nil {
|
|
| 783 | 783 |
return nil, err |
| 784 | 784 |
} |
| 785 | 785 |
defer func() {
|
| ... | ... |
@@ -799,7 +804,7 @@ func (n *network) CreateEndpoint(name string, options ...EndpointOption) (Endpoi |
| 799 | 799 |
} |
| 800 | 800 |
}() |
| 801 | 801 |
|
| 802 |
- if err = ep.assignAddress(ipam.driver, false, n.postIPv6); err != nil {
|
|
| 802 |
+ if err = ep.assignAddress(ipam.driver, false, n.enableIPv6 && n.postIPv6); err != nil {
|
|
| 803 | 803 |
return nil, err |
| 804 | 804 |
} |
| 805 | 805 |
|
| ... | ... |
@@ -890,68 +895,103 @@ func (n *network) EndpointByID(id string) (Endpoint, error) {
|
| 890 | 890 |
} |
| 891 | 891 |
|
| 892 | 892 |
func (n *network) updateSvcRecord(ep *endpoint, localEps []*endpoint, isAdd bool) {
|
| 893 |
+ var ipv6 net.IP |
|
| 893 | 894 |
epName := ep.Name() |
| 894 | 895 |
if iface := ep.Iface(); iface.Address() != nil {
|
| 895 | 896 |
myAliases := ep.MyAliases() |
| 897 |
+ if iface.AddressIPv6() != nil {
|
|
| 898 |
+ ipv6 = iface.AddressIPv6().IP |
|
| 899 |
+ } |
|
| 900 |
+ |
|
| 896 | 901 |
if isAdd {
|
| 897 | 902 |
// If anonymous endpoint has an alias use the first alias |
| 898 | 903 |
// for ip->name mapping. Not having the reverse mapping |
| 899 | 904 |
// breaks some apps |
| 900 | 905 |
if ep.isAnonymous() {
|
| 901 | 906 |
if len(myAliases) > 0 {
|
| 902 |
- n.addSvcRecords(myAliases[0], iface.Address().IP, true) |
|
| 907 |
+ n.addSvcRecords(myAliases[0], iface.Address().IP, ipv6, true) |
|
| 903 | 908 |
} |
| 904 | 909 |
} else {
|
| 905 |
- n.addSvcRecords(epName, iface.Address().IP, true) |
|
| 910 |
+ n.addSvcRecords(epName, iface.Address().IP, ipv6, true) |
|
| 906 | 911 |
} |
| 907 | 912 |
for _, alias := range myAliases {
|
| 908 |
- n.addSvcRecords(alias, iface.Address().IP, false) |
|
| 913 |
+ n.addSvcRecords(alias, iface.Address().IP, ipv6, false) |
|
| 909 | 914 |
} |
| 910 | 915 |
} else {
|
| 911 | 916 |
if ep.isAnonymous() {
|
| 912 | 917 |
if len(myAliases) > 0 {
|
| 913 |
- n.deleteSvcRecords(myAliases[0], iface.Address().IP, true) |
|
| 918 |
+ n.deleteSvcRecords(myAliases[0], iface.Address().IP, ipv6, true) |
|
| 914 | 919 |
} |
| 915 | 920 |
} else {
|
| 916 |
- n.deleteSvcRecords(epName, iface.Address().IP, true) |
|
| 921 |
+ n.deleteSvcRecords(epName, iface.Address().IP, ipv6, true) |
|
| 917 | 922 |
} |
| 918 | 923 |
for _, alias := range myAliases {
|
| 919 |
- n.deleteSvcRecords(alias, iface.Address().IP, false) |
|
| 924 |
+ n.deleteSvcRecords(alias, iface.Address().IP, ipv6, false) |
|
| 920 | 925 |
} |
| 921 | 926 |
} |
| 922 | 927 |
} |
| 923 | 928 |
} |
| 924 | 929 |
|
| 925 |
-func (n *network) addSvcRecords(name string, epIP net.IP, ipMapUpdate bool) {
|
|
| 930 |
+func addIPToName(ipMap map[string]string, name string, ip net.IP) {
|
|
| 931 |
+ reverseIP := netutils.ReverseIP(ip.String()) |
|
| 932 |
+ if _, ok := ipMap[reverseIP]; !ok {
|
|
| 933 |
+ ipMap[reverseIP] = name |
|
| 934 |
+ } |
|
| 935 |
+} |
|
| 936 |
+ |
|
| 937 |
+func addNameToIP(svcMap map[string][]net.IP, name string, epIP net.IP) {
|
|
| 938 |
+ ipList := svcMap[name] |
|
| 939 |
+ for _, ip := range ipList {
|
|
| 940 |
+ if ip.Equal(epIP) {
|
|
| 941 |
+ return |
|
| 942 |
+ } |
|
| 943 |
+ } |
|
| 944 |
+ svcMap[name] = append(svcMap[name], epIP) |
|
| 945 |
+} |
|
| 946 |
+ |
|
| 947 |
+func delNameToIP(svcMap map[string][]net.IP, name string, epIP net.IP) {
|
|
| 948 |
+ ipList := svcMap[name] |
|
| 949 |
+ for i, ip := range ipList {
|
|
| 950 |
+ if ip.Equal(epIP) {
|
|
| 951 |
+ ipList = append(ipList[:i], ipList[i+1:]...) |
|
| 952 |
+ break |
|
| 953 |
+ } |
|
| 954 |
+ } |
|
| 955 |
+ svcMap[name] = ipList |
|
| 956 |
+ |
|
| 957 |
+ if len(ipList) == 0 {
|
|
| 958 |
+ delete(svcMap, name) |
|
| 959 |
+ } |
|
| 960 |
+} |
|
| 961 |
+ |
|
| 962 |
+func (n *network) addSvcRecords(name string, epIP net.IP, epIPv6 net.IP, ipMapUpdate bool) {
|
|
| 926 | 963 |
c := n.getController() |
| 927 | 964 |
c.Lock() |
| 928 | 965 |
defer c.Unlock() |
| 929 | 966 |
sr, ok := c.svcDb[n.ID()] |
| 930 | 967 |
if !ok {
|
| 931 | 968 |
sr = svcInfo{
|
| 932 |
- svcMap: make(map[string][]net.IP), |
|
| 933 |
- ipMap: make(map[string]string), |
|
| 969 |
+ svcMap: make(map[string][]net.IP), |
|
| 970 |
+ svcIPv6Map: make(map[string][]net.IP), |
|
| 971 |
+ ipMap: make(map[string]string), |
|
| 934 | 972 |
} |
| 935 | 973 |
c.svcDb[n.ID()] = sr |
| 936 | 974 |
} |
| 937 | 975 |
|
| 938 | 976 |
if ipMapUpdate {
|
| 939 |
- reverseIP := netutils.ReverseIP(epIP.String()) |
|
| 940 |
- if _, ok := sr.ipMap[reverseIP]; !ok {
|
|
| 941 |
- sr.ipMap[reverseIP] = name |
|
| 977 |
+ addIPToName(sr.ipMap, name, epIP) |
|
| 978 |
+ if epIPv6 != nil {
|
|
| 979 |
+ addIPToName(sr.ipMap, name, epIPv6) |
|
| 942 | 980 |
} |
| 943 | 981 |
} |
| 944 | 982 |
|
| 945 |
- ipList := sr.svcMap[name] |
|
| 946 |
- for _, ip := range ipList {
|
|
| 947 |
- if ip.Equal(epIP) {
|
|
| 948 |
- return |
|
| 949 |
- } |
|
| 983 |
+ addNameToIP(sr.svcMap, name, epIP) |
|
| 984 |
+ if epIPv6 != nil {
|
|
| 985 |
+ addNameToIP(sr.svcIPv6Map, name, epIPv6) |
|
| 950 | 986 |
} |
| 951 |
- sr.svcMap[name] = append(sr.svcMap[name], epIP) |
|
| 952 | 987 |
} |
| 953 | 988 |
|
| 954 |
-func (n *network) deleteSvcRecords(name string, epIP net.IP, ipMapUpdate bool) {
|
|
| 989 |
+func (n *network) deleteSvcRecords(name string, epIP net.IP, epIPv6 net.IP, ipMapUpdate bool) {
|
|
| 955 | 990 |
c := n.getController() |
| 956 | 991 |
c.Lock() |
| 957 | 992 |
defer c.Unlock() |
| ... | ... |
@@ -962,19 +1002,16 @@ func (n *network) deleteSvcRecords(name string, epIP net.IP, ipMapUpdate bool) {
|
| 962 | 962 |
|
| 963 | 963 |
if ipMapUpdate {
|
| 964 | 964 |
delete(sr.ipMap, netutils.ReverseIP(epIP.String())) |
| 965 |
- } |
|
| 966 | 965 |
|
| 967 |
- ipList := sr.svcMap[name] |
|
| 968 |
- for i, ip := range ipList {
|
|
| 969 |
- if ip.Equal(epIP) {
|
|
| 970 |
- ipList = append(ipList[:i], ipList[i+1:]...) |
|
| 971 |
- break |
|
| 966 |
+ if epIPv6 != nil {
|
|
| 967 |
+ delete(sr.ipMap, netutils.ReverseIP(epIPv6.String())) |
|
| 972 | 968 |
} |
| 973 | 969 |
} |
| 974 |
- sr.svcMap[name] = ipList |
|
| 975 | 970 |
|
| 976 |
- if len(ipList) == 0 {
|
|
| 977 |
- delete(sr.svcMap, name) |
|
| 971 |
+ delNameToIP(sr.svcMap, name, epIP) |
|
| 972 |
+ |
|
| 973 |
+ if epIPv6 != nil {
|
|
| 974 |
+ delNameToIP(sr.svcIPv6Map, name, epIPv6) |
|
| 978 | 975 |
} |
| 979 | 976 |
} |
| 980 | 977 |
|
| ... | ... |
@@ -1033,6 +1070,10 @@ func (n *network) ipamAllocate() error {
|
| 1033 | 1033 |
} |
| 1034 | 1034 |
}() |
| 1035 | 1035 |
|
| 1036 |
+ if !n.enableIPv6 {
|
|
| 1037 |
+ return nil |
|
| 1038 |
+ } |
|
| 1039 |
+ |
|
| 1036 | 1040 |
return n.ipamAllocateVersion(6, ipam) |
| 1037 | 1041 |
} |
| 1038 | 1042 |
|
| ... | ... |
@@ -1153,7 +1194,7 @@ func (n *network) ipamReleaseVersion(ipVer int, ipam ipamapi.Ipam) {
|
| 1153 | 1153 |
return |
| 1154 | 1154 |
} |
| 1155 | 1155 |
|
| 1156 |
- if *infoList == nil {
|
|
| 1156 |
+ if len(*infoList) == 0 {
|
|
| 1157 | 1157 |
return |
| 1158 | 1158 |
} |
| 1159 | 1159 |
|
| ... | ... |
@@ -10,6 +10,7 @@ import ( |
| 10 | 10 |
|
| 11 | 11 |
log "github.com/Sirupsen/logrus" |
| 12 | 12 |
"github.com/docker/libnetwork/iptables" |
| 13 |
+ "github.com/docker/libnetwork/netutils" |
|
| 13 | 14 |
"github.com/miekg/dns" |
| 14 | 15 |
) |
| 15 | 16 |
|
| ... | ... |
@@ -185,27 +186,46 @@ func shuffleAddr(addr []net.IP) []net.IP {
|
| 185 | 185 |
return addr |
| 186 | 186 |
} |
| 187 | 187 |
|
| 188 |
-func (r *resolver) handleIPv4Query(name string, query *dns.Msg) (*dns.Msg, error) {
|
|
| 189 |
- addr := r.sb.ResolveName(name) |
|
| 188 |
+func createRespMsg(query *dns.Msg) *dns.Msg {
|
|
| 189 |
+ resp := new(dns.Msg) |
|
| 190 |
+ resp.SetReply(query) |
|
| 191 |
+ setCommonFlags(resp) |
|
| 192 |
+ |
|
| 193 |
+ return resp |
|
| 194 |
+} |
|
| 195 |
+ |
|
| 196 |
+func (r *resolver) handleIPQuery(name string, query *dns.Msg, ipType int) (*dns.Msg, error) {
|
|
| 197 |
+ addr, ipv6Miss := r.sb.ResolveName(name, ipType) |
|
| 198 |
+ if addr == nil && ipv6Miss {
|
|
| 199 |
+ // Send a reply without any Answer sections |
|
| 200 |
+ log.Debugf("Lookup name %s present without IPv6 address", name)
|
|
| 201 |
+ resp := createRespMsg(query) |
|
| 202 |
+ return resp, nil |
|
| 203 |
+ } |
|
| 190 | 204 |
if addr == nil {
|
| 191 | 205 |
return nil, nil |
| 192 | 206 |
} |
| 193 | 207 |
|
| 194 | 208 |
log.Debugf("Lookup for %s: IP %v", name, addr)
|
| 195 | 209 |
|
| 196 |
- resp := new(dns.Msg) |
|
| 197 |
- resp.SetReply(query) |
|
| 198 |
- setCommonFlags(resp) |
|
| 199 |
- |
|
| 210 |
+ resp := createRespMsg(query) |
|
| 200 | 211 |
if len(addr) > 1 {
|
| 201 | 212 |
addr = shuffleAddr(addr) |
| 202 | 213 |
} |
| 203 |
- |
|
| 204 |
- for _, ip := range addr {
|
|
| 205 |
- rr := new(dns.A) |
|
| 206 |
- rr.Hdr = dns.RR_Header{Name: name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: respTTL}
|
|
| 207 |
- rr.A = ip |
|
| 208 |
- resp.Answer = append(resp.Answer, rr) |
|
| 214 |
+ if ipType == netutils.IPv4 {
|
|
| 215 |
+ for _, ip := range addr {
|
|
| 216 |
+ rr := new(dns.A) |
|
| 217 |
+ rr.Hdr = dns.RR_Header{Name: name, Rrtype: dns.TypeA, Class: dns.ClassINET, Ttl: respTTL}
|
|
| 218 |
+ rr.A = ip |
|
| 219 |
+ resp.Answer = append(resp.Answer, rr) |
|
| 220 |
+ } |
|
| 221 |
+ } else {
|
|
| 222 |
+ for _, ip := range addr {
|
|
| 223 |
+ rr := new(dns.AAAA) |
|
| 224 |
+ rr.Hdr = dns.RR_Header{Name: name, Rrtype: dns.TypeAAAA, Class: dns.ClassINET, Ttl: respTTL}
|
|
| 225 |
+ rr.AAAA = ip |
|
| 226 |
+ resp.Answer = append(resp.Answer, rr) |
|
| 227 |
+ } |
|
| 209 | 228 |
} |
| 210 | 229 |
return resp, nil |
| 211 | 230 |
} |
| ... | ... |
@@ -264,7 +284,9 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) {
|
| 264 | 264 |
} |
| 265 | 265 |
name := query.Question[0].Name |
| 266 | 266 |
if query.Question[0].Qtype == dns.TypeA {
|
| 267 |
- resp, err = r.handleIPv4Query(name, query) |
|
| 267 |
+ resp, err = r.handleIPQuery(name, query, netutils.IPv4) |
|
| 268 |
+ } else if query.Question[0].Qtype == dns.TypeAAAA {
|
|
| 269 |
+ resp, err = r.handleIPQuery(name, query, netutils.IPv6) |
|
| 268 | 270 |
} else if query.Question[0].Qtype == dns.TypePTR {
|
| 269 | 271 |
resp, err = r.handlePTRQuery(name, query) |
| 270 | 272 |
} |
| ... | ... |
@@ -11,6 +11,7 @@ import ( |
| 11 | 11 |
log "github.com/Sirupsen/logrus" |
| 12 | 12 |
"github.com/docker/libnetwork/etchosts" |
| 13 | 13 |
"github.com/docker/libnetwork/netlabel" |
| 14 |
+ "github.com/docker/libnetwork/netutils" |
|
| 14 | 15 |
"github.com/docker/libnetwork/osl" |
| 15 | 16 |
"github.com/docker/libnetwork/types" |
| 16 | 17 |
) |
| ... | ... |
@@ -36,9 +37,11 @@ type Sandbox interface {
|
| 36 | 36 |
Rename(name string) error |
| 37 | 37 |
// Delete destroys this container after detaching it from all connected endpoints. |
| 38 | 38 |
Delete() error |
| 39 |
- // ResolveName searches for the service name in the networks to which the sandbox |
|
| 40 |
- // is connected to. |
|
| 41 |
- ResolveName(name string) []net.IP |
|
| 39 |
+ // ResolveName resolves a service name to an IPv4 or IPv6 address by searching |
|
| 40 |
+ // the networks the sandbox is connected to. For IPv6 queries, second return |
|
| 41 |
+ // value will be true if the name exists in docker domain but doesn't have an |
|
| 42 |
+ // IPv6 address. Such queries shouldn't be forwarded to external nameservers. |
|
| 43 |
+ ResolveName(name string, iplen int) ([]net.IP, bool) |
|
| 42 | 44 |
// ResolveIP returns the service name for the passed in IP. IP is in reverse dotted |
| 43 | 45 |
// notation; the format used for DNS PTR records |
| 44 | 46 |
ResolveIP(name string) string |
| ... | ... |
@@ -418,9 +421,7 @@ func (sb *sandbox) execFunc(f func()) {
|
| 418 | 418 |
sb.osSbox.InvokeFunc(f) |
| 419 | 419 |
} |
| 420 | 420 |
|
| 421 |
-func (sb *sandbox) ResolveName(name string) []net.IP {
|
|
| 422 |
- var ip []net.IP |
|
| 423 |
- |
|
| 421 |
+func (sb *sandbox) ResolveName(name string, ipType int) ([]net.IP, bool) {
|
|
| 424 | 422 |
// Embedded server owns the docker network domain. Resolution should work |
| 425 | 423 |
// for both container_name and container_name.network_name |
| 426 | 424 |
// We allow '.' in service name and network name. For a name a.b.c.d the |
| ... | ... |
@@ -453,21 +454,29 @@ func (sb *sandbox) ResolveName(name string) []net.IP {
|
| 453 | 453 |
log.Debugf("To resolve: %v in %v", reqName[i], networkName[i])
|
| 454 | 454 |
|
| 455 | 455 |
// First check for local container alias |
| 456 |
- ip = sb.resolveName(reqName[i], networkName[i], epList, true) |
|
| 456 |
+ ip, ipv6Miss := sb.resolveName(reqName[i], networkName[i], epList, true, ipType) |
|
| 457 | 457 |
if ip != nil {
|
| 458 |
- return ip |
|
| 458 |
+ return ip, false |
|
| 459 |
+ } |
|
| 460 |
+ if ipv6Miss {
|
|
| 461 |
+ return ip, ipv6Miss |
|
| 459 | 462 |
} |
| 460 | 463 |
|
| 461 | 464 |
// Resolve the actual container name |
| 462 |
- ip = sb.resolveName(reqName[i], networkName[i], epList, false) |
|
| 465 |
+ ip, ipv6Miss = sb.resolveName(reqName[i], networkName[i], epList, false, ipType) |
|
| 463 | 466 |
if ip != nil {
|
| 464 |
- return ip |
|
| 467 |
+ return ip, false |
|
| 468 |
+ } |
|
| 469 |
+ if ipv6Miss {
|
|
| 470 |
+ return ip, ipv6Miss |
|
| 465 | 471 |
} |
| 466 | 472 |
} |
| 467 |
- return nil |
|
| 473 |
+ return nil, false |
|
| 468 | 474 |
} |
| 469 | 475 |
|
| 470 |
-func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoint, alias bool) []net.IP {
|
|
| 476 |
+func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoint, alias bool, ipType int) ([]net.IP, bool) {
|
|
| 477 |
+ var ipv6Miss bool |
|
| 478 |
+ |
|
| 471 | 479 |
for _, ep := range epList {
|
| 472 | 480 |
name := req |
| 473 | 481 |
n := ep.getNetwork() |
| ... | ... |
@@ -504,14 +513,26 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin |
| 504 | 504 |
continue |
| 505 | 505 |
} |
| 506 | 506 |
|
| 507 |
+ var ip []net.IP |
|
| 507 | 508 |
n.Lock() |
| 508 |
- ip, ok := sr.svcMap[name] |
|
| 509 |
+ ip, ok = sr.svcMap[name] |
|
| 510 |
+ |
|
| 511 |
+ if ipType == netutils.IPv6 {
|
|
| 512 |
+ // If the name resolved to v4 address then its a valid name in |
|
| 513 |
+ // the docker network domain. If the network is not v6 enabled |
|
| 514 |
+ // set ipv6Miss to filter the DNS query from going to external |
|
| 515 |
+ // resolvers. |
|
| 516 |
+ if ok && n.enableIPv6 == false {
|
|
| 517 |
+ ipv6Miss = true |
|
| 518 |
+ } |
|
| 519 |
+ ip = sr.svcIPv6Map[name] |
|
| 520 |
+ } |
|
| 509 | 521 |
n.Unlock() |
| 510 |
- if ok {
|
|
| 511 |
- return ip |
|
| 522 |
+ if ip != nil {
|
|
| 523 |
+ return ip, false |
|
| 512 | 524 |
} |
| 513 | 525 |
} |
| 514 |
- return nil |
|
| 526 |
+ return nil, ipv6Miss |
|
| 515 | 527 |
} |
| 516 | 528 |
|
| 517 | 529 |
func (sb *sandbox) SetKey(basePath string) error {
|