mirror of
https://github.com/libp2p/go-libp2p.git
synced 2025-09-27 04:26:41 +08:00
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.
This commit is contained in:
@@ -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) {
|
|||||||
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) {
|
|||||||
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) {}
|
||||||
|
Reference in New Issue
Block a user