2016-12-01 16:48:04 +01:00
|
|
|
import socket
|
|
|
|
|
2017-06-10 10:13:49 +02:00
|
|
|
import state
|
|
|
|
|
2017-01-10 21:22:22 +01:00
|
|
|
from advanceddispatcher import AdvancedDispatcher
|
2017-03-10 23:11:57 +01:00
|
|
|
import asyncore_pollchoose as asyncore
|
2017-06-10 10:13:49 +02:00
|
|
|
import network.connectionpool
|
2017-03-10 23:11:57 +01:00
|
|
|
|
|
|
|
class ProxyError(Exception): pass
|
|
|
|
class GeneralProxyError(ProxyError): pass
|
2016-12-01 16:48:04 +01:00
|
|
|
|
2017-01-10 21:22:22 +01:00
|
|
|
class Proxy(AdvancedDispatcher):
|
2016-12-01 16:48:04 +01:00
|
|
|
# these are global, and if you change config during runtime, all active/new
|
|
|
|
# instances should change too
|
2017-03-10 23:11:57 +01:00
|
|
|
_proxy = ("127.0.0.1", 9050)
|
2016-12-01 16:48:04 +01:00
|
|
|
_auth = None
|
|
|
|
_remote_dns = True
|
|
|
|
|
|
|
|
@property
|
|
|
|
def proxy(self):
|
|
|
|
return self.__class__._proxy
|
|
|
|
|
|
|
|
@proxy.setter
|
|
|
|
def proxy(self, address):
|
2017-03-10 23:11:57 +01:00
|
|
|
if type(address) != tuple or (len(address) < 2) or (type(str(address[0])) != type('')) or (type(address[1]) != int):
|
|
|
|
raise ValueError
|
2016-12-01 16:48:04 +01:00
|
|
|
self.__class__._proxy = address
|
|
|
|
|
|
|
|
@property
|
|
|
|
def auth(self):
|
|
|
|
return self.__class__._auth
|
|
|
|
|
|
|
|
@auth.setter
|
|
|
|
def auth(self, authTuple):
|
|
|
|
self.__class__._auth = authTuple
|
|
|
|
|
2017-03-10 23:11:57 +01:00
|
|
|
def __init__(self, address):
|
2017-06-10 10:13:49 +02:00
|
|
|
if not isinstance(address, state.Peer):
|
2017-03-10 23:11:57 +01:00
|
|
|
raise ValueError
|
|
|
|
AdvancedDispatcher.__init__(self)
|
2016-12-01 16:48:04 +01:00
|
|
|
self.destination = address
|
2017-06-10 10:13:49 +02:00
|
|
|
self.isOutbound = True
|
2016-12-01 16:48:04 +01:00
|
|
|
self.create_socket(socket.AF_INET, socket.SOCK_STREAM)
|
|
|
|
self.connect(self.proxy)
|
2017-03-10 23:11:57 +01:00
|
|
|
print "connecting in background to %s:%i" % (self.proxy[0], self.proxy[1])
|
2017-06-10 10:13:49 +02:00
|
|
|
|
|
|
|
def handle_connect(self):
|
|
|
|
try:
|
|
|
|
AdvancedDispatcher.handle_connect(self)
|
|
|
|
except socket.error as e:
|
|
|
|
if e.errno in asyncore._DISCONNECTED:
|
|
|
|
logger.debug("%s:%i: Connection failed: %s" % (self.destination.host, self.destination.port, str(e)))
|
|
|
|
return
|
|
|
|
|
|
|
|
def state_proxy_handshake_done(self):
|
|
|
|
self.writeQueue.put(protocol.assembleVersionMessage(self.destination.host, self.destination.port, network.connectionpool.BMConnectionPool().streams, False))
|
|
|
|
self.connectedAt = time.time()
|
|
|
|
return False
|
|
|
|
|