def _download_and_get_retry_delay(self): if self.blob_hashes and self.servers: if self.sd_hashes: log.debug("trying to download stream from mirror (sd %s)", self.sd_hashes[0][:8]) else: log.debug("trying to download %i blobs from mirror", len(self.blob_hashes)) blobs = yield DeferredDict({ blob_hash: self.blob_manager.get_blob(blob_hash) for blob_hash in self.blob_hashes }) self.deferreds = [ self.download_blob(blobs[blob_hash]) for blob_hash in self.blob_hashes ] yield defer.DeferredList(self.deferreds) if self.retry and self.missing_blob_hashes: if not self.downloaded_blob_hashes: defer.returnValue(self.long_delay) if len(self.missing_blob_hashes) < self.last_missing: self.last_missing = len(self.missing_blob_hashes) defer.returnValue(self.short_delay) if self.retry and self.last_missing and len( self.missing_blob_hashes) == self.last_missing: defer.returnValue(self.long_delay) defer.returnValue(None)
def _setup_redirects(self): d = {} if PEER_PROTOCOL_SERVER_COMPONENT not in self.component_manager.skip_components: d["TCP"] = from_future( self.upnp.get_next_mapping(self._int_peer_port, "TCP", "LBRY peer port")) if DHT_COMPONENT not in self.component_manager.skip_components: d["UDP"] = from_future( self.upnp.get_next_mapping(self._int_dht_node_port, "UDP", "LBRY DHT port")) upnp_redirects = yield DeferredDict(d) self.upnp_redirects.update(upnp_redirects)
def announceHaveBlob(self, blob_hash): contacts = yield self.iterativeFindNode(blob_hash) if not self.externalIP: raise Exception("Cannot determine external IP: %s" % self.externalIP) stored_to = yield DeferredDict({ contact: self.storeToContact(blob_hash, contact) for contact in contacts }) contacted_node_ids = [ binascii.hexlify(contact.id) for contact in stored_to.keys() if stored_to[contact] ] log.debug("Stored %s to %i of %i attempted peers", binascii.hexlify(blob_hash), len(contacted_node_ids), len(contacts)) defer.returnValue(contacted_node_ids)
def _ping_contacts(contacts): d = DeferredDict({contact: contact.ping() for contact in contacts}, consumeErrors=True) d.addErrback(lambda err: err.trap(TimeoutError)) return d
def _maintain_redirects(self): # setup the gateway if necessary if not self.upnp: try: self.upnp = yield from_future(UPnP.discover()) log.info("found upnp gateway: %s", self.upnp.gateway.manufacturer_string) except Exception as err: log.warning("upnp discovery failed: %s", err) self.upnp = None # update the external ip external_ip = None if self.upnp: try: external_ip = yield from_future(self.upnp.get_external_ip()) if external_ip != "0.0.0.0" and not self.external_ip: log.info("got external ip from UPnP: %s", external_ip) except (asyncio.TimeoutError, UPnPError): pass if external_ip == "0.0.0.0" or not external_ip: log.warning( "unable to get external ip from UPnP, checking lbry.io fallback" ) external_ip = yield CS.get_external_ip() if self.external_ip and self.external_ip != external_ip: log.info("external ip changed from %s to %s", self.external_ip, external_ip) self.external_ip = external_ip assert self.external_ip is not None # TODO: handle going/starting offline if not self.upnp_redirects and self.upnp: # setup missing redirects try: log.info("add UPnP port mappings") d = {} if PEER_PROTOCOL_SERVER_COMPONENT not in self.component_manager.skip_components: d["TCP"] = from_future( self.upnp.get_next_mapping(self._int_peer_port, "TCP", "LBRY peer port")) if DHT_COMPONENT not in self.component_manager.skip_components: d["UDP"] = from_future( self.upnp.get_next_mapping(self._int_dht_node_port, "UDP", "LBRY DHT port")) upnp_redirects = yield DeferredDict(d) log.info("set up redirects: %s", upnp_redirects) self.upnp_redirects.update(upnp_redirects) except (asyncio.TimeoutError, UPnPError): self.upnp = None return self._maintain_redirects() elif self.upnp: # check existing redirects are still active found = set() mappings = yield from_future(self.upnp.get_redirects()) for mapping in mappings: proto = mapping['NewProtocol'] if proto in self.upnp_redirects and mapping[ 'NewExternalPort'] == self.upnp_redirects[proto]: if mapping['NewInternalClient'] == self.upnp.lan_address: found.add(proto) if 'UDP' not in found and DHT_COMPONENT not in self.component_manager.skip_components: try: udp_port = yield from_future( self.upnp.get_next_mapping(self._int_dht_node_port, "UDP", "LBRY DHT port")) self.upnp_redirects['UDP'] = udp_port log.info("refreshed upnp redirect for dht port: %i", udp_port) except (asyncio.TimeoutError, UPnPError): del self.upnp_redirects['UDP'] if 'TCP' not in found and PEER_PROTOCOL_SERVER_COMPONENT not in self.component_manager.skip_components: try: tcp_port = yield from_future( self.upnp.get_next_mapping(self._int_peer_port, "TCP", "LBRY peer port")) self.upnp_redirects['TCP'] = tcp_port log.info("refreshed upnp redirect for peer port: %i", tcp_port) except (asyncio.TimeoutError, UPnPError): del self.upnp_redirects['TCP'] if ('TCP' in self.upnp_redirects and PEER_PROTOCOL_SERVER_COMPONENT not in self.component_manager.skip_components) and ( 'UDP' in self.upnp_redirects and DHT_COMPONENT not in self.component_manager.skip_components): if self.upnp_redirects: log.debug("upnp redirects are still active")