diff --git a/container/container.go b/container/container.go index a6278f0f67..5b73672070 100644 --- a/container/container.go +++ b/container/container.go @@ -782,7 +782,7 @@ func (container *Container) BuildJoinOptions(n libnetwork.Network) ([]libnetwork } // BuildCreateEndpointOptions builds endpoint options from a given network. -func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epConfig *networktypes.EndpointSettings, sb libnetwork.Sandbox) ([]libnetwork.EndpointOption, error) { +func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epConfig *networktypes.EndpointSettings, sb libnetwork.Sandbox, daemonDNS []string) ([]libnetwork.EndpointOption, error) { var ( bindings = make(nat.PortMap) pbList []types.PortBinding @@ -792,7 +792,8 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC defaultNetName := runconfig.DefaultDaemonNetworkMode().NetworkName() - if n.Name() == defaultNetName || container.NetworkSettings.IsAnonymousEndpoint { + if (!container.EnableServiceDiscoveryOnDefaultNetwork() && n.Name() == defaultNetName) || + container.NetworkSettings.IsAnonymousEndpoint { createOptions = append(createOptions, libnetwork.CreateOptionAnonymous()) } @@ -914,6 +915,19 @@ func (container *Container) BuildCreateEndpointOptions(n libnetwork.Network, epC } } + var dns []string + + if len(container.HostConfig.DNS) > 0 { + dns = container.HostConfig.DNS + } else if len(daemonDNS) > 0 { + dns = daemonDNS + } + + if len(dns) > 0 { + createOptions = append(createOptions, + libnetwork.CreateOptionDNS(dns)) + } + createOptions = append(createOptions, libnetwork.CreateOptionPortMapping(pbList), libnetwork.CreateOptionExposedPorts(exposeList)) diff --git a/container/container_solaris.go b/container/container_solaris.go index 5c5b66e022..32c0edb6c4 100644 --- a/container/container_solaris.go +++ b/container/container_solaris.go @@ -93,3 +93,8 @@ func (container *Container) BuildHostnameFile() error { func (container *Container) canMountFS() bool { return true } + +// EnableServiceDiscoveryOnDefaultNetwork Enable service discovery on default network +func (container *Container) EnableServiceDiscoveryOnDefaultNetwork() bool { + return false +} diff --git a/container/container_unix.go b/container/container_unix.go index 22c07c2652..02e6ad81ba 100644 --- a/container/container_unix.go +++ b/container/container_unix.go @@ -428,3 +428,8 @@ func cleanResourcePath(path string) string { func (container *Container) canMountFS() bool { return true } + +// EnableServiceDiscoveryOnDefaultNetwork Enable service discovery on default network +func (container *Container) EnableServiceDiscoveryOnDefaultNetwork() bool { + return false +} diff --git a/container/container_windows.go b/container/container_windows.go index 0a6c7a8ff8..736c7e95d8 100644 --- a/container/container_windows.go +++ b/container/container_windows.go @@ -110,3 +110,8 @@ func (container *Container) BuildHostnameFile() error { func (container *Container) canMountFS() bool { return !containertypes.Isolation.IsHyperV(container.HostConfig.Isolation) } + +// EnableServiceDiscoveryOnDefaultNetwork Enable service discovery on default network +func (container *Container) EnableServiceDiscoveryOnDefaultNetwork() bool { + return true +} diff --git a/daemon/container_operations.go b/daemon/container_operations.go index 64335b0218..d6a8374f18 100644 --- a/daemon/container_operations.go +++ b/daemon/container_operations.go @@ -598,11 +598,12 @@ func cleanOperationalData(es *network.EndpointSettings) { } func (daemon *Daemon) updateNetworkConfig(container *container.Container, n libnetwork.Network, endpointConfig *networktypes.EndpointSettings, updateSettings bool) error { + if !containertypes.NetworkMode(n.Name()).IsUserDefined() { if hasUserDefinedIPAddress(endpointConfig) && !enableIPOnPredefinedNetwork() { return runconfig.ErrUnsupportedNetworkAndIP } - if endpointConfig != nil && len(endpointConfig.Aliases) > 0 { + if endpointConfig != nil && len(endpointConfig.Aliases) > 0 && !container.EnableServiceDiscoveryOnDefaultNetwork() { return runconfig.ErrUnsupportedNetworkAndAlias } } else { @@ -674,9 +675,8 @@ func (daemon *Daemon) connectToNetwork(container *container.Container, idOrName } controller := daemon.netController - sb := daemon.getNetworkSandbox(container) - createOptions, err := container.BuildCreateEndpointOptions(n, endpointConfig, sb) + createOptions, err := container.BuildCreateEndpointOptions(n, endpointConfig, sb, daemon.configStore.DNS) if err != nil { return err } diff --git a/daemon/start_windows.go b/daemon/start_windows.go index 710c8ccbf4..160a57e860 100644 --- a/daemon/start_windows.go +++ b/daemon/start_windows.go @@ -53,6 +53,7 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain // Get endpoints for the libnetwork allocated networks to the container var epList []string + AllowUnqualifiedDNSQuery := false if container.NetworkSettings != nil { for n := range container.NetworkSettings.Networks { sn, err := daemon.FindNetwork(n) @@ -72,6 +73,10 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain if data["hnsid"] != nil { epList = append(epList, data["hnsid"].(string)) } + + if data["AllowUnqualifiedDNSQuery"] != nil { + AllowUnqualifiedDNSQuery = true + } } } @@ -80,7 +85,7 @@ func (daemon *Daemon) getLibcontainerdCreateOptions(container *container.Contain createOptions = append(createOptions, hvOpts) createOptions = append(createOptions, layerOpts) if epList != nil { - createOptions = append(createOptions, &libcontainerd.NetworkEndpointsOption{Endpoints: epList}) + createOptions = append(createOptions, &libcontainerd.NetworkEndpointsOption{Endpoints: epList, AllowUnqualifiedDNSQuery: AllowUnqualifiedDNSQuery}) } return &createOptions, nil diff --git a/hack/vendor.sh b/hack/vendor.sh index 81cae7aa43..1b0435c774 100755 --- a/hack/vendor.sh +++ b/hack/vendor.sh @@ -48,7 +48,7 @@ esac # the following lines are in sorted order, FYI clone git github.com/Azure/go-ansiterm 388960b655244e76e24c75f48631564eaefade62 -clone git github.com/Microsoft/hcsshim v0.4.2 +clone git github.com/Microsoft/hcsshim v0.4.3 clone git github.com/Microsoft/go-winio v0.3.4 clone git github.com/Sirupsen/logrus v0.10.0 # logrus is a common dependency among multiple deps clone git github.com/docker/libtrust 9cbd2a1374f46905c68a4eb3694a130610adc62a @@ -70,7 +70,7 @@ clone git github.com/RackSec/srslog 365bf33cd9acc21ae1c355209865f17228ca534e clone git github.com/imdario/mergo 0.2.1 #get libnetwork packages -clone git github.com/docker/libnetwork c8ce8c78b46da08976cfb817011ca5cb97adb576 +clone git github.com/docker/libnetwork e69621c5fb6882627f83187ebefe7709a7211277 clone git github.com/docker/go-events 18b43f1bc85d9cdd42c05a6cd2d444c7a200a894 clone git github.com/armon/go-radix e39d623f12e8e41c7b5529e9a9dd67a1e2261f80 clone git github.com/armon/go-metrics eb0af217e5e9747e41dd5303755356b62d28e3ec diff --git a/libcontainerd/client_windows.go b/libcontainerd/client_windows.go index e3cb7a8d62..b6a4b6b939 100644 --- a/libcontainerd/client_windows.go +++ b/libcontainerd/client_windows.go @@ -150,6 +150,7 @@ func (clnt *client) Create(containerID string, checkpoint string, checkpointDir } if n, ok := option.(*NetworkEndpointsOption); ok { configuration.EndpointList = n.Endpoints + configuration.AllowUnqualifiedDNSQuery = n.AllowUnqualifiedDNSQuery continue } } diff --git a/libcontainerd/types_windows.go b/libcontainerd/types_windows.go index 89652f1ff9..5a50771a74 100644 --- a/libcontainerd/types_windows.go +++ b/libcontainerd/types_windows.go @@ -64,7 +64,8 @@ type LayerOption struct { // NetworkEndpointsOption is a CreateOption that provides the runtime list // of network endpoints to which a container should be attached during its creation. type NetworkEndpointsOption struct { - Endpoints []string + Endpoints []string + AllowUnqualifiedDNSQuery bool } // Checkpoint holds the details of a checkpoint (not supported in windows) diff --git a/vendor/src/github.com/Microsoft/hcsshim/hcsshim.go b/vendor/src/github.com/Microsoft/hcsshim/hcsshim.go index 6b83a5ba64..eaecf1321e 100644 --- a/vendor/src/github.com/Microsoft/hcsshim/hcsshim.go +++ b/vendor/src/github.com/Microsoft/hcsshim/hcsshim.go @@ -14,6 +14,7 @@ import ( //go:generate go run mksyscall_windows.go -output zhcsshim.go hcsshim.go //sys coTaskMemFree(buffer unsafe.Pointer) = ole32.CoTaskMemFree +//sys SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) = iphlpapi.SetCurrentThreadCompartmentId //sys activateLayer(info *driverInfo, id string) (hr error) = vmcompute.ActivateLayer? //sys copyLayer(info *driverInfo, srcId string, dstId string, descriptors []WC_LAYER_DESCRIPTOR) (hr error) = vmcompute.CopyLayer? diff --git a/vendor/src/github.com/Microsoft/hcsshim/hnsfuncs.go b/vendor/src/github.com/Microsoft/hcsshim/hnsfuncs.go index 642b3167b2..7bf46a6881 100644 --- a/vendor/src/github.com/Microsoft/hcsshim/hnsfuncs.go +++ b/vendor/src/github.com/Microsoft/hcsshim/hnsfuncs.go @@ -33,8 +33,9 @@ type VsidPolicy struct { // Subnet is assoicated with a network and represents a list // of subnets available to the network type Subnet struct { - AddressPrefix string `json:",omitempty"` - GatewayAddress string `json:",omitempty"` + AddressPrefix string `json:",omitempty"` + GatewayAddress string `json:",omitempty"` + Policies []json.RawMessage `json:",omitempty"` } // MacPool is assoicated with a network and represents a list @@ -46,16 +47,17 @@ type MacPool struct { // HNSNetwork represents a network in HNS type HNSNetwork struct { - Id string `json:",omitempty"` - Name string `json:",omitempty"` - Type string `json:",omitempty"` - NetworkAdapterName string `json:",omitempty"` - SourceMac string `json:",omitempty"` - Policies []json.RawMessage `json:",omitempty"` - MacPools []MacPool `json:",omitempty"` - Subnets []Subnet `json:",omitempty"` - DNSSuffix string `json:",omitempty"` - DNSServerList string `json:",omitempty"` + Id string `json:",omitempty"` + Name string `json:",omitempty"` + Type string `json:",omitempty"` + NetworkAdapterName string `json:",omitempty"` + SourceMac string `json:",omitempty"` + Policies []json.RawMessage `json:",omitempty"` + MacPools []MacPool `json:",omitempty"` + Subnets []Subnet `json:",omitempty"` + DNSSuffix string `json:",omitempty"` + DNSServerList string `json:",omitempty"` + DNSServerCompartment uint32 `json:",omitempty"` } // HNSEndpoint represents a network endpoint in HNS @@ -70,6 +72,7 @@ type HNSEndpoint struct { DNSSuffix string `json:",omitempty"` DNSServerList string `json:",omitempty"` GatewayAddress string `json:",omitempty"` + EnableInternalDNS bool `json:",omitempty"` PrefixLength uint8 `json:",omitempty"` } diff --git a/vendor/src/github.com/Microsoft/hcsshim/interface.go b/vendor/src/github.com/Microsoft/hcsshim/interface.go index 31210c366d..528cde2f86 100644 --- a/vendor/src/github.com/Microsoft/hcsshim/interface.go +++ b/vendor/src/github.com/Microsoft/hcsshim/interface.go @@ -38,29 +38,30 @@ type HvRuntime struct { // ContainerConfig is used as both the input of CreateContainer // and to convert the parameters to JSON for passing onto the HCS type ContainerConfig struct { - SystemType string // HCS requires this to be hard-coded to "Container" - Name string // Name of the container. We use the docker ID. - Owner string // The management platform that created this container - IsDummy bool // Used for development purposes. - VolumePath string // Windows volume path for scratch space - IgnoreFlushesDuringBoot bool // Optimization hint for container startup in Windows - LayerFolderPath string // Where the layer folders are located - Layers []Layer // List of storage layers - Credentials string `json:",omitempty"` // Credentials information - ProcessorCount uint32 `json:",omitempty"` // Number of processors to assign to the container. - ProcessorWeight uint64 `json:",omitempty"` // CPU Shares 0..10000 on Windows; where 0 will be omitted and HCS will default. - ProcessorMaximum int64 `json:",omitempty"` // CPU maximum usage percent 1..100 - StorageIOPSMaximum uint64 `json:",omitempty"` // Maximum Storage IOPS - StorageBandwidthMaximum uint64 `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second - StorageSandboxSize uint64 `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller - MemoryMaximumInMB int64 `json:",omitempty"` // Maximum memory available to the container in Megabytes - HostName string // Hostname - MappedDirectories []MappedDir // List of mapped directories (volumes/mounts) - SandboxPath string // Location of unmounted sandbox (used for Hyper-V containers) - HvPartition bool // True if it a Hyper-V Container - EndpointList []string // List of networking endpoints to be attached to container - HvRuntime *HvRuntime // Hyper-V container settings - Servicing bool // True if this container is for servicing + SystemType string // HCS requires this to be hard-coded to "Container" + Name string // Name of the container. We use the docker ID. + Owner string // The management platform that created this container + IsDummy bool // Used for development purposes. + VolumePath string // Windows volume path for scratch space + IgnoreFlushesDuringBoot bool // Optimization hint for container startup in Windows + LayerFolderPath string // Where the layer folders are located + Layers []Layer // List of storage layers + Credentials string `json:",omitempty"` // Credentials information + ProcessorCount uint32 `json:",omitempty"` // Number of processors to assign to the container. + ProcessorWeight uint64 `json:",omitempty"` // CPU Shares 0..10000 on Windows; where 0 will be omitted and HCS will default. + ProcessorMaximum int64 `json:",omitempty"` // CPU maximum usage percent 1..100 + StorageIOPSMaximum uint64 `json:",omitempty"` // Maximum Storage IOPS + StorageBandwidthMaximum uint64 `json:",omitempty"` // Maximum Storage Bandwidth in bytes per second + StorageSandboxSize uint64 `json:",omitempty"` // Size in bytes that the container system drive should be expanded to if smaller + MemoryMaximumInMB int64 `json:",omitempty"` // Maximum memory available to the container in Megabytes + HostName string // Hostname + MappedDirectories []MappedDir // List of mapped directories (volumes/mounts) + SandboxPath string // Location of unmounted sandbox (used for Hyper-V containers) + HvPartition bool // True if it a Hyper-V Container + EndpointList []string // List of networking endpoints to be attached to container + HvRuntime *HvRuntime // Hyper-V container settings + Servicing bool // True if this container is for servicing + AllowUnqualifiedDNSQuery bool // True to allow unqualified DNS name resolution } // Container represents a created (but not necessarily running) container. diff --git a/vendor/src/github.com/Microsoft/hcsshim/zhcsshim.go b/vendor/src/github.com/Microsoft/hcsshim/zhcsshim.go index a1faeaa083..3ae95864cc 100644 --- a/vendor/src/github.com/Microsoft/hcsshim/zhcsshim.go +++ b/vendor/src/github.com/Microsoft/hcsshim/zhcsshim.go @@ -10,9 +10,11 @@ var _ unsafe.Pointer var ( modole32 = syscall.NewLazyDLL("ole32.dll") + modiphlpapi = syscall.NewLazyDLL("iphlpapi.dll") modvmcompute = syscall.NewLazyDLL("vmcompute.dll") procCoTaskMemFree = modole32.NewProc("CoTaskMemFree") + procSetCurrentThreadCompartmentId = modiphlpapi.NewProc("SetCurrentThreadCompartmentId") procActivateLayer = modvmcompute.NewProc("ActivateLayer") procCopyLayer = modvmcompute.NewProc("CopyLayer") procCreateLayer = modvmcompute.NewProc("CreateLayer") @@ -82,6 +84,14 @@ func coTaskMemFree(buffer unsafe.Pointer) { return } +func SetCurrentThreadCompartmentId(compartmentId uint32) (hr error) { + r0, _, _ := syscall.Syscall(procSetCurrentThreadCompartmentId.Addr(), 1, uintptr(compartmentId), 0, 0) + if int32(r0) < 0 { + hr = syscall.Errno(win32FromHresult(r0)) + } + return +} + func activateLayer(info *driverInfo, id string) (hr error) { var _p0 *uint16 _p0, hr = syscall.UTF16PtrFromString(id) diff --git a/vendor/src/github.com/docker/libnetwork/agent.go b/vendor/src/github.com/docker/libnetwork/agent.go index 2b2ecf4324..837653e499 100644 --- a/vendor/src/github.com/docker/libnetwork/agent.go +++ b/vendor/src/github.com/docker/libnetwork/agent.go @@ -9,6 +9,7 @@ import ( "sort" "github.com/Sirupsen/logrus" + "github.com/docker/docker/pkg/stringid" "github.com/docker/go-events" "github.com/docker/libnetwork/datastore" "github.com/docker/libnetwork/discoverapi" @@ -247,9 +248,12 @@ func (c *controller) agentInit(bindAddrOrInterface, advertiseAddr string) error keys, tags := c.getKeys(subsysGossip) hostname, _ := os.Hostname() + nodeName := hostname + "-" + stringid.TruncateID(stringid.GenerateRandomID()) + logrus.Info("Gossip cluster hostname ", nodeName) + nDB, err := networkdb.New(&networkdb.Config{ AdvertiseAddr: advertiseAddr, - NodeName: hostname, + NodeName: nodeName, Keys: keys, }) @@ -464,8 +468,12 @@ func (n *network) addDriverWatches() { c := n.getController() for _, tableName := range n.driverTables { - ch, cancel := c.agent.networkDB.Watch(tableName, n.ID(), "") c.Lock() + if c.agent == nil { + c.Unlock() + return + } + ch, cancel := c.agent.networkDB.Watch(tableName, n.ID(), "") c.agent.driverCancelFuncs[n.ID()] = append(c.agent.driverCancelFuncs[n.ID()], cancel) c.Unlock() diff --git a/vendor/src/github.com/docker/libnetwork/controller.go b/vendor/src/github.com/docker/libnetwork/controller.go index c63535d1b8..a1906da322 100644 --- a/vendor/src/github.com/docker/libnetwork/controller.go +++ b/vendor/src/github.com/docker/libnetwork/controller.go @@ -753,9 +753,11 @@ func (c *controller) reservePools() { c.Gateway = n.ipamV4Info[i].Gateway.IP.String() } } - for i, c := range n.ipamV6Config { - if c.Gateway == "" && n.ipamV6Info[i].Gateway != nil { - c.Gateway = n.ipamV6Info[i].Gateway.IP.String() + if n.enableIPv6 { + for i, c := range n.ipamV6Config { + if c.Gateway == "" && n.ipamV6Info[i].Gateway != nil { + c.Gateway = n.ipamV6Info[i].Gateway.IP.String() + } } } // Reserve pools @@ -802,6 +804,8 @@ func (c *controller) addNetwork(n *network) error { return err } + n.startResolver() + return nil } @@ -920,6 +924,7 @@ func (c *controller) NewSandbox(containerID string, options ...SandboxOption) (s if sb.ingress { c.ingressSandbox = sb + sb.id = "ingress_sbox" } c.Unlock() defer func() { diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/encryption.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/encryption.go index 5b4800716b..fefb5da65c 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/overlay/encryption.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/encryption.go @@ -392,10 +392,11 @@ func (d *driver) secMapWalk(f func(string, []*spi) ([]*spi, bool)) error { } func (d *driver) setKeys(keys []*key) error { - if d.keys != nil { - return types.ForbiddenErrorf("initial keys are already present") - } + // Accept the encryption keys and clear any stale encryption map + d.Lock() d.keys = keys + d.secMap = &encrMap{nodes: map[string][]*spi{}} + d.Unlock() log.Debugf("Initial encryption keys: %v", d.keys) return nil } @@ -433,10 +434,8 @@ func (d *driver) updateKeys(newKey, primary, pruneKey *key) error { if (newKey != nil && newIdx == -1) || (primary != nil && priIdx == -1) || (pruneKey != nil && delIdx == -1) { - err := types.BadRequestErrorf("cannot find proper key indices while processing key update:"+ + return types.BadRequestErrorf("cannot find proper key indices while processing key update:"+ "(newIdx,priIdx,delIdx):(%d, %d, %d)", newIdx, priIdx, delIdx) - log.Warn(err) - return err } d.secMapWalk(func(rIPs string, spis []*spi) ([]*spi, bool) { diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go index 59877dd1ac..492f7f4254 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/overlay.go @@ -336,7 +336,9 @@ func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) } keys = append(keys, k) } - d.setKeys(keys) + if err := d.setKeys(keys); err != nil { + logrus.Warn(err) + } case discoverapi.EncryptionKeysUpdate: var newKey, delKey, priKey *key encrData, ok := data.(discoverapi.DriverEncryptionUpdate) @@ -361,7 +363,9 @@ func (d *driver) DiscoverNew(dType discoverapi.DiscoveryType, data interface{}) tag: uint32(encrData.PruneTag), } } - d.updateKeys(newKey, priKey, delKey) + if err := d.updateKeys(newKey, priKey, delKey); err != nil { + logrus.Warn(err) + } default: } return nil diff --git a/vendor/src/github.com/docker/libnetwork/drivers/overlay/peerdb.go b/vendor/src/github.com/docker/libnetwork/drivers/overlay/peerdb.go index c9808f692a..517909a816 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/overlay/peerdb.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/overlay/peerdb.go @@ -168,14 +168,14 @@ func (d *driver) peerDbAdd(nid, eid string, peerIP net.IP, peerIPMask net.IPMask } func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMask, - peerMac net.HardwareAddr, vtep net.IP) bool { + peerMac net.HardwareAddr, vtep net.IP) peerEntry { peerDbWg.Wait() d.peerDb.Lock() pMap, ok := d.peerDb.mp[nid] if !ok { d.peerDb.Unlock() - return false + return peerEntry{} } d.peerDb.Unlock() @@ -186,19 +186,20 @@ func (d *driver) peerDbDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPM pMap.Lock() - if pEntry, ok := pMap.mp[pKey.String()]; ok { + pEntry, ok := pMap.mp[pKey.String()] + if ok { // Mismatched endpoint ID(possibly outdated). Do not // delete peerdb if pEntry.eid != eid { pMap.Unlock() - return false + return pEntry } } delete(pMap.mp, pKey.String()) pMap.Unlock() - return true + return pEntry } func (d *driver) peerDbUpdateSandbox(nid string) { @@ -312,10 +313,9 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas return err } + var pEntry peerEntry if updateDb { - if !d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep) { - return nil - } + pEntry = d.peerDbDelete(nid, eid, peerIP, peerIPMask, peerMac, vtep) } n := d.network(nid) @@ -328,14 +328,24 @@ func (d *driver) peerDelete(nid, eid string, peerIP net.IP, peerIPMask net.IPMas return nil } - // Delete fdb entry to the bridge for the peer mac - if err := sbox.DeleteNeighbor(vtep, peerMac); err != nil { - return fmt.Errorf("could not delete fdb entry into the sandbox: %v", err) + // Delete fdb entry to the bridge for the peer mac only if the + // entry existed in local peerdb. If it is a stale delete + // request, still call DeleteNeighbor but only to cleanup any + // leftover sandbox neighbor cache and not actually delete the + // kernel state. + if (eid == pEntry.eid && vtep.Equal(pEntry.vtep)) || + (eid != pEntry.eid && !vtep.Equal(pEntry.vtep)) { + if err := sbox.DeleteNeighbor(vtep, peerMac, + eid == pEntry.eid && vtep.Equal(pEntry.vtep)); err != nil { + return fmt.Errorf("could not delete fdb entry into the sandbox: %v", err) + } } // Delete neighbor entry for the peer IP - if err := sbox.DeleteNeighbor(peerIP, peerMac); err != nil { - return fmt.Errorf("could not delete neighbor entry into the sandbox: %v", err) + if eid == pEntry.eid { + if err := sbox.DeleteNeighbor(peerIP, peerMac, true); err != nil { + return fmt.Errorf("could not delete neighbor entry into the sandbox: %v", err) + } } if err := d.checkEncryption(nid, vtep, 0, false, false); err != nil { diff --git a/vendor/src/github.com/docker/libnetwork/drivers/windows/labels.go b/vendor/src/github.com/docker/libnetwork/drivers/windows/labels.go index f1b77bf334..5740913c04 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/windows/labels.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/windows/labels.go @@ -15,4 +15,19 @@ const ( // QosPolicies of the endpoint QosPolicies = "com.docker.endpoint.windowsshim.qospolicies" + + // VLAN of the network + VLAN = "com.docker.network.windowsshim.vlanid" + + // VSID of the network + VSID = "com.docker.network.windowsshim.vsid" + + // DNSSuffix of the network + DNSSuffix = "com.docker.network.windowsshim.dnssuffix" + + // DNSServers of the network + DNSServers = "com.docker.network.windowsshim.dnsservers" + + // SourceMac of the network + SourceMac = "com.docker.network.windowsshim.sourcemac" ) diff --git a/vendor/src/github.com/docker/libnetwork/drivers/windows/windows.go b/vendor/src/github.com/docker/libnetwork/drivers/windows/windows.go index aa4c7e5808..ed6f7c2f26 100644 --- a/vendor/src/github.com/docker/libnetwork/drivers/windows/windows.go +++ b/vendor/src/github.com/docker/libnetwork/drivers/windows/windows.go @@ -15,6 +15,7 @@ import ( "encoding/json" "fmt" "net" + "strconv" "strings" "sync" @@ -34,6 +35,11 @@ type networkConfiguration struct { Name string HnsID string RDID string + VLAN uint + VSID uint + DNSServers string + DNSSuffix string + SourceMac string NetworkAdapterName string } @@ -43,6 +49,7 @@ type endpointConfiguration struct { PortBindings []types.PortBinding ExposedPorts []types.TransportPort QosPolicies []types.QosPolicy + DNSServers []string } type hnsEndpoint struct { @@ -69,7 +76,7 @@ type driver struct { } func isValidNetworkType(networkType string) bool { - if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "transparent" == networkType { + if "l2bridge" == networkType || "l2tunnel" == networkType || "nat" == networkType || "ics" == networkType || "transparent" == networkType { return true } @@ -129,6 +136,22 @@ func (d *driver) parseNetworkOptions(id string, genericOptions map[string]string config.RDID = value case Interface: config.NetworkAdapterName = value + case DNSSuffix: + config.DNSSuffix = value + case DNSServers: + config.DNSServers = value + case VLAN: + vlan, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return nil, err + } + config.VLAN = uint(vlan) + case VSID: + vsid, err := strconv.ParseUint(value, 10, 32) + if err != nil { + return nil, err + } + config.VSID = uint(vsid) } } @@ -207,9 +230,36 @@ func (d *driver) CreateNetwork(id string, option map[string]interface{}, nInfo d Name: config.Name, Type: d.name, Subnets: subnets, + DNSServerList: config.DNSServers, + DNSSuffix: config.DNSSuffix, + SourceMac: config.SourceMac, NetworkAdapterName: config.NetworkAdapterName, } + if config.VLAN != 0 { + vlanPolicy, err := json.Marshal(hcsshim.VlanPolicy{ + Type: "VLAN", + VLAN: config.VLAN, + }) + + if err != nil { + return err + } + network.Policies = append(network.Policies, vlanPolicy) + } + + if config.VSID != 0 { + vsidPolicy, err := json.Marshal(hcsshim.VsidPolicy{ + Type: "VSID", + VSID: config.VSID, + }) + + if err != nil { + return err + } + network.Policies = append(network.Policies, vsidPolicy) + } + if network.Name == "" { network.Name = id } @@ -379,6 +429,14 @@ func parseEndpointOptions(epOptions map[string]interface{}) (*endpointConfigurat } } + if opt, ok := epOptions[netlabel.DNSServers]; ok { + if dns, ok := opt.([]string); ok { + ec.DNSServers = dns + } else { + return nil, fmt.Errorf("Invalid endpoint configuration") + } + } + return ec, nil } @@ -421,6 +479,12 @@ func (d *driver) CreateEndpoint(nid, eid string, ifInfo driverapi.InterfaceInfo, endpointStruct.IPAddress = ifInfo.Address().IP } + endpointStruct.DNSServerList = strings.Join(ec.DNSServers, ",") + + if n.driver.name == "nat" { + endpointStruct.EnableInternalDNS = true + } + configurationb, err := json.Marshal(endpointStruct) if err != nil { return err @@ -502,6 +566,10 @@ func (d *driver) EndpointOperInfo(nid, eid string) (map[string]interface{}, erro } data := make(map[string]interface{}, 1) + if network.driver.name == "nat" { + data["AllowUnqualifiedDNSQuery"] = true + } + data["hnsid"] = ep.profileID if ep.config.ExposedPorts != nil { // Return a copy of the config data diff --git a/vendor/src/github.com/docker/libnetwork/endpoint.go b/vendor/src/github.com/docker/libnetwork/endpoint.go index 44893573ff..1c75b6fea5 100644 --- a/vendor/src/github.com/docker/libnetwork/endpoint.go +++ b/vendor/src/github.com/docker/libnetwork/endpoint.go @@ -883,6 +883,14 @@ func CreateOptionPortMapping(portBindings []types.PortBinding) EndpointOption { } } +// CreateOptionDNS function returns an option setter for dns entry option to +// be passed to container Create method. +func CreateOptionDNS(dns []string) EndpointOption { + return func(ep *endpoint) { + ep.generic[netlabel.DNSServers] = dns + } +} + // CreateOptionAnonymous function returns an option setter for setting // this endpoint as anonymous func CreateOptionAnonymous() EndpointOption { diff --git a/vendor/src/github.com/docker/libnetwork/netlabel/labels.go b/vendor/src/github.com/docker/libnetwork/netlabel/labels.go index 7d5c35579b..49ba3081d3 100644 --- a/vendor/src/github.com/docker/libnetwork/netlabel/labels.go +++ b/vendor/src/github.com/docker/libnetwork/netlabel/labels.go @@ -27,6 +27,9 @@ const ( // ExposedPorts constant represents the container's Exposed Ports ExposedPorts = Prefix + ".endpoint.exposedports" + // DNSServers A list of DNS servers associated with the endpoint + DNSServers = Prefix + ".endpoint.dnsservers" + //EnableIPv6 constant represents enabling IPV6 at network level EnableIPv6 = Prefix + ".enable_ipv6" diff --git a/vendor/src/github.com/docker/libnetwork/network.go b/vendor/src/github.com/docker/libnetwork/network.go index 2cd857a462..6b35bc628b 100644 --- a/vendor/src/github.com/docker/libnetwork/network.go +++ b/vendor/src/github.com/docker/libnetwork/network.go @@ -184,6 +184,8 @@ type network struct { persist bool stopWatchCh chan struct{} drvOnce *sync.Once + resolverOnce sync.Once + resolver []Resolver internal bool inDelete bool ingress bool @@ -803,6 +805,9 @@ func (n *network) deleteNetwork() error { } } + for _, resolver := range n.resolver { + resolver.Stop() + } return nil } @@ -1528,3 +1533,126 @@ func (n *network) TableEventRegister(tableName string) error { func (n *network) hasSpecialDriver() bool { return n.Type() == "host" || n.Type() == "null" } + +func (n *network) ResolveName(req string, ipType int) ([]net.IP, bool) { + var ipv6Miss bool + + c := n.getController() + c.Lock() + sr, ok := c.svcRecords[n.ID()] + c.Unlock() + + if !ok { + return nil, false + } + + req = strings.TrimSuffix(req, ".") + var ip []net.IP + n.Lock() + ip, ok = sr.svcMap[req] + + if ipType == types.IPv6 { + // 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[req] + } + n.Unlock() + + if ip != nil { + return ip, false + } + + return nil, ipv6Miss +} + +func (n *network) ResolveIP(ip string) string { + var svc string + + c := n.getController() + c.Lock() + sr, ok := c.svcRecords[n.ID()] + c.Unlock() + + if !ok { + return "" + } + + nwName := n.Name() + + n.Lock() + defer n.Unlock() + svc, ok = sr.ipMap[ip] + + if ok { + return svc + "." + nwName + } + + return svc +} + +func (n *network) ResolveService(name string) ([]*net.SRV, []net.IP) { + c := n.getController() + + srv := []*net.SRV{} + ip := []net.IP{} + + log.Debugf("Service name To resolve: %v", name) + + // There are DNS implementaions that allow SRV queries for names not in + // the format defined by RFC 2782. Hence specific validations checks are + // not done + parts := strings.Split(name, ".") + if len(parts) < 3 { + return nil, nil + } + + portName := parts[0] + proto := parts[1] + svcName := strings.Join(parts[2:], ".") + + c.Lock() + sr, ok := c.svcRecords[n.ID()] + c.Unlock() + + if !ok { + return nil, nil + } + + svcs, ok := sr.service[svcName] + if !ok { + return nil, nil + } + + for _, svc := range svcs { + if svc.portName != portName { + continue + } + if svc.proto != proto { + continue + } + for _, t := range svc.target { + srv = append(srv, + &net.SRV{ + Target: t.name, + Port: t.port, + }) + + ip = append(ip, t.ip) + } + } + + return srv, ip +} + +func (n *network) ExecFunc(f func()) error { + return types.NotImplementedErrorf("ExecFunc not supported by network") +} + +func (n *network) NdotsSet() bool { + return false +} diff --git a/vendor/src/github.com/docker/libnetwork/network_unix.go b/vendor/src/github.com/docker/libnetwork/network_unix.go new file mode 100644 index 0000000000..77b6e1ce97 --- /dev/null +++ b/vendor/src/github.com/docker/libnetwork/network_unix.go @@ -0,0 +1,8 @@ +// +build !windows + +package libnetwork + +// Stub implementations for DNS related functions + +func (n *network) startResolver() { +} diff --git a/vendor/src/github.com/docker/libnetwork/network_windows.go b/vendor/src/github.com/docker/libnetwork/network_windows.go new file mode 100644 index 0000000000..f529d5b799 --- /dev/null +++ b/vendor/src/github.com/docker/libnetwork/network_windows.go @@ -0,0 +1,52 @@ +// +build windows + +package libnetwork + +import ( + "runtime" + + "github.com/Microsoft/hcsshim" + log "github.com/Sirupsen/logrus" + "github.com/docker/libnetwork/drivers/windows" +) + +func executeInCompartment(compartmentID uint32, x func()) { + runtime.LockOSThread() + + if err := hcsshim.SetCurrentThreadCompartmentId(compartmentID); err != nil { + log.Error(err) + } + defer func() { + hcsshim.SetCurrentThreadCompartmentId(0) + runtime.UnlockOSThread() + }() + + x() +} + +func (n *network) startResolver() { + n.resolverOnce.Do(func() { + log.Debugf("Launching DNS server for network", n.Name()) + options := n.Info().DriverOptions() + hnsid := options[windows.HNSID] + + hnsresponse, err := hcsshim.HNSNetworkRequest("GET", hnsid, "") + if err != nil { + log.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err) + return + } + + for _, subnet := range hnsresponse.Subnets { + if subnet.GatewayAddress != "" { + resolver := NewResolver(subnet.GatewayAddress, false, "", n) + log.Debugf("Binding a resolver on network %s gateway %s", n.Name(), subnet.GatewayAddress) + executeInCompartment(hnsresponse.DNSServerCompartment, resolver.SetupFunc(53)) + if err = resolver.Start(); err != nil { + log.Errorf("Resolver Setup/Start failed for container %s, %q", n.Name(), err) + } else { + n.resolver = append(n.resolver, resolver) + } + } + } + }) +} diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/broadcast.go b/vendor/src/github.com/docker/libnetwork/networkdb/broadcast.go index 2e07729569..faaf642948 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/broadcast.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/broadcast.go @@ -1,10 +1,15 @@ package networkdb import ( + "fmt" + "time" + "github.com/hashicorp/memberlist" "github.com/hashicorp/serf/serf" ) +const broadcastTimeout = 5 * time.Second + type networkEventMessage struct { id string node string @@ -44,6 +49,53 @@ func (nDB *NetworkDB) sendNetworkEvent(nid string, event NetworkEvent_Type, ltim return nil } +type nodeEventMessage struct { + msg []byte + notify chan<- struct{} +} + +func (m *nodeEventMessage) Invalidates(other memberlist.Broadcast) bool { + return false +} + +func (m *nodeEventMessage) Message() []byte { + return m.msg +} + +func (m *nodeEventMessage) Finished() { + if m.notify != nil { + close(m.notify) + } +} + +func (nDB *NetworkDB) sendNodeEvent(event NodeEvent_Type) error { + nEvent := NodeEvent{ + Type: event, + LTime: nDB.networkClock.Increment(), + NodeName: nDB.config.NodeName, + } + + raw, err := encodeMessage(MessageTypeNodeEvent, &nEvent) + if err != nil { + return err + } + + notifyCh := make(chan struct{}) + nDB.nodeBroadcasts.QueueBroadcast(&nodeEventMessage{ + msg: raw, + notify: notifyCh, + }) + + // Wait for the broadcast + select { + case <-notifyCh: + case <-time.After(broadcastTimeout): + return fmt.Errorf("timed out broadcasting node event") + } + + return nil +} + type tableEventMessage struct { id string tname string diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/cluster.go b/vendor/src/github.com/docker/libnetwork/networkdb/cluster.go index 17563589dc..0a21cae5ae 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/cluster.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/cluster.go @@ -7,6 +7,7 @@ import ( "fmt" "math/big" rnd "math/rand" + "net" "strings" "time" @@ -14,7 +15,11 @@ import ( "github.com/hashicorp/memberlist" ) -const reapInterval = 30 * time.Second +const ( + reapInterval = 60 * time.Second + reapPeriod = 5 * time.Second + retryInterval = 1 * time.Second +) type logWriter struct{} @@ -111,6 +116,13 @@ func (nDB *NetworkDB) clusterInit() error { RetransmitMult: config.RetransmitMult, } + nDB.nodeBroadcasts = &memberlist.TransmitLimitedQueue{ + NumNodes: func() int { + return len(nDB.nodes) + }, + RetransmitMult: config.RetransmitMult, + } + mlist, err := memberlist.Create(config) if err != nil { return fmt.Errorf("failed to create memberlist: %v", err) @@ -124,9 +136,10 @@ func (nDB *NetworkDB) clusterInit() error { interval time.Duration fn func() }{ - {reapInterval, nDB.reapState}, + {reapPeriod, nDB.reapState}, {config.GossipInterval, nDB.gossip}, {config.PushPullInterval, nDB.bulkSyncTables}, + {retryInterval, nDB.reconnectNode}, } { t := time.NewTicker(trigger.interval) go nDB.triggerFunc(trigger.interval, t.C, nDB.stopCh, trigger.fn) @@ -136,19 +149,49 @@ func (nDB *NetworkDB) clusterInit() error { return nil } +func (nDB *NetworkDB) retryJoin(members []string, stop <-chan struct{}) { + t := time.NewTicker(retryInterval) + defer t.Stop() + + for { + select { + case <-t.C: + if _, err := nDB.memberlist.Join(members); err != nil { + logrus.Errorf("Failed to join memberlist %s on retry: %v", members, err) + continue + } + return + case <-stop: + return + } + } + +} + func (nDB *NetworkDB) clusterJoin(members []string) error { mlist := nDB.memberlist if _, err := mlist.Join(members); err != nil { + // Incase of failure, keep retrying join until it succeeds or the cluster is shutdown. + go nDB.retryJoin(members, nDB.stopCh) + return fmt.Errorf("could not join node to memberlist: %v", err) } + if err := nDB.sendNodeEvent(NodeEventTypeJoin); err != nil { + return fmt.Errorf("failed to send node join: %v", err) + } + return nil } func (nDB *NetworkDB) clusterLeave() error { mlist := nDB.memberlist + if err := nDB.sendNodeEvent(NodeEventTypeLeave); err != nil { + return fmt.Errorf("failed to send node leave: %v", err) + } + if err := mlist.Leave(time.Second); err != nil { return err } @@ -180,6 +223,42 @@ func (nDB *NetworkDB) triggerFunc(stagger time.Duration, C <-chan time.Time, sto } } +func (nDB *NetworkDB) reconnectNode() { + nDB.RLock() + if len(nDB.failedNodes) == 0 { + nDB.RUnlock() + return + } + + nodes := make([]*node, 0, len(nDB.failedNodes)) + for _, n := range nDB.failedNodes { + nodes = append(nodes, n) + } + nDB.RUnlock() + + // Update all the local state to a new time to force update on + // the node we are trying to rejoin, just in case that node + // has these in leaving/deleting state still. This is + // facilitate fast convergence after recovering from a gossip + // failure. + nDB.updateLocalStateTime() + + node := nodes[randomOffset(len(nodes))] + addr := net.UDPAddr{IP: node.Addr, Port: int(node.Port)} + + if _, err := nDB.memberlist.Join([]string{addr.String()}); err != nil { + return + } + + if err := nDB.sendNodeEvent(NodeEventTypeJoin); err != nil { + logrus.Errorf("failed to send node join during reconnect: %v", err) + return + } + + logrus.Debugf("Initiating bulk sync with node %s after reconnect", node.Name) + nDB.bulkSync([]string{node.Name}, true) +} + func (nDB *NetworkDB) reapState() { nDB.reapNetworks() nDB.reapTableEntries() @@ -288,7 +367,7 @@ func (nDB *NetworkDB) gossip() { } // Send the compound message - if err := nDB.memberlist.SendToUDP(mnode, compound); err != nil { + if err := nDB.memberlist.SendToUDP(&mnode.Node, compound); err != nil { logrus.Errorf("Failed to send gossip to %s: %s", mnode.Addr, err) } } @@ -323,7 +402,7 @@ func (nDB *NetworkDB) bulkSyncTables() { continue } - completed, err := nDB.bulkSync(nid, nodes, false) + completed, err := nDB.bulkSync(nodes, false) if err != nil { logrus.Errorf("periodic bulk sync failure for network %s: %v", nid, err) continue @@ -350,7 +429,7 @@ func (nDB *NetworkDB) bulkSyncTables() { } } -func (nDB *NetworkDB) bulkSync(nid string, nodes []string, all bool) ([]string, error) { +func (nDB *NetworkDB) bulkSync(nodes []string, all bool) ([]string, error) { if !all { // If not all, then just pick one. nodes = nDB.mRandomNodes(1, nodes) @@ -388,7 +467,12 @@ func (nDB *NetworkDB) bulkSync(nid string, nodes []string, all bool) ([]string, func (nDB *NetworkDB) bulkSyncNode(networks []string, node string, unsolicited bool) error { var msgs [][]byte - logrus.Debugf("%s: Initiating bulk sync for networks %v with node %s", nDB.config.NodeName, networks, node) + var unsolMsg string + if unsolicited { + unsolMsg = "unsolicited" + } + + logrus.Debugf("%s: Initiating %s bulk sync for networks %v with node %s", nDB.config.NodeName, unsolMsg, networks, node) nDB.RLock() mnode := nDB.nodes[node] @@ -404,15 +488,14 @@ func (nDB *NetworkDB) bulkSyncNode(networks []string, node string, unsolicited b return false } - // Do not bulk sync state which is in the - // process of getting deleted. + eType := TableEventTypeCreate if entry.deleting { - return false + eType = TableEventTypeDelete } params := strings.Split(path[1:], "/") tEvent := TableEvent{ - Type: TableEventTypeCreate, + Type: eType, LTime: entry.ltime, NodeName: entry.node, NetworkID: nid, @@ -454,7 +537,7 @@ func (nDB *NetworkDB) bulkSyncNode(networks []string, node string, unsolicited b nDB.bulkSyncAckTbl[node] = ch nDB.Unlock() - err = nDB.memberlist.SendToTCP(mnode, buf) + err = nDB.memberlist.SendToTCP(&mnode.Node, buf) if err != nil { nDB.Lock() delete(nDB.bulkSyncAckTbl, node) diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/delegate.go b/vendor/src/github.com/docker/libnetwork/networkdb/delegate.go index 35c126a847..3e96384465 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/delegate.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/delegate.go @@ -17,6 +17,56 @@ func (d *delegate) NodeMeta(limit int) []byte { return []byte{} } +func (nDB *NetworkDB) checkAndGetNode(nEvent *NodeEvent) *node { + nDB.Lock() + defer nDB.Unlock() + + for _, nodes := range []map[string]*node{ + nDB.failedNodes, + nDB.leftNodes, + nDB.nodes, + } { + if n, ok := nodes[nEvent.NodeName]; ok { + if n.ltime >= nEvent.LTime { + return nil + } + + delete(nDB.failedNodes, n.Name) + return n + } + } + + return nil +} + +func (nDB *NetworkDB) handleNodeEvent(nEvent *NodeEvent) bool { + // Update our local clock if the received messages has newer + // time. + nDB.networkClock.Witness(nEvent.LTime) + + n := nDB.checkAndGetNode(nEvent) + if n == nil { + return false + } + + n.ltime = nEvent.LTime + + switch nEvent.Type { + case NodeEventTypeJoin: + nDB.Lock() + nDB.nodes[n.Name] = n + nDB.Unlock() + return true + case NodeEventTypeLeave: + nDB.Lock() + nDB.leftNodes[n.Name] = n + nDB.Unlock() + return true + } + + return false +} + func (nDB *NetworkDB) handleNetworkEvent(nEvent *NetworkEvent) bool { // Update our local clock if the received messages has newer // time. @@ -188,6 +238,27 @@ func (nDB *NetworkDB) handleTableMessage(buf []byte, isBulkSync bool) { } } +func (nDB *NetworkDB) handleNodeMessage(buf []byte) { + var nEvent NodeEvent + if err := proto.Unmarshal(buf, &nEvent); err != nil { + logrus.Errorf("Error decoding node event message: %v", err) + return + } + + if rebroadcast := nDB.handleNodeEvent(&nEvent); rebroadcast { + var err error + buf, err = encodeRawMessage(MessageTypeNodeEvent, buf) + if err != nil { + logrus.Errorf("Error marshalling gossip message for node event rebroadcast: %v", err) + return + } + + nDB.nodeBroadcasts.QueueBroadcast(&nodeEventMessage{ + msg: buf, + }) + } +} + func (nDB *NetworkDB) handleNetworkMessage(buf []byte) { var nEvent NetworkEvent if err := proto.Unmarshal(buf, &nEvent); err != nil { @@ -256,6 +327,8 @@ func (nDB *NetworkDB) handleMessage(buf []byte, isBulkSync bool) { } switch mType { + case MessageTypeNodeEvent: + nDB.handleNodeMessage(data) case MessageTypeNetworkEvent: nDB.handleNetworkMessage(data) case MessageTypeTableEvent: @@ -278,7 +351,9 @@ func (d *delegate) NotifyMsg(buf []byte) { } func (d *delegate) GetBroadcasts(overhead, limit int) [][]byte { - return d.nDB.networkBroadcasts.GetBroadcasts(overhead, limit) + msgs := d.nDB.networkBroadcasts.GetBroadcasts(overhead, limit) + msgs = append(msgs, d.nDB.nodeBroadcasts.GetBroadcasts(overhead, limit)...) + return msgs } func (d *delegate) LocalState(join bool) []byte { @@ -286,7 +361,8 @@ func (d *delegate) LocalState(join bool) []byte { defer d.nDB.RUnlock() pp := NetworkPushPull{ - LTime: d.nDB.networkClock.Time(), + LTime: d.nDB.networkClock.Time(), + NodeName: d.nDB.config.NodeName, } for name, nn := range d.nDB.networks { @@ -336,6 +412,13 @@ func (d *delegate) MergeRemoteState(buf []byte, isJoin bool) { d.nDB.networkClock.Witness(pp.LTime) } + nodeEvent := &NodeEvent{ + LTime: pp.LTime, + NodeName: pp.NodeName, + Type: NodeEventTypeJoin, + } + d.nDB.handleNodeEvent(nodeEvent) + for _, n := range pp.Networks { nEvent := &NetworkEvent{ LTime: n.LTime, diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/event_delegate.go b/vendor/src/github.com/docker/libnetwork/networkdb/event_delegate.go index 7dfea84f6e..019cafbd06 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/event_delegate.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/event_delegate.go @@ -6,17 +6,31 @@ type eventDelegate struct { nDB *NetworkDB } -func (e *eventDelegate) NotifyJoin(n *memberlist.Node) { +func (e *eventDelegate) NotifyJoin(mn *memberlist.Node) { e.nDB.Lock() - e.nDB.nodes[n.Name] = n + // In case the node is rejoining after a failure or leave, + // wait until an explicit join message arrives before adding + // it to the nodes just to make sure this is not a stale + // join. If you don't know about this node add it immediately. + _, fOk := e.nDB.failedNodes[mn.Name] + _, lOk := e.nDB.leftNodes[mn.Name] + if fOk || lOk { + e.nDB.Unlock() + return + } + + e.nDB.nodes[mn.Name] = &node{Node: *mn} e.nDB.Unlock() } -func (e *eventDelegate) NotifyLeave(n *memberlist.Node) { - e.nDB.deleteNodeTableEntries(n.Name) - e.nDB.deleteNetworkNodeEntries(n.Name) +func (e *eventDelegate) NotifyLeave(mn *memberlist.Node) { + e.nDB.deleteNodeTableEntries(mn.Name) + e.nDB.deleteNetworkEntriesForNode(mn.Name) e.nDB.Lock() - delete(e.nDB.nodes, n.Name) + if n, ok := e.nDB.nodes[mn.Name]; ok { + delete(e.nDB.nodes, mn.Name) + e.nDB.failedNodes[mn.Name] = n + } e.nDB.Unlock() } diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go index 2f35be6ffa..c452a90835 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.go @@ -41,7 +41,13 @@ type NetworkDB struct { // List of all peer nodes in the cluster not-limited to any // network. - nodes map[string]*memberlist.Node + nodes map[string]*node + + // List of all peer nodes which have failed + failedNodes map[string]*node + + // List of all peer nodes which have left + leftNodes map[string]*node // A multi-dimensional map of network/node attachmemts. The // first key is a node name and the second key is a network ID @@ -66,6 +72,9 @@ type NetworkDB struct { // Broadcast queue for network event gossip. networkBroadcasts *memberlist.TransmitLimitedQueue + // Broadcast queue for node event gossip. + nodeBroadcasts *memberlist.TransmitLimitedQueue + // A central stop channel to stop all go routines running on // behalf of the NetworkDB instance. stopCh chan struct{} @@ -82,6 +91,11 @@ type NetworkDB struct { keyring *memberlist.Keyring } +type node struct { + memberlist.Node + ltime serf.LamportTime +} + // network describes the node/network attachment. type network struct { // Network ID @@ -146,7 +160,9 @@ func New(c *Config) (*NetworkDB, error) { config: c, indexes: make(map[int]*radix.Tree), networks: make(map[string]map[string]*network), - nodes: make(map[string]*memberlist.Node), + nodes: make(map[string]*node), + failedNodes: make(map[string]*node), + leftNodes: make(map[string]*node), networkNodes: make(map[string][]string), bulkSyncAckTbl: make(map[string]chan struct{}), broadcaster: events.NewBroadcaster(), @@ -286,7 +302,7 @@ func (nDB *NetworkDB) DeleteEntry(tname, nid, key string) error { return nil } -func (nDB *NetworkDB) deleteNetworkNodeEntries(deletedNode string) { +func (nDB *NetworkDB) deleteNetworkEntriesForNode(deletedNode string) { nDB.Lock() for nid, nodes := range nDB.networkNodes { updatedNodes := make([]string, 0, len(nodes)) @@ -300,6 +316,8 @@ func (nDB *NetworkDB) deleteNetworkNodeEntries(deletedNode string) { nDB.networkNodes[nid] = updatedNodes } + + delete(nDB.networks, deletedNode) nDB.Unlock() } @@ -389,7 +407,7 @@ func (nDB *NetworkDB) JoinNetwork(nid string) error { } logrus.Debugf("%s: joined network %s", nDB.config.NodeName, nid) - if _, err := nDB.bulkSync(nid, networkNodes, true); err != nil { + if _, err := nDB.bulkSync(networkNodes, true); err != nil { logrus.Errorf("Error bulk syncing while joining network %s: %v", nid, err) } @@ -492,10 +510,41 @@ func (nDB *NetworkDB) findCommonNetworks(nodeName string) []string { var networks []string for nid := range nDB.networks[nDB.config.NodeName] { - if _, ok := nDB.networks[nodeName][nid]; ok { - networks = append(networks, nid) + if n, ok := nDB.networks[nodeName][nid]; ok { + if !n.leaving { + networks = append(networks, nid) + } } } return networks } + +func (nDB *NetworkDB) updateLocalStateTime() { + nDB.Lock() + defer nDB.Unlock() + + ltime := nDB.networkClock.Increment() + for _, n := range nDB.networks[nDB.config.NodeName] { + n.ltime = ltime + } + + ltime = nDB.tableClock.Increment() + nDB.indexes[byTable].Walk(func(path string, v interface{}) bool { + entry := v.(*entry) + if entry.node != nDB.config.NodeName { + return false + } + + params := strings.Split(path[1:], "/") + tname := params[0] + nid := params[1] + key := params[2] + entry.ltime = ltime + + nDB.indexes[byTable].Insert(fmt.Sprintf("/%s/%s/%s", tname, nid, key), entry) + nDB.indexes[byNetwork].Insert(fmt.Sprintf("/%s/%s/%s", nid, tname, key), entry) + + return false + }) +} diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.pb.go b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.pb.go index 86177cf315..dfbc7131fb 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.pb.go +++ b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.pb.go @@ -10,6 +10,7 @@ It has these top-level messages: GossipMessage + NodeEvent NetworkEvent NetworkEntry NetworkPushPull @@ -67,6 +68,9 @@ const ( // which is a pack of many message of above types, packed into // a single compound message. MessageTypeCompound MessageType = 5 + // NodeEvent message type is used to communicare node + // join/leave events in the cluster + MessageTypeNodeEvent MessageType = 6 ) var MessageType_name = map[int32]string{ @@ -76,6 +80,7 @@ var MessageType_name = map[int32]string{ 3: "PUSH_PULL", 4: "BULK_SYNC", 5: "COMPOUND", + 6: "NODE_EVENT", } var MessageType_value = map[string]int32{ "INVALID": 0, @@ -84,6 +89,7 @@ var MessageType_value = map[string]int32{ "PUSH_PULL": 3, "BULK_SYNC": 4, "COMPOUND": 5, + "NODE_EVENT": 6, } func (x MessageType) String() string { @@ -91,6 +97,32 @@ func (x MessageType) String() string { } func (MessageType) EnumDescriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{0} } +type NodeEvent_Type int32 + +const ( + NodeEventTypeInvalid NodeEvent_Type = 0 + // Join event is generated when this node joins the cluster. + NodeEventTypeJoin NodeEvent_Type = 1 + // Leave event is generated when this node leaves the cluster. + NodeEventTypeLeave NodeEvent_Type = 2 +) + +var NodeEvent_Type_name = map[int32]string{ + 0: "INVALID", + 1: "JOIN", + 2: "LEAVE", +} +var NodeEvent_Type_value = map[string]int32{ + "INVALID": 0, + "JOIN": 1, + "LEAVE": 2, +} + +func (x NodeEvent_Type) String() string { + return proto.EnumName(NodeEvent_Type_name, int32(x)) +} +func (NodeEvent_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{1, 0} } + type NetworkEvent_Type int32 const ( @@ -115,7 +147,7 @@ var NetworkEvent_Type_value = map[string]int32{ func (x NetworkEvent_Type) String() string { return proto.EnumName(NetworkEvent_Type_name, int32(x)) } -func (NetworkEvent_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{1, 0} } +func (NetworkEvent_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{2, 0} } type TableEvent_Type int32 @@ -148,7 +180,7 @@ var TableEvent_Type_value = map[string]int32{ func (x TableEvent_Type) String() string { return proto.EnumName(TableEvent_Type_name, int32(x)) } -func (TableEvent_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{4, 0} } +func (TableEvent_Type) EnumDescriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{5, 0} } // GossipMessage is a basic message header used by all messages types. type GossipMessage struct { @@ -160,6 +192,21 @@ func (m *GossipMessage) Reset() { *m = GossipMessage{} } func (*GossipMessage) ProtoMessage() {} func (*GossipMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{0} } +// NodeEvent message payload definition. +type NodeEvent struct { + Type NodeEvent_Type `protobuf:"varint,1,opt,name=type,proto3,enum=networkdb.NodeEvent_Type" json:"type,omitempty"` + // Lamport time using a network lamport clock indicating the + // time this event was generated on the node where it was + // generated. + LTime github_com_hashicorp_serf_serf.LamportTime `protobuf:"varint,2,opt,name=l_time,json=lTime,proto3,customtype=github.com/hashicorp/serf/serf.LamportTime" json:"l_time"` + // Source node name. + NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` +} + +func (m *NodeEvent) Reset() { *m = NodeEvent{} } +func (*NodeEvent) ProtoMessage() {} +func (*NodeEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{1} } + // NetworkEvent message payload definition. type NetworkEvent struct { Type NetworkEvent_Type `protobuf:"varint,1,opt,name=type,proto3,enum=networkdb.NetworkEvent_Type" json:"type,omitempty"` @@ -175,7 +222,7 @@ type NetworkEvent struct { func (m *NetworkEvent) Reset() { *m = NetworkEvent{} } func (*NetworkEvent) ProtoMessage() {} -func (*NetworkEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{1} } +func (*NetworkEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{2} } // NetworkEntry for push pull of networks. type NetworkEntry struct { @@ -192,18 +239,20 @@ type NetworkEntry struct { func (m *NetworkEntry) Reset() { *m = NetworkEntry{} } func (*NetworkEntry) ProtoMessage() {} -func (*NetworkEntry) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{2} } +func (*NetworkEntry) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{3} } // NetworkPushpull message payload definition. type NetworkPushPull struct { // Lamport time when this push pull was initiated. LTime github_com_hashicorp_serf_serf.LamportTime `protobuf:"varint,1,opt,name=l_time,json=lTime,proto3,customtype=github.com/hashicorp/serf/serf.LamportTime" json:"l_time"` Networks []*NetworkEntry `protobuf:"bytes,2,rep,name=networks" json:"networks,omitempty"` + // Name of the node sending this push pull payload. + NodeName string `protobuf:"bytes,3,opt,name=node_name,json=nodeName,proto3" json:"node_name,omitempty"` } func (m *NetworkPushPull) Reset() { *m = NetworkPushPull{} } func (*NetworkPushPull) ProtoMessage() {} -func (*NetworkPushPull) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{3} } +func (*NetworkPushPull) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{4} } func (m *NetworkPushPull) GetNetworks() []*NetworkEntry { if m != nil { @@ -231,7 +280,7 @@ type TableEvent struct { func (m *TableEvent) Reset() { *m = TableEvent{} } func (*TableEvent) ProtoMessage() {} -func (*TableEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{4} } +func (*TableEvent) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{5} } // BulkSync message payload definition. type BulkSyncMessage struct { @@ -251,7 +300,7 @@ type BulkSyncMessage struct { func (m *BulkSyncMessage) Reset() { *m = BulkSyncMessage{} } func (*BulkSyncMessage) ProtoMessage() {} -func (*BulkSyncMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{5} } +func (*BulkSyncMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{6} } // Compound message payload definition. type CompoundMessage struct { @@ -261,7 +310,7 @@ type CompoundMessage struct { func (m *CompoundMessage) Reset() { *m = CompoundMessage{} } func (*CompoundMessage) ProtoMessage() {} -func (*CompoundMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{6} } +func (*CompoundMessage) Descriptor() ([]byte, []int) { return fileDescriptorNetworkdb, []int{7} } func (m *CompoundMessage) GetMessages() []*CompoundMessage_SimpleMessage { if m != nil { @@ -279,11 +328,12 @@ type CompoundMessage_SimpleMessage struct { func (m *CompoundMessage_SimpleMessage) Reset() { *m = CompoundMessage_SimpleMessage{} } func (*CompoundMessage_SimpleMessage) ProtoMessage() {} func (*CompoundMessage_SimpleMessage) Descriptor() ([]byte, []int) { - return fileDescriptorNetworkdb, []int{6, 0} + return fileDescriptorNetworkdb, []int{7, 0} } func init() { proto.RegisterType((*GossipMessage)(nil), "networkdb.GossipMessage") + proto.RegisterType((*NodeEvent)(nil), "networkdb.NodeEvent") proto.RegisterType((*NetworkEvent)(nil), "networkdb.NetworkEvent") proto.RegisterType((*NetworkEntry)(nil), "networkdb.NetworkEntry") proto.RegisterType((*NetworkPushPull)(nil), "networkdb.NetworkPushPull") @@ -292,6 +342,7 @@ func init() { proto.RegisterType((*CompoundMessage)(nil), "networkdb.CompoundMessage") proto.RegisterType((*CompoundMessage_SimpleMessage)(nil), "networkdb.CompoundMessage.SimpleMessage") proto.RegisterEnum("networkdb.MessageType", MessageType_name, MessageType_value) + proto.RegisterEnum("networkdb.NodeEvent_Type", NodeEvent_Type_name, NodeEvent_Type_value) proto.RegisterEnum("networkdb.NetworkEvent_Type", NetworkEvent_Type_name, NetworkEvent_Type_value) proto.RegisterEnum("networkdb.TableEvent_Type", TableEvent_Type_name, TableEvent_Type_value) } @@ -306,6 +357,18 @@ func (this *GossipMessage) GoString() string { s = append(s, "}") return strings.Join(s, "") } +func (this *NodeEvent) GoString() string { + if this == nil { + return "nil" + } + s := make([]string, 0, 7) + s = append(s, "&networkdb.NodeEvent{") + s = append(s, "Type: "+fmt.Sprintf("%#v", this.Type)+",\n") + s = append(s, "LTime: "+fmt.Sprintf("%#v", this.LTime)+",\n") + s = append(s, "NodeName: "+fmt.Sprintf("%#v", this.NodeName)+",\n") + s = append(s, "}") + return strings.Join(s, "") +} func (this *NetworkEvent) GoString() string { if this == nil { return "nil" @@ -336,12 +399,13 @@ func (this *NetworkPushPull) GoString() string { if this == nil { return "nil" } - s := make([]string, 0, 6) + s := make([]string, 0, 7) s = append(s, "&networkdb.NetworkPushPull{") s = append(s, "LTime: "+fmt.Sprintf("%#v", this.LTime)+",\n") if this.Networks != nil { s = append(s, "Networks: "+fmt.Sprintf("%#v", this.Networks)+",\n") } + s = append(s, "NodeName: "+fmt.Sprintf("%#v", this.NodeName)+",\n") s = append(s, "}") return strings.Join(s, "") } @@ -451,6 +515,40 @@ func (m *GossipMessage) MarshalTo(data []byte) (int, error) { return i, nil } +func (m *NodeEvent) Marshal() (data []byte, err error) { + size := m.Size() + data = make([]byte, size) + n, err := m.MarshalTo(data) + if err != nil { + return nil, err + } + return data[:n], nil +} + +func (m *NodeEvent) MarshalTo(data []byte) (int, error) { + var i int + _ = i + var l int + _ = l + if m.Type != 0 { + data[i] = 0x8 + i++ + i = encodeVarintNetworkdb(data, i, uint64(m.Type)) + } + if m.LTime != 0 { + data[i] = 0x10 + i++ + i = encodeVarintNetworkdb(data, i, uint64(m.LTime)) + } + if len(m.NodeName) > 0 { + data[i] = 0x1a + i++ + i = encodeVarintNetworkdb(data, i, uint64(len(m.NodeName))) + i += copy(data[i:], m.NodeName) + } + return i, nil +} + func (m *NetworkEvent) Marshal() (data []byte, err error) { size := m.Size() data = make([]byte, size) @@ -568,6 +666,12 @@ func (m *NetworkPushPull) MarshalTo(data []byte) (int, error) { i += n } } + if len(m.NodeName) > 0 { + data[i] = 0x1a + i++ + i = encodeVarintNetworkdb(data, i, uint64(len(m.NodeName))) + i += copy(data[i:], m.NodeName) + } return i, nil } @@ -783,6 +887,22 @@ func (m *GossipMessage) Size() (n int) { return n } +func (m *NodeEvent) Size() (n int) { + var l int + _ = l + if m.Type != 0 { + n += 1 + sovNetworkdb(uint64(m.Type)) + } + if m.LTime != 0 { + n += 1 + sovNetworkdb(uint64(m.LTime)) + } + l = len(m.NodeName) + if l > 0 { + n += 1 + l + sovNetworkdb(uint64(l)) + } + return n +} + func (m *NetworkEvent) Size() (n int) { var l int _ = l @@ -835,6 +955,10 @@ func (m *NetworkPushPull) Size() (n int) { n += 1 + l + sovNetworkdb(uint64(l)) } } + l = len(m.NodeName) + if l > 0 { + n += 1 + l + sovNetworkdb(uint64(l)) + } return n } @@ -942,6 +1066,18 @@ func (this *GossipMessage) String() string { }, "") return s } +func (this *NodeEvent) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&NodeEvent{`, + `Type:` + fmt.Sprintf("%v", this.Type) + `,`, + `LTime:` + fmt.Sprintf("%v", this.LTime) + `,`, + `NodeName:` + fmt.Sprintf("%v", this.NodeName) + `,`, + `}`, + }, "") + return s +} func (this *NetworkEvent) String() string { if this == nil { return "nil" @@ -975,6 +1111,7 @@ func (this *NetworkPushPull) String() string { s := strings.Join([]string{`&NetworkPushPull{`, `LTime:` + fmt.Sprintf("%v", this.LTime) + `,`, `Networks:` + strings.Replace(fmt.Sprintf("%v", this.Networks), "NetworkEntry", "NetworkEntry", 1) + `,`, + `NodeName:` + fmt.Sprintf("%v", this.NodeName) + `,`, `}`, }, "") return s @@ -1137,6 +1274,123 @@ func (m *GossipMessage) Unmarshal(data []byte) error { } return nil } +func (m *NodeEvent) Unmarshal(data []byte) error { + l := len(data) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNetworkdb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: NodeEvent: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: NodeEvent: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Type", wireType) + } + m.Type = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNetworkdb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.Type |= (NodeEvent_Type(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field LTime", wireType) + } + m.LTime = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNetworkdb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + m.LTime |= (github_com_hashicorp_serf_serf.LamportTime(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNetworkdb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthNetworkdb + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeName = string(data[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipNetworkdb(data[iNdEx:]) + if err != nil { + return err + } + if skippy < 0 { + return ErrInvalidLengthNetworkdb + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *NetworkEvent) Unmarshal(data []byte) error { l := len(data) iNdEx := 0 @@ -1509,6 +1763,35 @@ func (m *NetworkPushPull) Unmarshal(data []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field NodeName", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowNetworkdb + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := data[iNdEx] + iNdEx++ + stringLen |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthNetworkdb + } + postIndex := iNdEx + intStringLen + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.NodeName = string(data[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipNetworkdb(data[iNdEx:]) @@ -2211,56 +2494,61 @@ var ( ) var fileDescriptorNetworkdb = []byte{ - // 812 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x95, 0x4d, 0x6f, 0xe2, 0x46, - 0x18, 0xc7, 0x31, 0x18, 0x02, 0x0f, 0xd0, 0x20, 0x27, 0x4d, 0x5c, 0xa7, 0x25, 0x91, 0x9b, 0x46, - 0x14, 0x55, 0x4e, 0x95, 0x7c, 0x02, 0x5e, 0xac, 0x96, 0xc4, 0x31, 0xc8, 0x40, 0xaa, 0x9e, 0x90, - 0xc1, 0x53, 0xb0, 0x62, 0x6c, 0x0b, 0x9b, 0x54, 0xdc, 0xaa, 0x9e, 0xa2, 0xde, 0x7a, 0xad, 0xd4, - 0x53, 0x7b, 0xee, 0x07, 0xe8, 0xa1, 0xe7, 0xa8, 0xa7, 0xf6, 0xb6, 0xda, 0x43, 0xb4, 0xc9, 0x27, - 0xd8, 0x8f, 0xb0, 0xe3, 0xc1, 0x86, 0x81, 0x44, 0xb9, 0xec, 0x6a, 0xb5, 0x07, 0xc3, 0xbc, 0xfc, - 0xe6, 0xd1, 0xff, 0x79, 0xe6, 0x3f, 0x33, 0xb0, 0x69, 0x23, 0xff, 0x47, 0x67, 0x72, 0x65, 0xf4, - 0x25, 0x77, 0xe2, 0xf8, 0x0e, 0x97, 0x59, 0x0c, 0x08, 0xdb, 0x43, 0x67, 0xe8, 0x90, 0xd1, 0xe3, - 0xa0, 0x35, 0x07, 0xc4, 0x26, 0xe4, 0xbf, 0x71, 0x3c, 0xcf, 0x74, 0x2f, 0x90, 0xe7, 0xe9, 0x43, - 0xc4, 0x95, 0x81, 0xf5, 0x67, 0x2e, 0xe2, 0x99, 0x03, 0xa6, 0xf4, 0xd1, 0xc9, 0x8e, 0xb4, 0x8c, - 0x18, 0x12, 0x1d, 0x3c, 0xab, 0x11, 0x86, 0xe3, 0x80, 0x35, 0x74, 0x5f, 0xe7, 0xe3, 0x98, 0xcd, - 0x69, 0xa4, 0x2d, 0xde, 0xc7, 0x21, 0xa7, 0xce, 0xd7, 0xc8, 0xd7, 0xc8, 0xf6, 0xb9, 0xaf, 0x57, - 0x02, 0x7e, 0x4a, 0x05, 0xa4, 0x31, 0x89, 0x0a, 0xdb, 0x80, 0x94, 0xd5, 0xf3, 0xcd, 0x31, 0x22, - 0x81, 0xd9, 0xea, 0xc9, 0xed, 0xdd, 0x7e, 0xec, 0xe5, 0xdd, 0x7e, 0x79, 0x68, 0xfa, 0xa3, 0x69, - 0x5f, 0x1a, 0x38, 0xe3, 0xe3, 0x91, 0xee, 0x8d, 0xcc, 0x81, 0x33, 0x71, 0x8f, 0x3d, 0x34, 0xf9, - 0x81, 0xfc, 0x48, 0x8a, 0x3e, 0x76, 0x9d, 0x89, 0xdf, 0xc1, 0x2b, 0xb5, 0xa4, 0x15, 0xfc, 0x71, - 0x7b, 0x90, 0xb1, 0x1d, 0x03, 0xf5, 0x6c, 0x1d, 0x47, 0x4b, 0xe0, 0x68, 0x19, 0x2d, 0x1d, 0x0c, - 0xa8, 0xb8, 0xcf, 0x7d, 0x05, 0x10, 0x8a, 0xe9, 0x99, 0x06, 0xcf, 0x06, 0xb3, 0xd5, 0xfc, 0xc3, - 0xdd, 0x7e, 0x26, 0x14, 0xd6, 0xa8, 0x6b, 0x51, 0xfd, 0x1a, 0x86, 0x78, 0xc3, 0x00, 0x1b, 0x88, - 0xe4, 0x4a, 0xb0, 0xd1, 0x50, 0x2f, 0x2b, 0x4a, 0xa3, 0x5e, 0x88, 0x09, 0x7b, 0xbf, 0xfc, 0x7e, - 0xb0, 0x4b, 0x27, 0x12, 0x20, 0x0d, 0xfb, 0x5a, 0xb7, 0x4c, 0x83, 0x13, 0x81, 0x3d, 0x6b, 0x36, - 0xd4, 0x02, 0x23, 0xf0, 0x18, 0xdb, 0x5e, 0xc7, 0xce, 0x1c, 0xd3, 0xe6, 0x0e, 0x21, 0xa9, 0xc8, - 0x95, 0x4b, 0xb9, 0x10, 0x17, 0x3e, 0xc1, 0xd0, 0xc7, 0xeb, 0x90, 0x82, 0xf4, 0x6b, 0x24, 0xe4, - 0x6e, 0xfe, 0x28, 0xc6, 0xfe, 0xfe, 0xb3, 0x48, 0x14, 0x88, 0xff, 0x30, 0xcb, 0x1a, 0xdb, 0xfe, - 0x64, 0xb6, 0x96, 0x09, 0xf3, 0x7c, 0x26, 0xef, 0xad, 0xbe, 0x3c, 0x6c, 0x58, 0x58, 0xbd, 0x69, - 0x0f, 0x49, 0x71, 0xd3, 0x5a, 0xd4, 0x15, 0x7f, 0x65, 0x60, 0x33, 0x94, 0xd6, 0x9a, 0x7a, 0xa3, - 0xd6, 0xd4, 0xb2, 0x28, 0x55, 0xcc, 0xdb, 0xaa, 0x3a, 0x85, 0x74, 0x98, 0xad, 0x87, 0x53, 0x4c, - 0x94, 0xb2, 0x27, 0xbb, 0x4f, 0xd8, 0x2e, 0xa8, 0x9c, 0xb6, 0x00, 0xc5, 0x7f, 0x13, 0x00, 0x1d, - 0xbd, 0x6f, 0xa1, 0xb9, 0x6d, 0xa5, 0x15, 0xdb, 0x0a, 0xd4, 0xfa, 0x25, 0xf4, 0xc1, 0x9b, 0x96, - 0xfb, 0x0c, 0xc0, 0x0f, 0xe4, 0xce, 0x63, 0x25, 0x49, 0xac, 0x0c, 0x19, 0x21, 0xc1, 0x0a, 0x90, - 0xb8, 0x42, 0x33, 0x3e, 0x45, 0xc6, 0x83, 0x26, 0xb7, 0x0d, 0x49, 0xec, 0xdd, 0x29, 0xe2, 0x37, - 0xc8, 0x99, 0x9e, 0x77, 0xc4, 0xbf, 0x22, 0xef, 0x1f, 0xd1, 0xde, 0x27, 0x7e, 0x5d, 0x56, 0x83, - 0x76, 0xfe, 0x21, 0xa4, 0x6a, 0x9a, 0x5c, 0xe9, 0xc8, 0x91, 0xf7, 0x57, 0xb1, 0xda, 0x04, 0xe9, - 0x3e, 0x0a, 0xa8, 0x6e, 0xab, 0x1e, 0x50, 0xf1, 0xa7, 0xa8, 0xae, 0x6b, 0x84, 0x54, 0x5d, 0x56, - 0x64, 0x4c, 0x25, 0x9e, 0xa2, 0xea, 0xc8, 0x42, 0xfe, 0xfa, 0x09, 0xf9, 0x1f, 0x1b, 0xac, 0x3a, - 0xb5, 0xae, 0xda, 0x33, 0x7b, 0x10, 0xdd, 0x6c, 0xef, 0xd0, 0x60, 0x07, 0x90, 0x9d, 0xda, 0x9e, - 0x63, 0x99, 0x03, 0xd3, 0x47, 0x06, 0xd9, 0xf1, 0xb4, 0x46, 0x0f, 0x3d, 0xbf, 0x87, 0x02, 0xe5, - 0x4f, 0x16, 0xfb, 0x33, 0xb3, 0xb4, 0x61, 0x70, 0x68, 0x5c, 0x7d, 0x66, 0x39, 0xba, 0x41, 0xb6, - 0x2b, 0xa7, 0x45, 0x5d, 0xf1, 0x67, 0x9c, 0x53, 0xcd, 0xc1, 0x5a, 0xa6, 0xb6, 0x11, 0xe5, 0x54, - 0x87, 0xf4, 0x78, 0xde, 0xf4, 0x70, 0x56, 0x81, 0xd3, 0x4b, 0x94, 0x53, 0xd7, 0x68, 0xa9, 0x6d, - 0x8e, 0x5d, 0x0b, 0x85, 0x3d, 0x6d, 0xb1, 0x52, 0xf8, 0x12, 0xf2, 0x2b, 0x53, 0x81, 0x88, 0x56, - 0x28, 0x82, 0x59, 0x11, 0x51, 0xfe, 0x2d, 0x0e, 0x59, 0xea, 0x21, 0xe0, 0x3e, 0xa7, 0x0d, 0xb1, - 0x83, 0x77, 0x87, 0xa3, 0x66, 0x23, 0x37, 0x48, 0x90, 0x57, 0xe5, 0xce, 0x77, 0x4d, 0xed, 0xbc, - 0x27, 0x5f, 0xca, 0x6a, 0x07, 0x9b, 0x82, 0xdc, 0x9b, 0x14, 0xba, 0xf2, 0x64, 0x94, 0x21, 0xdb, - 0xa9, 0x54, 0x15, 0x39, 0xa4, 0xc3, 0x9b, 0x91, 0xa2, 0xa9, 0x73, 0x7a, 0x04, 0x99, 0x56, 0xb7, - 0xfd, 0x6d, 0xaf, 0xd5, 0x55, 0x14, 0x6c, 0x90, 0x5d, 0x4c, 0x6e, 0x51, 0xe4, 0xe2, 0x7a, 0xc1, - 0x5c, 0xb5, 0xab, 0x9c, 0xf7, 0xda, 0xdf, 0xab, 0xb5, 0x02, 0xfb, 0x88, 0x8b, 0xcc, 0xc2, 0x7d, - 0x01, 0xe9, 0x5a, 0xf3, 0xa2, 0xd5, 0xec, 0xaa, 0xf5, 0x42, 0xf2, 0x11, 0x16, 0x55, 0x54, 0xd8, - 0x0a, 0xed, 0x46, 0x17, 0xa3, 0xca, 0xbf, 0xb8, 0x2f, 0xc6, 0x5e, 0xdf, 0x17, 0x99, 0x9f, 0x1e, - 0x8a, 0xcc, 0x2d, 0xfe, 0xfe, 0xc3, 0xdf, 0x2b, 0xfc, 0xf5, 0x53, 0xe4, 0xb5, 0x3d, 0x7d, 0x13, - 0x00, 0x00, 0xff, 0xff, 0x7d, 0x9c, 0x5f, 0x56, 0xa1, 0x07, 0x00, 0x00, + // 887 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x09, 0x6e, 0x88, 0x02, 0xff, 0xcc, 0x96, 0xc1, 0x6e, 0xe3, 0x44, + 0x18, 0xc7, 0xeb, 0xc4, 0x49, 0xe3, 0xaf, 0x0d, 0x1b, 0xbc, 0xdd, 0xad, 0xd7, 0x0b, 0x49, 0x31, + 0xcb, 0x2a, 0x44, 0xe0, 0xa2, 0xee, 0x13, 0x24, 0xb1, 0x05, 0xd9, 0xf5, 0x3a, 0x91, 0x93, 0x14, + 0x71, 0x8a, 0x9c, 0x78, 0x48, 0xac, 0x3a, 0xb6, 0x15, 0x3b, 0x45, 0x39, 0x81, 0x38, 0xad, 0x78, + 0x07, 0x4e, 0xcb, 0x99, 0x07, 0xe0, 0xc0, 0x89, 0xc3, 0x8a, 0x13, 0xdc, 0x10, 0x87, 0x8a, 0xee, + 0x13, 0xf0, 0x08, 0x8c, 0xc7, 0x76, 0x32, 0x4e, 0xa3, 0x5e, 0x40, 0xc0, 0xc1, 0xad, 0x67, 0xe6, + 0xe7, 0xcf, 0xdf, 0xf7, 0x9f, 0xff, 0xe7, 0x09, 0xdc, 0x71, 0x51, 0xf8, 0x85, 0xb7, 0xb8, 0xb0, + 0xc6, 0xb2, 0xbf, 0xf0, 0x42, 0x8f, 0xe7, 0xd6, 0x13, 0xe2, 0xd1, 0xd4, 0x9b, 0x7a, 0x64, 0xf6, + 0x34, 0xba, 0x8b, 0x01, 0xa9, 0x0b, 0xe5, 0x8f, 0xbd, 0x20, 0xb0, 0xfd, 0xe7, 0x28, 0x08, 0xcc, + 0x29, 0xe2, 0x1b, 0xc0, 0x86, 0x2b, 0x1f, 0x09, 0xcc, 0x09, 0x53, 0x7f, 0xe3, 0xec, 0xbe, 0xbc, + 0x89, 0x98, 0x10, 0x03, 0xbc, 0x6a, 0x10, 0x86, 0xe7, 0x81, 0xb5, 0xcc, 0xd0, 0x14, 0x72, 0x98, + 0x3d, 0x34, 0xc8, 0xbd, 0xf4, 0x32, 0x07, 0x9c, 0xee, 0x59, 0x48, 0xbd, 0x44, 0x6e, 0xc8, 0x7f, + 0x98, 0x89, 0xf6, 0x80, 0x8a, 0xb6, 0x66, 0x64, 0x2a, 0x60, 0x07, 0x8a, 0xce, 0x28, 0xb4, 0xe7, + 0x88, 0x84, 0x64, 0x5b, 0x67, 0xaf, 0xae, 0x6a, 0x7b, 0xbf, 0x5f, 0xd5, 0x1a, 0x53, 0x3b, 0x9c, + 0x2d, 0xc7, 0xf2, 0xc4, 0x9b, 0x9f, 0xce, 0xcc, 0x60, 0x66, 0x4f, 0xbc, 0x85, 0x7f, 0x1a, 0xa0, + 0xc5, 0xe7, 0xe4, 0x8f, 0xac, 0x99, 0x73, 0xdf, 0x5b, 0x84, 0x03, 0xfc, 0xa4, 0x51, 0x70, 0xa2, + 0x7f, 0xfc, 0x43, 0xe0, 0x5c, 0xfc, 0x8a, 0x91, 0x6b, 0xe2, 0x68, 0x79, 0x1c, 0x8d, 0x33, 0x4a, + 0xd1, 0x84, 0x8e, 0xc7, 0xd2, 0x97, 0xc0, 0x46, 0x6f, 0xe5, 0xdf, 0x83, 0xfd, 0x8e, 0x7e, 0xde, + 0xd4, 0x3a, 0x4a, 0x65, 0x4f, 0x14, 0xbe, 0xf9, 0xf6, 0xe4, 0x68, 0x9d, 0x56, 0xb4, 0xde, 0x71, + 0x2f, 0x4d, 0xc7, 0xb6, 0xf8, 0x1a, 0xb0, 0x4f, 0xbb, 0x1d, 0xbd, 0xc2, 0x88, 0xf7, 0x30, 0xf3, + 0x66, 0x86, 0x79, 0xea, 0xd9, 0x2e, 0xff, 0x0e, 0x14, 0x34, 0xb5, 0x79, 0xae, 0x56, 0x72, 0xe2, + 0x7d, 0x4c, 0xf0, 0x19, 0x42, 0x43, 0xe6, 0x25, 0x12, 0x0f, 0x5f, 0xbc, 0xac, 0xee, 0xfd, 0xf0, + 0x5d, 0x95, 0xbc, 0x58, 0xba, 0xce, 0xc1, 0xa1, 0x1e, 0x6b, 0x11, 0x0b, 0xf5, 0x51, 0x46, 0xa8, + 0xb7, 0x68, 0xa1, 0x28, 0xec, 0x3f, 0xd0, 0x8a, 0xff, 0x00, 0x20, 0x49, 0x66, 0x64, 0x5b, 0x02, + 0x1b, 0xad, 0xb6, 0xca, 0xaf, 0xaf, 0x6a, 0x5c, 0x92, 0x58, 0x47, 0x31, 0x52, 0x97, 0x75, 0x2c, + 0xe9, 0x05, 0x93, 0x48, 0x5b, 0xa7, 0xa5, 0x7d, 0x88, 0x45, 0x39, 0xa6, 0x0b, 0xa1, 0xd5, 0x95, + 0xd6, 0xea, 0xc6, 0x3b, 0xb0, 0x85, 0x11, 0x81, 0x1f, 0x6d, 0x04, 0x7e, 0x80, 0xa1, 0x7b, 0xdb, + 0xd0, 0x2e, 0x8d, 0x7f, 0x64, 0x36, 0x1a, 0xbb, 0xe1, 0x62, 0xb5, 0x55, 0x09, 0x73, 0x7b, 0x25, + 0xff, 0x9a, 0xbe, 0x02, 0xec, 0x3b, 0x38, 0x7b, 0xdb, 0x9d, 0x12, 0x71, 0x4b, 0x46, 0x3a, 0x94, + 0xbe, 0x67, 0xe0, 0x4e, 0x92, 0x5a, 0x6f, 0x19, 0xcc, 0x7a, 0x4b, 0xc7, 0xa1, 0xb2, 0x62, 0xfe, + 0x6e, 0x56, 0x4f, 0xa0, 0x94, 0x54, 0x1b, 0xe0, 0x12, 0xf3, 0xf5, 0x83, 0xb3, 0xe3, 0x1d, 0xb6, + 0x8b, 0x94, 0x33, 0xd6, 0xe0, 0xed, 0x6d, 0xf5, 0x73, 0x1e, 0x60, 0x60, 0x8e, 0x9d, 0xa4, 0xf9, + 0xe5, 0x8c, 0xa7, 0x45, 0x2a, 0xf8, 0x06, 0xfa, 0xdf, 0x3b, 0x9a, 0x7f, 0x1b, 0x20, 0x8c, 0xd2, + 0x8d, 0x63, 0x15, 0x48, 0x2c, 0x8e, 0xcc, 0x90, 0x60, 0x15, 0xc8, 0x5f, 0xa0, 0x95, 0x50, 0x24, + 0xf3, 0xd1, 0x2d, 0x7f, 0x04, 0x05, 0x6c, 0xec, 0x25, 0x12, 0xf6, 0xc9, 0x67, 0x31, 0x1e, 0x44, + 0x9b, 0x19, 0x37, 0xc6, 0x63, 0xba, 0x31, 0x88, 0x99, 0x37, 0x6a, 0xd0, 0x6d, 0xf1, 0x08, 0x8a, + 0x6d, 0x43, 0x6d, 0x0e, 0xd4, 0xb4, 0x31, 0xb2, 0x58, 0x7b, 0x81, 0xcc, 0x10, 0x45, 0xd4, 0xb0, + 0xa7, 0x44, 0x54, 0x6e, 0x17, 0x35, 0xf4, 0xad, 0x84, 0x52, 0x54, 0x4d, 0xc5, 0x54, 0x7e, 0x17, + 0xa5, 0x20, 0x07, 0x85, 0xdb, 0xed, 0xf3, 0x2b, 0x76, 0x5f, 0x6b, 0xe9, 0x5c, 0xf4, 0x57, 0xee, + 0x24, 0x3d, 0x1c, 0xfe, 0x41, 0xf7, 0x9d, 0xc0, 0xc1, 0xd2, 0x0d, 0x3c, 0xc7, 0x9e, 0xd8, 0x21, + 0xb2, 0xc8, 0x8e, 0x97, 0x0c, 0x7a, 0xea, 0xf6, 0x3d, 0x14, 0x29, 0xf3, 0xb2, 0xd8, 0xbc, 0x1c, + 0xe5, 0x51, 0xdc, 0x51, 0xbe, 0xb9, 0x72, 0x3c, 0xd3, 0x22, 0xdb, 0x75, 0x68, 0xa4, 0x43, 0xe9, + 0x6b, 0x5c, 0x53, 0xdb, 0xc3, 0xb9, 0x2c, 0x5d, 0x2b, 0xad, 0x49, 0x81, 0xd2, 0x3c, 0xbe, 0x0d, + 0x70, 0x55, 0x51, 0x1b, 0xd4, 0x29, 0xa7, 0x6e, 0xd1, 0x72, 0xdf, 0x9e, 0xfb, 0x0e, 0x4a, 0x46, + 0xc6, 0xfa, 0x49, 0xf1, 0x7d, 0x28, 0x67, 0x96, 0xa2, 0x24, 0x7a, 0x49, 0x12, 0x4c, 0x26, 0x89, + 0xc6, 0x4f, 0x39, 0x38, 0xa0, 0xce, 0x52, 0xfe, 0x5d, 0xda, 0x10, 0xe4, 0xf8, 0xa0, 0x56, 0x53, + 0x37, 0xc8, 0x50, 0xd6, 0xd5, 0xc1, 0xa7, 0x5d, 0xe3, 0xd9, 0x48, 0x3d, 0x57, 0xf5, 0x01, 0x36, + 0x05, 0xf9, 0xa8, 0x52, 0x68, 0xe6, 0x3c, 0x69, 0xc0, 0xc1, 0xa0, 0xd9, 0xd2, 0xd4, 0x84, 0x4e, + 0x3e, 0x9b, 0x14, 0x4d, 0xf5, 0xe9, 0x63, 0xe0, 0x7a, 0xc3, 0xfe, 0x27, 0xa3, 0xde, 0x50, 0xd3, + 0xb0, 0x41, 0x8e, 0x31, 0x79, 0x97, 0x22, 0xd7, 0xdf, 0x1e, 0xcc, 0xb5, 0x86, 0xda, 0xb3, 0x51, + 0xff, 0x33, 0xbd, 0x5d, 0x61, 0x6f, 0x70, 0xa9, 0x59, 0xf0, 0xa9, 0x5a, 0x6a, 0x77, 0x9f, 0xf7, + 0xba, 0x43, 0x5d, 0xa9, 0x14, 0x6e, 0x60, 0xa9, 0xa2, 0xf8, 0x84, 0x00, 0xbd, 0xab, 0xa4, 0x19, + 0x16, 0x63, 0x63, 0xd2, 0xf5, 0xa4, 0x87, 0xa8, 0x78, 0x37, 0x31, 0x26, 0x2d, 0x5b, 0x4b, 0xf8, + 0xed, 0xba, 0xba, 0xf7, 0xe7, 0x75, 0x95, 0xf9, 0xea, 0x75, 0x95, 0x79, 0x85, 0xaf, 0x5f, 0xf0, + 0xf5, 0x07, 0xbe, 0xc6, 0x45, 0xf2, 0xd3, 0xe6, 0xc9, 0x5f, 0x01, 0x00, 0x00, 0xff, 0xff, 0x21, + 0x78, 0x72, 0xc3, 0x0e, 0x09, 0x00, 0x00, } diff --git a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.proto b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.proto index dbc7a921d0..7df1b42dca 100644 --- a/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.proto +++ b/vendor/src/github.com/docker/libnetwork/networkdb/networkdb.proto @@ -41,6 +41,10 @@ enum MessageType { // which is a pack of many message of above types, packed into // a single compound message. COMPOUND = 5 [(gogoproto.enumvalue_customname) = "MessageTypeCompound"]; + + // NodeEvent message type is used to communicare node + // join/leave events in the cluster + NODE_EVENT = 6 [(gogoproto.enumvalue_customname) = "MessageTypeNodeEvent"]; } // GossipMessage is a basic message header used by all messages types. @@ -49,6 +53,29 @@ message GossipMessage { bytes data = 2; // Payload of the message of any type defined here. } +// NodeEvent message payload definition. +message NodeEvent { + enum Type { + option (gogoproto.goproto_enum_prefix) = false; + option (gogoproto.enum_customname) = "Type"; + + INVALID = 0 [(gogoproto.enumvalue_customname) = "NodeEventTypeInvalid"]; + // Join event is generated when this node joins the cluster. + JOIN = 1 [(gogoproto.enumvalue_customname) = "NodeEventTypeJoin"];; + // Leave event is generated when this node leaves the cluster. + LEAVE = 2 [(gogoproto.enumvalue_customname) = "NodeEventTypeLeave"];; + } + + Type type = 1; + + // Lamport time using a network lamport clock indicating the + // time this event was generated on the node where it was + // generated. + uint64 l_time = 2 [(gogoproto.customtype) = "github.com/hashicorp/serf/serf.LamportTime", (gogoproto.nullable) = false]; + // Source node name. + string node_name = 3; +} + // NetworkEvent message payload definition. message NetworkEvent { enum Type { diff --git a/vendor/src/github.com/docker/libnetwork/osl/neigh_linux.go b/vendor/src/github.com/docker/libnetwork/osl/neigh_linux.go index c5c6c103d0..a7669a111b 100644 --- a/vendor/src/github.com/docker/libnetwork/osl/neigh_linux.go +++ b/vendor/src/github.com/docker/libnetwork/osl/neigh_linux.go @@ -32,7 +32,7 @@ func (n *networkNamespace) findNeighbor(dstIP net.IP, dstMac net.HardwareAddr) * return nil } -func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr) error { +func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr, osDelete bool) error { var ( iface netlink.Link err error @@ -43,42 +43,46 @@ func (n *networkNamespace) DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr) return fmt.Errorf("could not find the neighbor entry to delete") } - n.Lock() - nlh := n.nlHandle - n.Unlock() + if osDelete { + n.Lock() + nlh := n.nlHandle + n.Unlock() - if nh.linkDst != "" { - iface, err = nlh.LinkByName(nh.linkDst) - if err != nil { - return fmt.Errorf("could not find interface with destination name %s: %v", - nh.linkDst, err) + if nh.linkDst != "" { + iface, err = nlh.LinkByName(nh.linkDst) + if err != nil { + return fmt.Errorf("could not find interface with destination name %s: %v", + nh.linkDst, err) + } + } + + nlnh := &netlink.Neigh{ + IP: dstIP, + State: netlink.NUD_PERMANENT, + Family: nh.family, + } + + if nlnh.Family > 0 { + nlnh.HardwareAddr = dstMac + nlnh.Flags = netlink.NTF_SELF + } + + if nh.linkDst != "" { + nlnh.LinkIndex = iface.Attrs().Index + } + + if err := nlh.NeighDel(nlnh); err != nil { + return fmt.Errorf("could not delete neighbor entry: %v", err) } } - nlnh := &netlink.Neigh{ - IP: dstIP, - State: netlink.NUD_PERMANENT, - Family: nh.family, - } - - if nlnh.Family > 0 { - nlnh.HardwareAddr = dstMac - nlnh.Flags = netlink.NTF_SELF - } - - if nh.linkDst != "" { - nlnh.LinkIndex = iface.Attrs().Index - } - - if err := nlh.NeighDel(nlnh); err != nil { - return fmt.Errorf("could not delete neighbor entry: %v", err) - } - + n.Lock() for i, nh := range n.neighbors { if nh.dstIP.Equal(dstIP) && bytes.Equal(nh.dstMac, dstMac) { n.neighbors = append(n.neighbors[:i], n.neighbors[i+1:]...) } } + n.Unlock() return nil } diff --git a/vendor/src/github.com/docker/libnetwork/osl/sandbox.go b/vendor/src/github.com/docker/libnetwork/osl/sandbox.go index 75968a0f87..18085c9082 100644 --- a/vendor/src/github.com/docker/libnetwork/osl/sandbox.go +++ b/vendor/src/github.com/docker/libnetwork/osl/sandbox.go @@ -42,7 +42,7 @@ type Sandbox interface { AddNeighbor(dstIP net.IP, dstMac net.HardwareAddr, option ...NeighOption) error // DeleteNeighbor deletes neighbor entry from the sandbox. - DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr) error + DeleteNeighbor(dstIP net.IP, dstMac net.HardwareAddr, osDelete bool) error // Returns an interface with methods to set neighbor options. NeighborOptions() NeighborOptionSetter diff --git a/vendor/src/github.com/docker/libnetwork/resolver.go b/vendor/src/github.com/docker/libnetwork/resolver.go index fcb1a00a02..81b3520ae2 100644 --- a/vendor/src/github.com/docker/libnetwork/resolver.go +++ b/vendor/src/github.com/docker/libnetwork/resolver.go @@ -23,7 +23,7 @@ type Resolver interface { Stop() // SetupFunc() provides the setup function that should be run // in the container's network namespace. - SetupFunc() func() + SetupFunc(int) func() // NameServer() returns the IP of the DNS resolver for the // containers. NameServer() string @@ -34,8 +34,29 @@ type Resolver interface { ResolverOptions() []string } +// DNSBackend represents a backend DNS resolver used for DNS name +// resolution. All the queries to the resolver are forwared to the +// backend resolver. +type DNSBackend interface { + // 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 + // ResolveService returns all the backend details about the containers or hosts + // backing a service. Its purpose is to satisfy an SRV query + ResolveService(name string) ([]*net.SRV, []net.IP) + // ExecFunc allows a function to be executed in the context of the backend + // on behalf of the resolver. + ExecFunc(f func()) error + //NdotsSet queries the backends ndots dns option settings + NdotsSet() bool +} + const ( - resolverIP = "127.0.0.11" dnsPort = "53" ptrIPv4domain = ".in-addr.arpa." ptrIPv6domain = ".ip6.arpa." @@ -53,16 +74,19 @@ type extDNSEntry struct { // resolver implements the Resolver interface type resolver struct { - sb *sandbox - extDNSList [maxExtDNS]extDNSEntry - server *dns.Server - conn *net.UDPConn - tcpServer *dns.Server - tcpListen *net.TCPListener - err error - count int32 - tStamp time.Time - queryLock sync.Mutex + backend DNSBackend + extDNSList [maxExtDNS]extDNSEntry + server *dns.Server + conn *net.UDPConn + tcpServer *dns.Server + tcpListen *net.TCPListener + err error + count int32 + tStamp time.Time + queryLock sync.Mutex + listenAddress string + proxyDNS bool + resolverKey string } func init() { @@ -70,20 +94,24 @@ func init() { } // NewResolver creates a new instance of the Resolver -func NewResolver(sb *sandbox) Resolver { +func NewResolver(address string, proxyDNS bool, resolverKey string, backend DNSBackend) Resolver { return &resolver{ - sb: sb, - err: fmt.Errorf("setup not done yet"), + backend: backend, + proxyDNS: proxyDNS, + listenAddress: address, + resolverKey: resolverKey, + err: fmt.Errorf("setup not done yet"), } } -func (r *resolver) SetupFunc() func() { +func (r *resolver) SetupFunc(port int) func() { return (func() { var err error // DNS operates primarily on UDP addr := &net.UDPAddr{ - IP: net.ParseIP(resolverIP), + IP: net.ParseIP(r.listenAddress), + Port: port, } r.conn, err = net.ListenUDP("udp", addr) @@ -94,7 +122,8 @@ func (r *resolver) SetupFunc() func() { // Listen on a TCP as well tcpaddr := &net.TCPAddr{ - IP: net.ParseIP(resolverIP), + IP: net.ParseIP(r.listenAddress), + Port: port, } r.tcpListen, err = net.ListenTCP("tcp", tcpaddr) @@ -156,7 +185,7 @@ func (r *resolver) SetExtServers(dns []string) { } func (r *resolver) NameServer() string { - return resolverIP + return r.listenAddress } func (r *resolver) ResolverOptions() []string { @@ -184,7 +213,10 @@ func createRespMsg(query *dns.Msg) *dns.Msg { } func (r *resolver) handleIPQuery(name string, query *dns.Msg, ipType int) (*dns.Msg, error) { - addr, ipv6Miss := r.sb.ResolveName(name, ipType) + var addr []net.IP + var ipv6Miss bool + addr, ipv6Miss = r.backend.ResolveName(name, ipType) + if addr == nil && ipv6Miss { // Send a reply without any Answer sections log.Debugf("Lookup name %s present without IPv6 address", name) @@ -230,7 +262,8 @@ func (r *resolver) handlePTRQuery(ptr string, query *dns.Msg) (*dns.Msg, error) return nil, fmt.Errorf("invalid PTR query, %v", ptr) } - host := r.sb.ResolveIP(parts[0]) + host := r.backend.ResolveIP(parts[0]) + if len(host) == 0 { return nil, nil } @@ -250,11 +283,9 @@ func (r *resolver) handlePTRQuery(ptr string, query *dns.Msg) (*dns.Msg, error) } func (r *resolver) handleSRVQuery(svc string, query *dns.Msg) (*dns.Msg, error) { - srv, ip, err := r.sb.ResolveService(svc) - if err != nil { - return nil, err - } + srv, ip := r.backend.ResolveService(svc) + if len(srv) == 0 { return nil, nil } @@ -325,16 +356,25 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) { return } - // If the user sets ndots > 0 explicitly and the query is - // in the root domain don't forward it out. We will return - // failure and let the client retry with the search domain - // attached if resp == nil { + // If the backend doesn't support proxying dns request + // fail the response + if !r.proxyDNS { + resp = new(dns.Msg) + resp.SetRcode(query, dns.RcodeServerFailure) + w.WriteMsg(resp) + return + } + + // If the user sets ndots > 0 explicitly and the query is + // in the root domain don't forward it out. We will return + // failure and let the client retry with the search domain + // attached switch query.Question[0].Qtype { case dns.TypeA: fallthrough case dns.TypeAAAA: - if r.sb.ndotsSet && !strings.Contains(strings.TrimSuffix(name, "."), ".") { + if r.backend.NdotsSet() && !strings.Contains(strings.TrimSuffix(name, "."), ".") { resp = createRespMsg(query) } } @@ -369,8 +409,8 @@ func (r *resolver) ServeDNS(w dns.ResponseWriter, query *dns.Msg) { extConn, err = net.DialTimeout(proto, addr, extIOTimeout) } - r.sb.execFunc(extConnect) - if err != nil { + execErr := r.backend.ExecFunc(extConnect) + if execErr != nil || err != nil { log.Debugf("Connect failed, %s", err) continue } diff --git a/vendor/src/github.com/docker/libnetwork/resolver_unix.go b/vendor/src/github.com/docker/libnetwork/resolver_unix.go index cec2c7d493..17dce480d0 100644 --- a/vendor/src/github.com/docker/libnetwork/resolver_unix.go +++ b/vendor/src/github.com/docker/libnetwork/resolver_unix.go @@ -35,7 +35,7 @@ func reexecSetupResolver() { os.Exit(1) } - _, ipPort, _ := net.SplitHostPort(os.Args[2]) + resolverIP, ipPort, _ := net.SplitHostPort(os.Args[2]) _, tcpPort, _ := net.SplitHostPort(os.Args[3]) rules := [][]string{ {"-t", "nat", "-I", outputChain, "-d", resolverIP, "-p", "udp", "--dport", dnsPort, "-j", "DNAT", "--to-destination", os.Args[2]}, @@ -90,7 +90,7 @@ func (r *resolver) setupIPTable() error { cmd := &exec.Cmd{ Path: reexec.Self(), - Args: append([]string{"setup-resolver"}, r.sb.Key(), laddr, ltcpaddr), + Args: append([]string{"setup-resolver"}, r.resolverKey, laddr, ltcpaddr), Stdout: os.Stdout, Stderr: os.Stderr, } diff --git a/vendor/src/github.com/docker/libnetwork/sandbox.go b/vendor/src/github.com/docker/libnetwork/sandbox.go index ed439ff608..3bb1bb3644 100644 --- a/vendor/src/github.com/docker/libnetwork/sandbox.go +++ b/vendor/src/github.com/docker/libnetwork/sandbox.go @@ -37,19 +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. 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 - // ResolveService returns all the backend details about the containers or hosts - // backing a service. Its purpose is to satisfy an SRV query - ResolveService(name string) ([]*net.SRV, []net.IP, error) // Endpoints returns all the endpoints connected to the sandbox Endpoints() []Endpoint + // ResolveService returns all the backend details about the containers or hosts + // backing a service. Its purpose is to satisfy an SRV query + ResolveService(name string) ([]*net.SRV, []net.IP) } // SandboxOption is an option setter function type used to pass various options to @@ -131,6 +123,10 @@ type containerConfig struct { exposedPorts []types.TransportPort } +const ( + resolverIPSandbox = "127.0.0.11" +) + func (sb *sandbox) ID() string { return sb.id } @@ -415,33 +411,21 @@ func (sb *sandbox) ResolveIP(ip string) string { for _, ep := range sb.getConnectedEndpoints() { n := ep.getNetwork() - - c := n.getController() - - c.Lock() - sr, ok := c.svcRecords[n.ID()] - c.Unlock() - - if !ok { - continue - } - - nwName := n.Name() - n.Lock() - svc, ok = sr.ipMap[ip] - n.Unlock() - if ok { - return svc + "." + nwName + svc = n.ResolveIP(ip) + if len(svc) != 0 { + return svc } } + return svc } -func (sb *sandbox) execFunc(f func()) { +func (sb *sandbox) ExecFunc(f func()) error { sb.osSbox.InvokeFunc(f) + return nil } -func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP, error) { +func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP) { srv := []*net.SRV{} ip := []net.IP{} @@ -452,53 +436,18 @@ func (sb *sandbox) ResolveService(name string) ([]*net.SRV, []net.IP, error) { // not done parts := strings.Split(name, ".") if len(parts) < 3 { - return nil, nil, nil + return nil, nil } - portName := parts[0] - proto := parts[1] - svcName := strings.Join(parts[2:], ".") - for _, ep := range sb.getConnectedEndpoints() { n := ep.getNetwork() - c := n.getController() - - c.Lock() - sr, ok := c.svcRecords[n.ID()] - c.Unlock() - - if !ok { - continue - } - - svcs, ok := sr.service[svcName] - if !ok { - continue - } - - for _, svc := range svcs { - if svc.portName != portName { - continue - } - if svc.proto != proto { - continue - } - for _, t := range svc.target { - srv = append(srv, - &net.SRV{ - Target: t.name, - Port: t.port, - }) - - ip = append(ip, t.ip) - } - } + srv, ip = n.ResolveService(name) if len(srv) > 0 { break } } - return srv, ip, nil + return srv, ip } func getDynamicNwEndpoints(epList []*endpoint) []*endpoint { @@ -635,33 +584,15 @@ func (sb *sandbox) resolveName(req string, networkName string, epList []*endpoin ep.Unlock() } - c := n.getController() - c.Lock() - sr, ok := c.svcRecords[n.ID()] - c.Unlock() + ip, miss := n.ResolveName(name, ipType) - if !ok { - continue - } - - var ip []net.IP - n.Lock() - ip, ok = sr.svcMap[name] - - if ipType == types.IPv6 { - // 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 ip != nil { return ip, false } + + if miss { + ipv6Miss = miss + } } return nil, ipv6Miss } @@ -708,7 +639,7 @@ func (sb *sandbox) SetKey(basePath string) error { if oldosSbox != nil && sb.resolver != nil { sb.resolver.Stop() - sb.osSbox.InvokeFunc(sb.resolver.SetupFunc()) + sb.osSbox.InvokeFunc(sb.resolver.SetupFunc(0)) if err := sb.resolver.Start(); err != nil { log.Errorf("Resolver Setup/Start failed for container %s, %q", sb.ContainerID(), err) } @@ -1231,3 +1162,7 @@ func (eh *epHeap) Pop() interface{} { *eh = old[0 : n-1] return x } + +func (sb *sandbox) NdotsSet() bool { + return sb.ndotsSet +} diff --git a/vendor/src/github.com/docker/libnetwork/sandbox_dns_unix.go b/vendor/src/github.com/docker/libnetwork/sandbox_dns_unix.go index cd9e66224f..45b035e3e5 100644 --- a/vendor/src/github.com/docker/libnetwork/sandbox_dns_unix.go +++ b/vendor/src/github.com/docker/libnetwork/sandbox_dns_unix.go @@ -26,7 +26,7 @@ const ( func (sb *sandbox) startResolver(restore bool) { sb.resolverOnce.Do(func() { var err error - sb.resolver = NewResolver(sb) + sb.resolver = NewResolver(resolverIPSandbox, true, sb.Key(), sb) defer func() { if err != nil { sb.resolver = nil @@ -46,7 +46,7 @@ func (sb *sandbox) startResolver(restore bool) { } sb.resolver.SetExtServers(sb.extDNS) - sb.osSbox.InvokeFunc(sb.resolver.SetupFunc()) + sb.osSbox.InvokeFunc(sb.resolver.SetupFunc(0)) if err = sb.resolver.Start(); err != nil { log.Errorf("Resolver Setup/Start failed for container %s, %q", sb.ContainerID(), err) }