async def _verify_peer(self, session, peer): if not peer.is_tor: address = session.peer_address() if address: peer.ip_addr = address[0] # server.version goes first message = 'server.version' result = await session.send_request(message, self.server_version_args) assert_good(message, result, list) # Protocol version 1.1 returns a pair with the version first if len(result) != 2 or not all(isinstance(x, str) for x in result): raise BadPeerError(f'bad server.version result: {result}') server_version, protocol_version = result peer.server_version = server_version peer.features['server_version'] = server_version ptuple = protocol_tuple(protocol_version) # FIXME: Make concurrent preserving the exception await self._send_headers_subscribe(session, peer, ptuple) await self._send_server_features(session, peer) await self._send_peers_subscribe(session, peer)
async def _verify_peer(self, session, peer): if self._is_blacklisted(peer.host): raise BadPeerError('blacklisted') if not peer.is_tor: address = session.peer_address() if address: peer.ip_addr = address[0] # server.version goes first message = 'server.version' result = await session.send_request(message, self.server_version_args) assert_good(message, result, list) # Protocol version 1.1 returns a pair with the version first if len(result) != 2 or not all(isinstance(x, str) for x in result): raise BadPeerError(f'bad server.version result: {result}') server_version, protocol_version = result peer.server_version = server_version peer.features['server_version'] = server_version ptuple = protocol_tuple(protocol_version) async with TaskGroup() as g: await g.spawn(self._send_headers_subscribe(session, peer, ptuple)) await g.spawn(self._send_server_features(session, peer)) peers_task = await g.spawn(self._send_peers_subscribe (session, peer)) # Process reported peers if remote peer is good peers = peers_task.result() await self._note_peers(peers) features = self._features_to_register(peer, peers) if features: self.logger.info(f'registering ourself with {peer}') # We only care to wait for the response await session.send_request('server.add_peer', [features])
async def _verify_peer(self, session, peer): # store IP address for peer if not peer.is_tor: address = session.peer_address() if address: peer.ip_addr = address[0] if self._is_blacklisted(peer): raise BadPeerError('blacklisted') # Bucket good recent peers; forbid many servers from similar IPs # FIXME there's a race here, when verifying multiple peers # that belong to the same bucket ~simultaneously recent_peers = self._get_recent_good_peers() if peer in recent_peers: recent_peers.remove(peer) onion_peers = [] buckets = defaultdict(list) for other_peer in recent_peers: if other_peer.is_tor: onion_peers.append(other_peer) else: buckets[other_peer.bucket_for_internal_purposes()].append(other_peer) if peer.is_tor: # keep number of onion peers below half of all peers, # but up to 100 is OK regardless if len(onion_peers) > len(recent_peers) // 2 >= 100: raise BadPeerError('too many onion peers already') else: bucket = peer.bucket_for_internal_purposes() if len(buckets[bucket]) > 0: raise BadPeerError(f'too many peers already in bucket {bucket}') # server.version goes first message = 'server.version' result = await session.send_request(message, self.server_version_args) assert_good(message, result, list) # Protocol version 1.1 returns a pair with the version first if len(result) != 2 or not all(isinstance(x, str) for x in result): raise BadPeerError(f'bad server.version result: {result}') server_version, protocol_version = result peer.server_version = server_version peer.features['server_version'] = server_version ptuple = protocol_tuple(protocol_version) async with TaskGroup() as g: await g.spawn(self._send_headers_subscribe(session, peer, ptuple)) await g.spawn(self._send_server_features(session, peer)) peers_task = await g.spawn(self._send_peers_subscribe (session, peer)) # Process reported peers if remote peer is good peers = peers_task.result() await self._note_peers(peers) features = self._features_to_register(peer, peers) if features: self.logger.info(f'registering ourself with {peer}') # We only care to wait for the response await session.send_request('server.add_peer', [features])
def _protocol_version_string(self, key): version_str = self.features.get(key) ptuple = protocol_tuple(version_str) return version_string(ptuple)