diff --git a/onionr/communicator2.py b/onionr/communicator2.py index 00e80e13..3cf69513 100755 --- a/onionr/communicator2.py +++ b/onionr/communicator2.py @@ -108,7 +108,8 @@ class OnionrCommunicatorDaemon: cleanupTimer.count = (cleanupTimer.frequency - 60) announceTimer.count = (cleanupTimer.frequency - 60) - self.socketServer = onionrsockets.OnionrSocketServer(self._core) + self.socketServer = threading.Thread(target=onionrsockets.OnionrSocketServer, args=(self._core,)) + self.socketServer.start() self.socketClient = onionrsockets.OnionrSocketClient(self._core) # Main daemon loop, mainly for calling timers, don't do any complex operations here to avoid locking @@ -124,6 +125,7 @@ class OnionrCommunicatorDaemon: pass logger.info('Goodbye.') + self._core.killSockets = True self._core._utils.localCommand('shutdown') # shutdown the api time.sleep(0.5) @@ -473,9 +475,8 @@ class OnionrCommunicatorDaemon: elif cmd[0] == 'startSocket': # Create our own socket server socketInfo = json.loads(cmd[1]) - peer = socketInfo['peer'] - reason = socketInfo['reason'] - threading.Thread(target=self.socketServer.addSocket, args=(peer, reason)).start() + socketInfo['id'] = uuid.uuid4() + self._core.startSocket = socketInfo elif cmd[0] == 'addSocket': # Socket server was created for us socketInfo = json.loads(cmd[1]) diff --git a/onionr/core.py b/onionr/core.py index f6cb88b6..17036e30 100644 --- a/onionr/core.py +++ b/onionr/core.py @@ -50,6 +50,9 @@ class Core: self.dbCreate = dbcreator.DBCreator(self) self.forwardKeysFile = 'data/forward-keys.db' + self.killSockets = False + self.startSocket = {} + self.usageFile = 'data/disk-usage.txt' self.config = config diff --git a/onionr/onionr.py b/onionr/onionr.py index c1c07628..593055ef 100755 --- a/onionr/onionr.py +++ b/onionr/onionr.py @@ -271,8 +271,12 @@ class Onionr: ''' def startChat(self): - data = json.dumps({'peer': sys.argv[2], 'reason': 'chat'}) - self.onionrCore.daemonQueueAdd('startSocket', data) + try: + data = json.dumps({'peer': sys.argv[2], 'reason': 'chat'}) + except IndexError: + logger.error('Must specify peer to chat with.') + else: + self.onionrCore.daemonQueueAdd('startSocket', data) def getCommands(self): return self.cmds diff --git a/onionr/onionrsockets.py b/onionr/onionrsockets.py index 735b22c6..4d16ea7b 100644 --- a/onionr/onionrsockets.py +++ b/onionr/onionrsockets.py @@ -20,41 +20,59 @@ import stem.control import threading import socks, config, uuid -import onionrexceptions, time, requests, onionrblockapi +import onionrexceptions, time, requests, onionrblockapi, logger from dependencies import secrets +from gevent.pywsgi import WSGIServer from flask import request, Response, abort - +import flask class OnionrSocketServer: def __init__(self, coreInst): + app = flask.Flask(__name__) self.sockets = {} # pubkey: tor address self.connPool = {} self.bindPort = 1337 self._core = coreInst self.responseData = {} - self.killSocket = False + threading.Thread(target=self.detectShutdown).start() + threading.Thread(target=self.socketStarter).start() app = flask.Flask(__name__) - - http_server = WSGIServer((socket.service_id, bindPort), app) - threading.Thread(target=http_server.serve_forever).start() + self.http_server = WSGIServer(('127.0.0.1', self.bindPort), app) + self.http_server.serve_forever() - @app.route('/dc/', methods=['POST']) - def acceptConn(self): - data = request.form['data'] - data = self._core._utils.bytesTorStr(data) + @app.route('/dc/', methods=['POST']) + def acceptConn(self): + data = request.form['data'] + data = self._core._utils.bytesTorStr(data) - if request.host in self.connPool: - self.connPool[request.host].append(data) - else: - self.connPool[request.host] = [data] + if request.host in self.connPool: + self.connPool[request.host].append(data) + else: + self.connPool[request.host] = [data] - retData = self.responseData[request.host] + retData = self.responseData[request.host] - self.responseData[request.host] = '' + self.responseData[request.host] = '' - return retData + return retData + def socketStarter(self): + while not self._core.killSockets: + try: + self.addSocket(self._core.startSocket['peer'], reason=self._core.startSocket['reason']) + except KeyError: + pass + else: + logger.info('%s socket started with %s' % (self._core.startSocket['reason'], self._core.startSocket['peer'])) + self._core.startSocket = {} + + def detectShutdown(self): + while not self._core.killSockets: + time.sleep(5) + logger.info('Killing socket server') + self.http_server.stop() + def setResponseData(self, host, data): self.responseData[host] = data @@ -68,10 +86,8 @@ class OnionrSocketServer: self.responseData[socket.service_id] = '' - self._core.insertBlock(uuid.uuid4(), header='socket', sign=True, encryptType='asym', asymPeer=peer, meta={'reason': reason}) + self._core.insertBlock(str(uuid.uuid4()), header='socket', sign=True, encryptType='asym', asymPeer=peer, meta={'reason': reason}) - while not self.killSocket: - time.sleep(3) return class OnionrSocketClient: diff --git a/onionr/onionrutils.py b/onionr/onionrutils.py index b5fc10c1..15bbc866 100644 --- a/onionr/onionrutils.py +++ b/onionr/onionrutils.py @@ -593,7 +593,8 @@ class OnionrUtils: except ValueError as e: logger.debug('Failed to make request', error = e) except requests.exceptions.RequestException as e: - logger.debug('Error: %s' % str(e)) + if not 'ConnectTimeoutError' in str(e): + logger.debug('Error: %s' % str(e)) retData = False return retData