Commit 095da553 authored by Steven Allen's avatar Steven Allen

fix: make processing signed address records atomic

Previously, two calls to ConsumePeerRecord could interleave and cause us to keep
_old_ addresses with a _new_ record.
parent 56ebb42d
...@@ -159,7 +159,7 @@ func (mab *memoryAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Du ...@@ -159,7 +159,7 @@ func (mab *memoryAddrBook) AddAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Du
// if peerRec != nil { // if peerRec != nil {
// return // return
// } // }
mab.addAddrs(p, addrs, ttl, false) mab.addAddrs(p, addrs, ttl)
} }
// ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in // ConsumePeerRecord adds addresses from a signed peer.PeerRecord (contained in
...@@ -181,35 +181,38 @@ func (mab *memoryAddrBook) ConsumePeerRecord(recordEnvelope *record.Envelope, tt ...@@ -181,35 +181,38 @@ func (mab *memoryAddrBook) ConsumePeerRecord(recordEnvelope *record.Envelope, tt
// ensure seq is greater than, or equal to, the last received // ensure seq is greater than, or equal to, the last received
s := mab.segments.get(rec.PeerID) s := mab.segments.get(rec.PeerID)
s.Lock() s.Lock()
defer s.Unlock()
lastState, found := s.signedPeerRecords[rec.PeerID] lastState, found := s.signedPeerRecords[rec.PeerID]
if found && lastState.Seq > rec.Seq { if found && lastState.Seq > rec.Seq {
s.Unlock()
return false, nil return false, nil
} }
s.signedPeerRecords[rec.PeerID] = &peerRecordState{ s.signedPeerRecords[rec.PeerID] = &peerRecordState{
Envelope: recordEnvelope, Envelope: recordEnvelope,
Seq: rec.Seq, Seq: rec.Seq,
} }
s.Unlock() // need to release the lock, since addAddrs will try to take it mab.addAddrsUnlocked(s, rec.PeerID, rec.Addrs, ttl, true)
mab.addAddrs(rec.PeerID, rec.Addrs, ttl, true)
return true, nil return true, nil
} }
func (mab *memoryAddrBook) addAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration, signed bool) { func (mab *memoryAddrBook) addAddrs(p peer.ID, addrs []ma.Multiaddr, ttl time.Duration) {
if err := p.Validate(); err != nil { if err := p.Validate(); err != nil {
log.Warningf("tried to set addrs for invalid peer ID %s: %s", p, err) log.Warningf("tried to set addrs for invalid peer ID %s: %s", p, err)
return return
} }
s := mab.segments.get(p)
s.Lock()
defer s.Unlock()
mab.addAddrsUnlocked(s, p, addrs, ttl, false)
}
func (mab *memoryAddrBook) addAddrsUnlocked(s *addrSegment, p peer.ID, addrs []ma.Multiaddr, ttl time.Duration, signed bool) {
// if ttl is zero, exit. nothing to do. // if ttl is zero, exit. nothing to do.
if ttl <= 0 { if ttl <= 0 {
return return
} }
s := mab.segments.get(p)
s.Lock()
defer s.Unlock()
amap, ok := s.addrs[p] amap, ok := s.addrs[p]
if !ok { if !ok {
amap = make(map[string]*expiringAddr) amap = make(map[string]*expiringAddr)
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment