Fix peer replacement logic
- drop the IP address peer - update the remaining peer with fresh info
This commit is contained in:
parent
2656fd78a4
commit
9f27ea875c
18
lib/peer.py
18
lib/peer.py
@ -94,12 +94,14 @@ class Peer(object):
|
||||
return tuple(int(part) for part in vstr.split('.'))
|
||||
|
||||
def matches(self, peers):
|
||||
'''Return peers whose host matches the given peer's host or IP
|
||||
address. This results in our favouring host names over IP
|
||||
addresses.
|
||||
'''Return peers whose host matches our hostname or IP address.
|
||||
Additionally include all peers whose IP address matches our
|
||||
hostname if that is an IP address.
|
||||
'''
|
||||
candidates = (self.host.lower(), self.ip_addr)
|
||||
return [peer for peer in peers if peer.host.lower() in candidates]
|
||||
return [peer for peer in peers
|
||||
if peer.host.lower() in candidates
|
||||
or peer.ip_addr == self.host]
|
||||
|
||||
def __str__(self):
|
||||
return self.host
|
||||
@ -111,9 +113,13 @@ class Peer(object):
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
self.features = tmp.features
|
||||
self.update_features_from_peer(tmp)
|
||||
|
||||
def update_features_from_peer(self, peer):
|
||||
if peer != self:
|
||||
self.features = peer.features
|
||||
for feature in self.FEATURES:
|
||||
setattr(self, feature, getattr(tmp, feature))
|
||||
setattr(self, feature, getattr(peer, feature))
|
||||
|
||||
def connection_port_pairs(self):
|
||||
'''Return a list of (kind, port) pairs to try when making a
|
||||
|
||||
@ -555,15 +555,20 @@ class PeerManager(util.LoggedClass):
|
||||
how = 'via {} at {}'.format(kind, peer.ip_addr)
|
||||
status = 'verified' if good else 'failed to verify'
|
||||
elapsed = time.time() - peer.last_try
|
||||
self.log_info('{} {} in {:.1f}s'.format(status, how, elapsed))
|
||||
self.log_info('{} {} {} in {:.1f}s'.format(status, peer, how, elapsed))
|
||||
|
||||
if good:
|
||||
peer.try_count = 0
|
||||
peer.source = 'peer'
|
||||
# Remove matching IP addresses
|
||||
for match in peer.matches(self.peers):
|
||||
if match != peer and peer.host == peer.ip_addr:
|
||||
self.peers.remove(match)
|
||||
# At most 2 matches if we're a host name, potentially several if
|
||||
# we're an IP address (several instances can share a NAT).
|
||||
matches = peer.matches(self.peers)
|
||||
for match in matches:
|
||||
if match.ip_address:
|
||||
if len(matches) > 1:
|
||||
self.peers.remove(match)
|
||||
elif peer.host in match.features['hosts']:
|
||||
match.update_features_from_peer(peer)
|
||||
else:
|
||||
self.maybe_forget_peer(peer)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user