You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

95 lines
3.0 KiB

# -*- coding: utf-8 -*-
import asyncio
import aiorpcx
class SimpleDeferredMock:
def __init__(self):
self.cb = None
self.errb = None
def addCallback(self, cb):
self.cb = cb
def addErrback(self, errb):
self.errb = errb
def addCallbacks(self, cb, errb):
self.cb = cb
self.errb = errb
class TorClientService:
def __init__(self, factory, timeout, socks5_host, socks5_port, host, port):
self.factory = factory
self.logger = factory.logger
self.timeout = timeout
self.proxy = aiorpcx.SOCKSProxy(
f'{socks5_host}:{socks5_port}', aiorpcx.SOCKS5, None)
self.host = host
self.port = port
self.fail_after_failures = 1
self.transport = None
self.protocol = None
self.connected_deferred = None
self.stop_deferred = None
self.srv_task = None
self.stop_task = None
def whenConnected(self, failAfterFailures=None):
if failAfterFailures:
self.fail_after_failures = failAfterFailures
self.connected_deferred = SimpleDeferredMock()
return self.connected_deferred
async def _proxy_create_conn(self):
self.transport, self.protocol = await self.proxy.create_connection(
self.factory.buildProtocol, self.host, self.port)
async def _start_service(self):
if self.stop_task and not self.stop_task.done():
await self.stop_task
self.stop_task = None
fail_count = 0
while fail_count < self.fail_after_failures:
try:
await asyncio.wait_for(self._proxy_create_conn(),
timeout=self.timeout)
if self.connected_deferred and self.connected_deferred.cb:
self.connected_deferred.cb(self.protocol)
break
except BaseException as e:
self.logger.error(f'_start_service: {repr(e)}')
fail_count += 1
if fail_count < self.fail_after_failures:
continue
if self.connected_deferred and self.connected_deferred.errb:
self.connected_deferred.errb(e)
def startService(self):
self.srv_task = asyncio.create_task(self._start_service())
async def _stop_service(self):
try:
if self.srv_task and not self.srv_task.done():
self.srv_task.cancel()
self.srv_task = None
if self.transport:
self.transport.close()
self.transport = None
self.protocol = None
if self.stop_deferred and self.stop_deferred.cb:
self.stop_deferred.cb(None)
except BaseException as e:
self.logger.error(f'_stop_service: {repr(e)}')
def stopService(self):
self.stop_deferred = SimpleDeferredMock()
self.stop_task = asyncio.create_task(self._stop_service())
return self.stop_deferred