Esempio n. 1
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)
                return

        # update the external ip
        try:
            external_ip = yield from_future(self.upnp.get_external_ip())
            if external_ip == "0.0.0.0":
                log.warning(
                    "upnp doesn't know the external ip address (returned 0.0.0.0), using fallback"
                )
                external_ip = 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)
            elif not self.external_ip:
                log.info("got external ip: %s", external_ip)
            self.external_ip = external_ip
        except (asyncio.TimeoutError, UPnPError):
            pass

        if not self.upnp_redirects:  # setup missing redirects
            try:
                upnp_redirects = yield DeferredDict({
                    "UDP":
                    from_future(
                        self.upnp.get_next_mapping(self._int_dht_node_port,
                                                   "UDP", "LBRY DHT port")),
                    "TCP":
                    from_future(
                        self.upnp.get_next_mapping(self._int_peer_port, "TCP",
                                                   "LBRY peer port"))
                })
                self.upnp_redirects.update(upnp_redirects)
            except (asyncio.TimeoutError, UPnPError):
                self.upnp = None
                return self._maintain_redirects()
        else:  # 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:
                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:
                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 'UDP' in self.upnp_redirects:
                log.debug("upnp redirects are still active")
Esempio n. 2
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")