async def on_add_peer(self, features, source_addr): '''Add a peer (but only if the peer resolves to the source).''' if self.env.peer_discovery != self.env.PD_ON: return False if not source_addr: self.logger.info('ignored add_peer request: no source info') return False source = str(source_addr.host) peers = Peer.peers_from_features(features, source) if not peers: self.logger.info('ignored add_peer request: no peers given') return False # Just look at the first peer, require it peer = peers[0] host = peer.host now = time.time() # Rate limit peer adds by domain to one every 10 minutes if peer.ip_address is not None: bucket = 'ip_addr' else: bucket = '.'.join(host.lower().split('.')[-2:]) last = self.recent_peer_adds.get(bucket, 0) self.recent_peer_adds[bucket] = now if last + PEER_ADD_PAUSE >= now: return False if peer.is_tor: permit = self._permit_new_onion_peer(now) reason = 'rate limiting' else: getaddrinfo = asyncio.get_event_loop().getaddrinfo try: infos = await getaddrinfo(host, 80, type=socket.SOCK_STREAM) except socket.gaierror: permit = False reason = 'address resolution failure' else: permit = any(source == info[-1][0] for info in infos) reason = 'source-destination mismatch' if permit: self.logger.info( f'accepted add_peer request from {source} for {host}') await self._note_peers([peer], check_ports=True) else: self.logger.warning(f'rejected add_peer request from {source} ' f'for {host} ({reason})') return permit
async def on_add_peer(self, features, source_info): '''Add a peer (but only if the peer resolves to the source).''' if not source_info: self.logger.info('ignored add_peer request: no source info') return False source = source_info[0] peers = Peer.peers_from_features(features, source) if not peers: self.logger.info('ignored add_peer request: no peers given') return False # Just look at the first peer, require it peer = peers[0] host = peer.host if peer.is_tor: permit, reason = self._permit_new_onion_peer() # check if peer_discovery_tor is enabled and also if sufficient time has passed since we added tor peers (we rate limit tor even if discovery is enabled) else: getaddrinfo = asyncio.get_event_loop().getaddrinfo try: infos = await getaddrinfo(host, 80, type=socket.SOCK_STREAM) except socket.gaierror: permit = False reason = 'address resolution failure' else: permit = any(source == info[-1][0] for info in infos) reason = 'source-destination mismatch' if permit: permit = not any(ip_address(info[-1][0]) in self.session_mgr.banned_ips for info in infos) reason = 'banned IP' if permit: permit = not any(self._dupes_for_peer(info[-1][0]) for info in infos) reason = 'dupe peer' if permit: notok = self.session_mgr.does_peer_match_hostname_ban(peer) if notok: permit = False reason = f'banned hostname suffix: {notok}' if permit: self.logger.info(f'accepted add_peer request from {source} ' f'for {host}') await self._note_peers([peer], check_ports=True) else: self.logger.warning(f'rejected add_peer request from {source} ' f'for {host} ({reason})') return permit
async def on_add_peer(self, features, source_info): '''Add a peer (but only if the peer resolves to the source).''' if not source_info: self.logger.info('ignored add_peer request: no source info') return False source = source_info[0] peers = Peer.peers_from_features(features, source) if not peers: self.logger.info('ignored add_peer request: no peers given') return False # Just look at the first peer, require it peer = peers[0] host = peer.host if peer.is_tor: permit = self.permit_new_onion_peer() reason = 'rate limiting' else: try: infos = await self.loop.getaddrinfo(host, 80, type=socket.SOCK_STREAM) except socket.gaierror: permit = False reason = 'address resolution failure' else: permit = any(source == info[-1][0] for info in infos) reason = 'source-destination mismatch' if permit: self.logger.info('accepted add_peer request from {} for {}'.format( source, host)) self.add_peers([peer], check_ports=True) else: self.logger.warning( 'rejected add_peer request from {} for {} ({})'.format( source, host, reason)) return permit