|
@@ -3,12 +3,10 @@ package libnetwork
|
|
|
//go:generate protoc -I.:Godeps/_workspace/src/github.com/gogo/protobuf --gogo_out=import_path=github.com/docker/libnetwork,Mgogoproto/gogo.proto=github.com/gogo/protobuf/gogoproto:. agent.proto
|
|
|
|
|
|
import (
|
|
|
- "encoding/hex"
|
|
|
"fmt"
|
|
|
"net"
|
|
|
"os"
|
|
|
"sort"
|
|
|
- "strconv"
|
|
|
|
|
|
"github.com/Sirupsen/logrus"
|
|
|
"github.com/docker/go-events"
|
|
@@ -20,6 +18,12 @@ import (
|
|
|
"github.com/gogo/protobuf/proto"
|
|
|
)
|
|
|
|
|
|
+const (
|
|
|
+ subsysGossip = "networking:gossip"
|
|
|
+ subsysIPSec = "networking:ipsec"
|
|
|
+ keyringSize = 3
|
|
|
+)
|
|
|
+
|
|
|
// ByTime implements sort.Interface for []*types.EncryptionKey based on
|
|
|
// the LamportTime field.
|
|
|
type ByTime []*types.EncryptionKey
|
|
@@ -80,6 +84,82 @@ func resolveAddr(addrOrInterface string) (string, error) {
|
|
|
func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
|
|
|
drvEnc := discoverapi.DriverEncryptionUpdate{}
|
|
|
|
|
|
+ a := c.agent
|
|
|
+ // Find the deleted key. If the deleted key was the primary key,
|
|
|
+ // a new primary key should be set before removing if from keyring.
|
|
|
+ deleted := []byte{}
|
|
|
+ j := len(c.keys)
|
|
|
+ for i := 0; i < j; {
|
|
|
+ same := false
|
|
|
+ for _, key := range keys {
|
|
|
+ if same = key.LamportTime == c.keys[i].LamportTime; same {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if !same {
|
|
|
+ cKey := c.keys[i]
|
|
|
+ if cKey.Subsystem == subsysGossip {
|
|
|
+ deleted = cKey.Key
|
|
|
+ }
|
|
|
+
|
|
|
+ if cKey.Subsystem == subsysGossip /* subsysIPSec */ {
|
|
|
+ drvEnc.Prune = cKey.Key
|
|
|
+ drvEnc.PruneTag = cKey.LamportTime
|
|
|
+ }
|
|
|
+ c.keys[i], c.keys[j-1] = c.keys[j-1], c.keys[i]
|
|
|
+ c.keys[j-1] = nil
|
|
|
+ j--
|
|
|
+ }
|
|
|
+ i++
|
|
|
+ }
|
|
|
+ c.keys = c.keys[:j]
|
|
|
+
|
|
|
+ // Find the new key and add it to the key ring
|
|
|
+ for _, key := range keys {
|
|
|
+ same := false
|
|
|
+ for _, cKey := range c.keys {
|
|
|
+ if same = cKey.LamportTime == key.LamportTime; same {
|
|
|
+ break
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if !same {
|
|
|
+ c.keys = append(c.keys, key)
|
|
|
+ if key.Subsystem == subsysGossip {
|
|
|
+ a.networkDB.SetKey(key.Key)
|
|
|
+ }
|
|
|
+
|
|
|
+ if key.Subsystem == subsysGossip /*subsysIPSec*/ {
|
|
|
+ drvEnc.Key = key.Key
|
|
|
+ drvEnc.Tag = key.LamportTime
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ key, tag := c.getPrimaryKeyTag(subsysGossip)
|
|
|
+ a.networkDB.SetPrimaryKey(key)
|
|
|
+
|
|
|
+ //key, tag = c.getPrimaryKeyTag(subsysIPSec)
|
|
|
+ drvEnc.Primary = key
|
|
|
+ drvEnc.PrimaryTag = tag
|
|
|
+
|
|
|
+ if len(deleted) > 0 {
|
|
|
+ a.networkDB.RemoveKey(deleted)
|
|
|
+ }
|
|
|
+
|
|
|
+ c.drvRegistry.WalkDrivers(func(name string, driver driverapi.Driver, capability driverapi.Capability) bool {
|
|
|
+ err := driver.DiscoverNew(discoverapi.EncryptionKeysUpdate, drvEnc)
|
|
|
+ if err != nil {
|
|
|
+ logrus.Warnf("Failed to update datapath keys in driver %s: %v", name, err)
|
|
|
+ }
|
|
|
+ return false
|
|
|
+ })
|
|
|
+
|
|
|
+ return nil
|
|
|
+}
|
|
|
+
|
|
|
+func (c *controller) handleKeyChangeV1(keys []*types.EncryptionKey) error {
|
|
|
+ drvEnc := discoverapi.DriverEncryptionUpdate{}
|
|
|
+
|
|
|
// Find the new key and add it to the key ring
|
|
|
a := c.agent
|
|
|
for _, key := range keys {
|
|
@@ -91,12 +171,12 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
|
|
|
}
|
|
|
if !same {
|
|
|
c.keys = append(c.keys, key)
|
|
|
- if key.Subsystem == "networking:gossip" {
|
|
|
+ if key.Subsystem == subsysGossip {
|
|
|
a.networkDB.SetKey(key.Key)
|
|
|
}
|
|
|
- if key.Subsystem == "networking:gossip" /*"networking:ipsec"*/ {
|
|
|
- drvEnc.Key = hex.EncodeToString(key.Key)
|
|
|
- drvEnc.Tag = strconv.FormatUint(key.LamportTime, 10)
|
|
|
+ if key.Subsystem == subsysGossip /*subsysIPSec*/ {
|
|
|
+ drvEnc.Key = key.Key
|
|
|
+ drvEnc.Tag = key.LamportTime
|
|
|
}
|
|
|
break
|
|
|
}
|
|
@@ -112,12 +192,12 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
|
|
|
}
|
|
|
}
|
|
|
if !same {
|
|
|
- if cKey.Subsystem == "networking:gossip" {
|
|
|
+ if cKey.Subsystem == subsysGossip {
|
|
|
deleted = cKey.Key
|
|
|
}
|
|
|
- if cKey.Subsystem == "networking:gossip" /*"networking:ipsec"*/ {
|
|
|
- drvEnc.Prune = hex.EncodeToString(cKey.Key)
|
|
|
- drvEnc.PruneTag = strconv.FormatUint(cKey.LamportTime, 10)
|
|
|
+ if cKey.Subsystem == subsysGossip /*subsysIPSec*/ {
|
|
|
+ drvEnc.Prune = cKey.Key
|
|
|
+ drvEnc.PruneTag = cKey.LamportTime
|
|
|
}
|
|
|
c.keys = append(c.keys[:i], c.keys[i+1:]...)
|
|
|
break
|
|
@@ -126,15 +206,15 @@ func (c *controller) handleKeyChange(keys []*types.EncryptionKey) error {
|
|
|
|
|
|
sort.Sort(ByTime(c.keys))
|
|
|
for _, key := range c.keys {
|
|
|
- if key.Subsystem == "networking:gossip" {
|
|
|
+ if key.Subsystem == subsysGossip {
|
|
|
a.networkDB.SetPrimaryKey(key.Key)
|
|
|
break
|
|
|
}
|
|
|
}
|
|
|
for _, key := range c.keys {
|
|
|
- if key.Subsystem == "networking:gossip" /*"networking:ipsec"*/ {
|
|
|
- drvEnc.Primary = hex.EncodeToString(key.Key)
|
|
|
- drvEnc.PrimaryTag = strconv.FormatUint(key.LamportTime, 10)
|
|
|
+ if key.Subsystem == subsysGossip /*subsysIPSec*/ {
|
|
|
+ drvEnc.Primary = key.Key
|
|
|
+ drvEnc.PrimaryTag = key.LamportTime
|
|
|
break
|
|
|
}
|
|
|
}
|
|
@@ -197,26 +277,51 @@ func (c *controller) agentSetup() error {
|
|
|
return nil
|
|
|
}
|
|
|
|
|
|
-func (c *controller) agentInit(bindAddrOrInterface string) error {
|
|
|
- if !c.isAgent() {
|
|
|
- return nil
|
|
|
+// For a given subsystem getKeys sorts the keys by lamport time and returns
|
|
|
+// slice of keys and lamport time which can used as a unique tag for the keys
|
|
|
+func (c *controller) getKeys(subsys string) ([][]byte, []uint64) {
|
|
|
+ sort.Sort(ByTime(c.keys))
|
|
|
+
|
|
|
+ keys := [][]byte{}
|
|
|
+ tags := []uint64{}
|
|
|
+ for _, key := range c.keys {
|
|
|
+ if key.Subsystem == subsys {
|
|
|
+ keys = append(keys, key.Key)
|
|
|
+ tags = append(tags, key.LamportTime)
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
- drvEnc := discoverapi.DriverEncryptionConfig{}
|
|
|
+ if len(keys) < keyringSize {
|
|
|
+ return keys, tags
|
|
|
+ }
|
|
|
+ keys[0], keys[1] = keys[1], keys[0]
|
|
|
+ tags[0], tags[1] = tags[1], tags[0]
|
|
|
+ return keys, tags
|
|
|
+}
|
|
|
|
|
|
- // sort the keys by lamport time
|
|
|
+// getPrimaryKeyTag returns the primary key for a given subsytem from the
|
|
|
+// list of sorted key and the associated tag
|
|
|
+func (c *controller) getPrimaryKeyTag(subsys string) ([]byte, uint64) {
|
|
|
sort.Sort(ByTime(c.keys))
|
|
|
-
|
|
|
- gossipkey := [][]byte{}
|
|
|
+ keys := []*types.EncryptionKey{}
|
|
|
for _, key := range c.keys {
|
|
|
- if key.Subsystem == "networking:gossip" {
|
|
|
- gossipkey = append(gossipkey, key.Key)
|
|
|
- }
|
|
|
- if key.Subsystem == "networking:gossip" /*"networking:ipsec"*/ {
|
|
|
- drvEnc.Keys = append(drvEnc.Keys, hex.EncodeToString(key.Key))
|
|
|
- drvEnc.Tags = append(drvEnc.Tags, strconv.FormatUint(key.LamportTime, 10))
|
|
|
+ if key.Subsystem == subsys {
|
|
|
+ keys = append(keys, key)
|
|
|
}
|
|
|
}
|
|
|
+ return keys[1].Key, keys[1].LamportTime
|
|
|
+}
|
|
|
+
|
|
|
+func (c *controller) agentInit(bindAddrOrInterface string) error {
|
|
|
+ if !c.isAgent() {
|
|
|
+ return nil
|
|
|
+ }
|
|
|
+
|
|
|
+ drvEnc := discoverapi.DriverEncryptionConfig{}
|
|
|
+
|
|
|
+ keys, tags := c.getKeys(subsysGossip) // getKeys(subsysIPSec)
|
|
|
+ drvEnc.Keys = keys
|
|
|
+ drvEnc.Tags = tags
|
|
|
|
|
|
bindAddr, err := resolveAddr(bindAddrOrInterface)
|
|
|
if err != nil {
|
|
@@ -227,7 +332,7 @@ func (c *controller) agentInit(bindAddrOrInterface string) error {
|
|
|
nDB, err := networkdb.New(&networkdb.Config{
|
|
|
BindAddr: bindAddr,
|
|
|
NodeName: hostname,
|
|
|
- Keys: gossipkey,
|
|
|
+ Keys: keys,
|
|
|
})
|
|
|
|
|
|
if err != nil {
|
|
@@ -275,12 +380,10 @@ func (c *controller) agentDriverNotify(d driverapi.Driver) {
|
|
|
})
|
|
|
|
|
|
drvEnc := discoverapi.DriverEncryptionConfig{}
|
|
|
- for _, key := range c.keys {
|
|
|
- if key.Subsystem == "networking:gossip" /*"networking:ipsec"*/ {
|
|
|
- drvEnc.Keys = append(drvEnc.Keys, hex.EncodeToString(key.Key))
|
|
|
- drvEnc.Tags = append(drvEnc.Tags, strconv.FormatUint(key.LamportTime, 10))
|
|
|
- }
|
|
|
- }
|
|
|
+ keys, tags := c.getKeys(subsysGossip) // getKeys(subsysIPSec)
|
|
|
+ drvEnc.Keys = keys
|
|
|
+ drvEnc.Tags = tags
|
|
|
+
|
|
|
c.drvRegistry.WalkDrivers(func(name string, driver driverapi.Driver, capability driverapi.Capability) bool {
|
|
|
err := driver.DiscoverNew(discoverapi.EncryptionKeysConfig, drvEnc)
|
|
|
if err != nil {
|