Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    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])
Exemplo n.º 3
0
    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])
Exemplo n.º 4
0
 def _protocol_version_string(self, key):
     version_str = self.features.get(key)
     ptuple = protocol_tuple(version_str)
     return version_string(ptuple)