Merge branch '1.4'
This commit is contained in:
commit
63a9f879fb
4 files changed
+88
-3
No files matched your search
+21
-2
@@ -94,6 +94,9 @@ func (e1 *Entry) merge(e2 *Entry) bool {
|
||||
e1.Version = e2.Version
|
||||
e1.Tombstone = e2.Tombstone
|
||||
return true
|
||||
} else if e2.Version == e1.Version && e2.Tombstone > e1.Tombstone {
|
||||
e1.Tombstone = e2.Tombstone
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
@@ -106,6 +109,11 @@ func (e1 *Entry) addLowercase() {
|
||||
e1.lHostname = strings.ToLower(e1.Hostname)
|
||||
}
|
||||
|
||||
func (e *Entry) tombstone() {
|
||||
e.Version++
|
||||
e.Tombstone = now()
|
||||
}
|
||||
|
||||
func check(es SortableEntries) error {
|
||||
if !sort.IsSorted(es) {
|
||||
return fmt.Errorf("Not sorted!")
|
||||
@@ -183,8 +191,7 @@ func (es *Entries) tombstone(ourname mesh.PeerName, f func(*Entry) bool) Entries
|
||||
tombstoned := Entries{}
|
||||
for i, e := range *es {
|
||||
if f(&e) && e.Origin == ourname {
|
||||
e.Version++
|
||||
e.Tombstone = now()
|
||||
e.tombstone()
|
||||
(*es)[i] = e
|
||||
tombstoned = append(tombstoned, e)
|
||||
}
|
||||
@@ -192,6 +199,7 @@ func (es *Entries) tombstone(ourname mesh.PeerName, f func(*Entry) bool) Entries
|
||||
return tombstoned
|
||||
}
|
||||
|
||||
// note f() may only modify entries such that they remain in order defined by less()
|
||||
func (es *Entries) filter(f func(*Entry) bool) {
|
||||
defer es.checkAndPanic().checkAndPanic()
|
||||
|
||||
@@ -206,6 +214,17 @@ func (es *Entries) filter(f func(*Entry) bool) {
|
||||
*es = (*es)[:i]
|
||||
}
|
||||
|
||||
func (es Entries) findEqual(e *Entry) (*Entry, bool) {
|
||||
i := sort.Search(len(es), func(i int) bool {
|
||||
return !es[i].insensitiveLess(e)
|
||||
})
|
||||
if i < len(es) && es[i].equal(*e) {
|
||||
return &es[i], true
|
||||
} else {
|
||||
return nil, false
|
||||
}
|
||||
}
|
||||
|
||||
func (es Entries) lookup(hostname string) Entries {
|
||||
es.checkAndPanic()
|
||||
|
||||
|
||||
@@ -86,6 +86,21 @@ func TestTombstone(t *testing.T) {
|
||||
Entry{Hostname: "B", Version: 1, Tombstone: 1234},
|
||||
})
|
||||
require.Equal(t, expected, es)
|
||||
|
||||
// Now try a merge including two entries which differ only in tombstone
|
||||
e2 := make(Entries, len(es))
|
||||
copy(e2, es)
|
||||
e2[1].Tombstone = 5555
|
||||
|
||||
diff := es.merge(e2)
|
||||
|
||||
expected2 := l(Entries{
|
||||
Entry{Hostname: "A"},
|
||||
Entry{Hostname: "B", Version: 1, Tombstone: 5555},
|
||||
})
|
||||
require.Equal(t, expected2, es)
|
||||
expectedDiff := l(Entries{Entry{Hostname: "B", Version: 1, Tombstone: 5555}})
|
||||
require.Equal(t, expectedDiff, diff)
|
||||
}
|
||||
|
||||
func TestDelete(t *testing.T) {
|
||||
|
||||
@@ -202,11 +202,31 @@ func (n *Nameserver) receiveGossip(msg []byte) (mesh.GossipData, mesh.GossipData
|
||||
return nil, nil, fmt.Errorf("clock skew of %d detected", delta)
|
||||
}
|
||||
|
||||
// Filter to remove entries from unknown peers, done before we take
|
||||
// the nameserver lock, so we don't have to worry what isKnownPeer locks.
|
||||
gossip.Entries.filter(func(e *Entry) bool {
|
||||
return n.isKnownPeer(e.Origin)
|
||||
})
|
||||
|
||||
n.Lock()
|
||||
defer n.Unlock()
|
||||
|
||||
// Check entries claiming to originate from us against our current data
|
||||
gossip.Entries.filter(func(e *Entry) bool {
|
||||
return n.isKnownPeer(e.Origin)
|
||||
if e.Origin == n.ourName {
|
||||
if ourEntry, ok := n.entries.findEqual(e); ok {
|
||||
if ourEntry.Version < e.Version ||
|
||||
(ourEntry.Version == e.Version && ourEntry.Tombstone != e.Tombstone) {
|
||||
// Take our version of the data, but make the version higher than the incoming
|
||||
nextVersion := e.Version + 1
|
||||
*e = *ourEntry
|
||||
e.Version = nextVersion
|
||||
}
|
||||
} else { // We have no entry matching the one that came in with us as Origin
|
||||
e.tombstone()
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
newEntries := n.entries.merge(gossip.Entries)
|
||||
|
||||
Executable
+31
@@ -0,0 +1,31 @@
|
||||
#! /bin/bash
|
||||
|
||||
. ./config.sh
|
||||
|
||||
start_suite "Check propagation of DNS entries when gossip is delayed"
|
||||
|
||||
weave_on $HOST1 launch-router --no-discovery
|
||||
weave_on $HOST2 launch-router --no-discovery $HOST1
|
||||
weave_on $HOST3 launch-router --no-discovery $HOST2
|
||||
|
||||
start_container $HOST1 --name=c1
|
||||
C1=$(container_ip $HOST1 c1)
|
||||
start_container_with_dns $HOST3 --name=c3
|
||||
|
||||
assert_dns_record $HOST3 c3 c1.weave.local $C1
|
||||
|
||||
# Stall the propagation of gossip, stop weave and kill the container
|
||||
run_on $HOST3 "sudo iptables -A INPUT -s $HOST2 -j DROP"
|
||||
|
||||
weave_on $HOST1 stop-router
|
||||
docker_on $HOST1 rm -f c1
|
||||
|
||||
weave_on $HOST1 launch-router --no-discovery $HOST3
|
||||
|
||||
# Now re-enable gossip
|
||||
run_on $HOST3 "sudo iptables -D INPUT -s $HOST2 -j DROP"
|
||||
|
||||
# Currently failing due to Mesh #28
|
||||
# assert_no_dns_record $HOST3 c3 c1.weave.local
|
||||
|
||||
end_suite
|
||||
Reference in new issue
Block a user