Merge branch 'upnp-fixes'

This commit is contained in:
Jack Robison 2018-08-07 19:25:06 -04:00
commit 74b49fe69f
No known key found for this signature in database
GPG key ID: DF25C68FE0239BB2
6 changed files with 31 additions and 34 deletions

View file

@ -16,6 +16,8 @@ at anytime.
* loggly error reporting not following `share_usage_data` * loggly error reporting not following `share_usage_data`
* improper error handling when data is not valid JSON * improper error handling when data is not valid JSON
* edge cases of http mirrored download of blobs * edge cases of http mirrored download of blobs
* ports with upnp redirects not showing the correct external port in log messages ( https://github.com/lbryio/lbry/issues/1338 )
* miniupnpc fallback issue in txupnp ( https://github.com/lbryio/lbry/issues/1341 )
### Deprecated ### Deprecated
* automatic claim renew, this is no longer needed * automatic claim renew, this is no longer needed

View file

@ -375,8 +375,8 @@ class DHTComponent(Component):
Component.__init__(self, component_manager) Component.__init__(self, component_manager)
self.dht_node = None self.dht_node = None
self.upnp_component = None self.upnp_component = None
self.udp_port = None self.external_udp_port = None
self.peer_port = None self.external_peer_port = None
@property @property
def component(self): def component(self):
@ -391,16 +391,18 @@ class DHTComponent(Component):
@defer.inlineCallbacks @defer.inlineCallbacks
def start(self): def start(self):
self.upnp_component = self.component_manager.get_component(UPNP_COMPONENT) self.upnp_component = self.component_manager.get_component(UPNP_COMPONENT)
self.peer_port, self.udp_port = self.upnp_component.get_redirects() self.external_peer_port = self.upnp_component.upnp_redirects.get("TCP", GCS("peer_port"))
self.external_udp_port = self.upnp_component.upnp_redirects.get("UDP", GCS("dht_node_port"))
node_id = CS.get_node_id() node_id = CS.get_node_id()
if node_id is None: if node_id is None:
node_id = generate_id() node_id = generate_id()
self.dht_node = node.Node( self.dht_node = node.Node(
node_id=node_id, node_id=node_id,
udpPort=self.udp_port, udpPort=GCS('dht_node_port'),
externalIP=CS.get_external_ip(), externalUDPPort=self.external_udp_port,
peerPort=self.peer_port externalIP=self.upnp_component.external_ip,
peerPort=self.external_peer_port
) )
self.dht_node.start_listening() self.dht_node.start_listening()
@ -573,7 +575,8 @@ class PeerProtocolServerComponent(Component):
@defer.inlineCallbacks @defer.inlineCallbacks
def start(self): def start(self):
wallet = self.component_manager.get_component(WALLET_COMPONENT) wallet = self.component_manager.get_component(WALLET_COMPONENT)
peer_port = self.component_manager.get_component(UPNP_COMPONENT).get_redirects()[0] upnp = self.component_manager.get_component(UPNP_COMPONENT)
peer_port = GCS('peer_port')
query_handlers = { query_handlers = {
handler.get_primary_query_identifier(): handler for handler in [ handler.get_primary_query_identifier(): handler for handler in [
BlobRequestHandlerFactory( BlobRequestHandlerFactory(
@ -591,7 +594,8 @@ class PeerProtocolServerComponent(Component):
) )
try: try:
log.info("Peer protocol listening on TCP %d", peer_port) log.info("Peer protocol listening on TCP %i (ext port %i)", peer_port,
upnp.upnp_redirects.get("TCP", peer_port))
self.lbry_server_port = yield reactor.listenTCP(peer_port, server_factory) self.lbry_server_port = yield reactor.listenTCP(peer_port, server_factory)
except error.CannotListenError as e: except error.CannotListenError as e:
import traceback import traceback
@ -648,51 +652,41 @@ class UPnPComponent(Component):
def __init__(self, component_manager): def __init__(self, component_manager):
Component.__init__(self, component_manager) Component.__init__(self, component_manager)
self._default_peer_port = GCS('peer_port') self._int_peer_port = GCS('peer_port')
self._default_dht_node_port = GCS('dht_node_port') self._int_dht_node_port = GCS('dht_node_port')
self.use_upnp = GCS('use_upnp') self.use_upnp = GCS('use_upnp')
self.external_ip = None self.upnp = None
self.upnp = UPnP(self.component_manager.reactor, try_miniupnpc_fallback=True)
self.upnp_redirects = {} self.upnp_redirects = {}
self.external_ip = None
@property @property
def component(self): def component(self):
return self return self
def get_redirects(self):
if not self.use_upnp or not self.upnp_redirects:
return self._default_peer_port, self._default_dht_node_port
return self.upnp_redirects["TCP"], self.upnp_redirects["UDP"]
@defer.inlineCallbacks @defer.inlineCallbacks
def _setup_redirects(self): def _setup_redirects(self):
self.external_ip = yield self.upnp.get_external_ip()
upnp_redirects = yield DeferredDict({ upnp_redirects = yield DeferredDict({
"UDP": self.upnp.get_next_mapping(self._default_dht_node_port, "UDP", "LBRY DHT port"), "UDP": self.upnp.get_next_mapping(self._int_dht_node_port, "UDP", "LBRY DHT port"),
"TCP": self.upnp.get_next_mapping(self._default_peer_port, "TCP", "LBRY peer port") "TCP": self.upnp.get_next_mapping(self._int_peer_port, "TCP", "LBRY peer port")
}) })
self.upnp_redirects.update(upnp_redirects) self.upnp_redirects.update(upnp_redirects)
@defer.inlineCallbacks @defer.inlineCallbacks
def start(self): def start(self):
if not self.use_upnp: if not self.use_upnp:
self.external_ip = CS.get_external_ip()
return return
log.debug("In _try_upnp") self.upnp = UPnP(self.component_manager.reactor, try_miniupnpc_fallback=True)
found = yield self.upnp.discover() found = yield self.upnp.discover()
if found and not self.upnp.miniupnpc_runner: if found and not self.upnp.miniupnpc_runner:
log.info("set up redirects using txupnp") log.info("set up redirects using txupnp")
elif found and self.upnp.miniupnpc_runner: elif found and self.upnp.miniupnpc_runner:
log.warning("failed to set up redirect with txupnp, miniupnpc fallback was successful") log.warning("failed to set up redirect with txupnp, miniupnpc fallback was successful")
if found: if found:
try: self.external_ip = yield self.upnp.get_external_ip()
yield self._setup_redirects()
except Exception as err:
if not self.upnp.miniupnpc_runner:
started_fallback = yield self.upnp.start_miniupnpc_fallback()
if started_fallback:
yield self._setup_redirects() yield self._setup_redirects()
else: else:
log.warning("failed to set up upnp redirects") self.external_ip = CS.get_external_ip()
def stop(self): def stop(self):
return defer.DeferredList( return defer.DeferredList(

View file

@ -3022,7 +3022,7 @@ class Daemon(AuthJSONRPCServer):
'head_blob_hash': None, 'head_blob_hash': None,
'head_blob_availability': {}, 'head_blob_availability': {},
'use_upnp': conf.settings['use_upnp'], 'use_upnp': conf.settings['use_upnp'],
'upnp_redirect_is_set': len(self.upnp.get_redirects()) > 0, 'upnp_redirect_is_set': len(self.upnp.upnp_redirects),
'error': None 'error': None
} }

View file

@ -99,7 +99,7 @@ class Node(MockKademliaHelper):
routingTableClass=None, networkProtocol=None, routingTableClass=None, networkProtocol=None,
externalIP=None, peerPort=3333, listenUDP=None, externalIP=None, peerPort=3333, listenUDP=None,
callLater=None, resolve=None, clock=None, peer_finder=None, callLater=None, resolve=None, clock=None, peer_finder=None,
peer_manager=None, interface=''): peer_manager=None, interface='', externalUDPPort=None):
""" """
@param dataStore: The data store to use. This must be class inheriting @param dataStore: The data store to use. This must be class inheriting
from the C{DataStore} interface (or providing the from the C{DataStore} interface (or providing the
@ -149,6 +149,7 @@ class Node(MockKademliaHelper):
self.old_token_secret = None self.old_token_secret = None
self.externalIP = externalIP self.externalIP = externalIP
self.peerPort = peerPort self.peerPort = peerPort
self.externalUDPPort = externalUDPPort or self.port
self._dataStore = dataStore or datastore.DictDataStore(self.clock.seconds) self._dataStore = dataStore or datastore.DictDataStore(self.clock.seconds)
self.peer_manager = peer_manager or PeerManager() self.peer_manager = peer_manager or PeerManager()
self.peer_finder = peer_finder or DHTPeerFinder(self, self.peer_manager) self.peer_finder = peer_finder or DHTPeerFinder(self, self.peer_manager)

View file

@ -199,7 +199,7 @@ class KademliaProtocol(protocol.DatagramProtocol):
return df return df
def startProtocol(self): def startProtocol(self):
log.info("DHT listening on UDP %s:%i", self._node.externalIP, self._node.port) log.info("DHT listening on UDP %i (ext port %i)", self._node.port, self._node.externalUDPPort)
if self._listening.called: if self._listening.called:
self._listening = defer.Deferred() self._listening = defer.Deferred()
self._listening.callback(True) self._listening.callback(True)

View file

@ -24,7 +24,7 @@ requires = [
'lbryschema==0.0.16', 'lbryschema==0.0.16',
'lbryum==3.2.3', 'lbryum==3.2.3',
'miniupnpc', 'miniupnpc',
'txupnp==0.0.1a6', 'txupnp==0.0.1a9',
'pyyaml', 'pyyaml',
'requests', 'requests',
'txJSON-RPC', 'txJSON-RPC',