diff --git a/src/network/connectionpool.py b/src/network/connectionpool.py index 2c3b5054..9b91386e 100644 --- a/src/network/connectionpool.py +++ b/src/network/connectionpool.py @@ -1,3 +1,4 @@ +from ConfigParser import NoOptionError, NoSectionError import errno import socket import time @@ -8,8 +9,6 @@ from bmconfigparser import BMConfigParser from debug import logger import helper_bootstrap from network.proxy import Proxy -from network.bmproto import BMProto -from network.dandelion import Dandelion from network.tcp import TCPServer, Socks5BMConnection, Socks4aBMConnection, TCPConnection from network.udp import UDPSocket from network.connectionchooser import chooseConnection @@ -143,6 +142,15 @@ class BMConnectionPool(object): self.bootstrapped = True Proxy.proxy = (BMConfigParser().safeGet("bitmessagesettings", "sockshostname"), BMConfigParser().safeGetInt("bitmessagesettings", "socksport")) + # TODO AUTH + # TODO reset based on GUI settings changes + try: + if not BMConfigParser().get("network", "onionsocksproxytype").beginswith("SOCKS"): + raise NoOptionError + Proxy.onionproxy = (BMConfigParser().get("network", "onionsockshostname"), + BMConfigParser().getint("network", "onionsocksport")) + except (NoOptionError, NoSectionError): + Proxy.onionproxy = None established = sum(1 for c in self.outboundConnections.values() if (c.connected and c.fullyEstablished)) pending = len(self.outboundConnections) - established if established < BMConfigParser().safeGetInt("bitmessagesettings", "maxoutboundconnections"): @@ -166,15 +174,23 @@ class BMConnectionPool(object): # if chosen.host == c.destination.host: # continue try: - if (BMConfigParser().safeGet("bitmessagesettings", "socksproxytype") == "SOCKS5"): + if chosen.host.endswith(".onion") and Proxy.onionproxy is not None: + if BMConfigParser().get("network", "onionsocksproxytype") == "SOCKS5": + self.addConnection(Socks5BMConnection(chosen)) + elif BMConfigParser().get("network", "onionsocksproxytype") == "SOCKS4a": + self.addConnection(Socks4aBMConnection(chosen)) + elif BMConfigParser().safeGet("bitmessagesettings", "socksproxytype") == "SOCKS5": self.addConnection(Socks5BMConnection(chosen)) - elif (BMConfigParser().safeGet("bitmessagesettings", "socksproxytype") == "SOCKS4a"): + elif BMConfigParser().safeGet("bitmessagesettings", "socksproxytype") == "SOCKS4a": self.addConnection(Socks4aBMConnection(chosen)) - elif not chosen.host.endswith(".onion"): + else: self.addConnection(TCPConnection(chosen)) except socket.error as e: if e.errno == errno.ENETUNREACH: continue + except (NoSectionError, NoOptionError): + # shouldn't happen + pass self.lastSpawned = time.time() else: diff --git a/src/network/proxy.py b/src/network/proxy.py index 96930c18..43298f63 100644 --- a/src/network/proxy.py +++ b/src/network/proxy.py @@ -37,6 +37,8 @@ class Proxy(AdvancedDispatcher): # instances should change too _proxy = ("127.0.0.1", 9050) _auth = None + _onion_proxy = None + _onion_auth = None _remote_dns = True @property @@ -58,6 +60,25 @@ class Proxy(AdvancedDispatcher): def auth(self, authTuple): self.__class__._auth = authTuple + @property + def onion_proxy(self): + return self.__class__._onion_proxy + + @onion_proxy.setter + def onion_proxy(self, address): + if address is not None and (not isinstance(address, tuple) or (len(address) < 2) or \ + (not isinstance(address[0], str) or not isinstance(address[1], int))): + raise ValueError + self.__class__._onion_proxy = address + + @property + def onion_auth(self): + return self.__class__._onion_auth + + @onion_auth.setter + def onion_auth(self, authTuple): + self.__class__._onion_auth = authTuple + def __init__(self, address): if not isinstance(address, state.Peer): raise ValueError @@ -66,7 +87,10 @@ class Proxy(AdvancedDispatcher): self.isOutbound = True self.fullyEstablished = False self.create_socket(socket.AF_INET, socket.SOCK_STREAM) - self.connect(self.proxy) + if address.host.endswith(".onion") and self.onion_proxy is not None: + self.connect(self.onion_proxy) + else: + self.connect(self.proxy) def handle_connect(self): self.set_state("init")