Commit 096a2c83 authored by Steven Allen's avatar Steven Allen
Browse files

fix peerstore apocalypse redux

This commit prevents us from repeatedly extending the lifetimes of all observed
addresses if a peer keeps on reconnecting.

It also fixes two race conditions:

1. We may end up processing a disconnect after a re-connect and may
accidentally give the addresses associated with that peer a
RecentlyConnectedAddrTTL instead of a ConnectedAddrTTL.

2. We may end up processing a connect after the associated disconnect storing
the associated peer addresses indefinitely.
parent 64afdfef
...@@ -50,6 +50,8 @@ type IDService struct { ...@@ -50,6 +50,8 @@ type IDService struct {
currid map[inet.Conn]chan struct{} currid map[inet.Conn]chan struct{}
currmu sync.RWMutex currmu sync.RWMutex
addrMu sync.Mutex
// our own observed addresses. // our own observed addresses.
// TODO: instead of expiring, remove these when we disconnect // TODO: instead of expiring, remove these when we disconnect
observedAddrs ObservedAddrSet observedAddrs ObservedAddrSet
...@@ -220,9 +222,17 @@ func (ids *IDService) consumeMessage(mes *pb.Identify, c inet.Conn) { ...@@ -220,9 +222,17 @@ func (ids *IDService) consumeMessage(mes *pb.Identify, c inet.Conn) {
lmaddrs = append(lmaddrs, c.RemoteMultiaddr()) lmaddrs = append(lmaddrs, c.RemoteMultiaddr())
} }
// update our peerstore with the addresses. here, we SET the addresses, clearing old ones. // Extend the TTLs on the known (probably) good addresses.
// We are receiving from the peer itself. this is current address ground truth. // Taking the lock ensures that we don't concurrently process a disconnect.
ids.Host.Peerstore().SetAddrs(p, lmaddrs, pstore.ConnectedAddrTTL) ids.addrMu.Lock()
switch ids.Host.Network().Connectedness(p) {
case inet.Connected:
ids.Host.Peerstore().AddAddrs(p, lmaddrs, pstore.ConnectedAddrTTL)
default:
ids.Host.Peerstore().AddAddrs(p, lmaddrs, pstore.RecentlyConnectedAddrTTL)
}
ids.addrMu.Unlock()
log.Debugf("%s received listen addrs for %s: %s", c.LocalPeer(), c.RemotePeer(), lmaddrs) log.Debugf("%s received listen addrs for %s: %s", c.LocalPeer(), c.RemotePeer(), lmaddrs)
// get protocol versions // get protocol versions
...@@ -449,9 +459,14 @@ func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) { ...@@ -449,9 +459,14 @@ func (nn *netNotifiee) Connected(n inet.Network, v inet.Conn) {
func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) { func (nn *netNotifiee) Disconnected(n inet.Network, v inet.Conn) {
// undo the setting of addresses to peer.ConnectedAddrTTL we did // undo the setting of addresses to peer.ConnectedAddrTTL we did
ids := nn.IDService() ids := nn.IDService()
ps := ids.Host.Peerstore() ids.addrMu.Lock()
addrs := ps.Addrs(v.RemotePeer()) defer ids.addrMu.Unlock()
ps.SetAddrs(v.RemotePeer(), addrs, pstore.RecentlyConnectedAddrTTL)
if ids.Host.Network().Connectedness(v.RemotePeer()) != inet.Connected {
// Last disconnect.
ps := ids.Host.Peerstore()
ps.UpdateAddrs(v.RemotePeer(), pstore.ConnectedAddrTTL, pstore.RecentlyConnectedAddrTTL)
}
} }
func (nn *netNotifiee) OpenedStream(n inet.Network, v inet.Stream) {} func (nn *netNotifiee) OpenedStream(n inet.Network, v inet.Stream) {}
......
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