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)
Beispiel #2
0
 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)
Beispiel #3
0
    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)
Beispiel #4
0
 def _ping_contacts(contacts):
     d = DeferredDict({contact: contact.ping()
                       for contact in contacts},
                      consumeErrors=True)
     d.addErrback(lambda err: err.trap(TimeoutError))
     return d
Beispiel #5
0
    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")