Allow separate proxy for onions

- new options in network section: onionsocksproxytype,
onionsockshostname and onionsocksport. These allow to separate
connectivity types for onion and non-onion addresses, e.g. connect to
clear nodes over clearnet and onions over tor
- also remove some obsolete imports
This commit is contained in:
Peter Šurda 2018-02-04 21:03:54 +01:00
parent fd1a6c1fa1
commit a646ec4902
Signed by untrusted user: PeterSurda
GPG Key ID: 0C5F50C0B5F37D87
2 changed files with 46 additions and 6 deletions

View File

@ -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:

View File

@ -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")