Check entries claiming to originate from us against our current data, and override if necessary

This commit is contained in:
Bryan Boreham committed 2016-03-22 12:57:07 +00:00
1 parent 001322751f
commit 010766fe9e
2 files changed
+39 -6

No files matched your search

+18 -2
View File
@@ -105,6 +105,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!")
@@ -182,8 +187,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)
}
@@ -191,6 +195,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()
@@ -205,6 +210,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()
+21 -4
View File
@@ -203,16 +203,33 @@ func (n *Nameserver) receiveGossip(msg []byte) (mesh.GossipData, mesh.GossipData
return nil, nil, fmt.Errorf("clock skew of %d detected", delta)
}
n.Lock()
isKnownPeer := n.isKnownPeer
n.Unlock() // Don't hold the lock over call out to code elsewhere
// 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 isKnownPeer(e.Origin)
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 {
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)
if len(newEntries) > 0 {
return &GossipData{Entries: newEntries, Timestamp: now()}, &gossip, nil