work on direct connections

This commit is contained in:
Kevin Froman 2019-03-19 00:09:53 -05:00
parent a87d1bf1e8
commit 2da5e0479a
6 changed files with 62 additions and 53 deletions

View File

@ -24,7 +24,7 @@ from dependencies import secrets
from utils import networkmerger
import onionrexceptions, onionrpeers, onionrevents as events, onionrplugins as plugins, onionrblockapi as block
from communicatorutils import onionrdaemontools
import onionrsockets, onionr, onionrproofs
import onionrservices, onionr, onionrproofs
from communicatorutils import onionrcommunicatortimers, proxypicker
OnionrCommunicatorTimers = onionrcommunicatortimers.OnionrCommunicatorTimers
@ -126,9 +126,9 @@ class OnionrCommunicatorDaemon:
#forwardSecrecyTimer.count = (forwardSecrecyTimer.frequency - 990)
if config.get('general.socket_servers'):
self.socketServer = threading.Thread(target=onionrsockets.OnionrSocketServer, args=(self._core,))
self.socketServer.start()
self.socketClient = onionrsockets.OnionrSocketClient(self._core)
self.services = onionrservices.OnionrServices(self._core)
else:
self.services = None
# Main daemon loop, mainly for calling timers, don't do any complex operations here to avoid locking
try:
@ -565,19 +565,6 @@ class OnionrCommunicatorDaemon:
i.count = (i.frequency - 1)
elif cmd[0] == 'uploadBlock':
self.blocksToUpload.append(cmd[1])
elif cmd[0] == 'startSocket':
# Create our own socket server
socketInfo = json.loads(cmd[1])
socketInfo['id'] = uuid.uuid4()
self._core.startSocket = socketInfo
elif cmd[0] == 'addSocket':
# Socket server was created for us
socketInfo = json.loads(cmd[1])
peer = socketInfo['peer']
reason = socketInfo['reason']
threading.Thread(target=self.socketClient.startSocket, args=(peer, reason)).start()
else:
logger.info('Recieved daemonQueue command:' + cmd[0])
if cmd[0] not in ('', None):
if response != '':

View File

@ -355,7 +355,6 @@ class Core:
conn = sqlite3.connect(self.queueDB, timeout=30)
c = conn.cursor()
t = (command, data, date, responseID)
try:
c.execute('INSERT INTO commands (command, data, date, responseID) VALUES(?, ?, ?, ?)', t)
conn.commit()

View File

@ -1,17 +1,29 @@
import time
import stem
import core
from . import connectionserver, connectionclient, bootstrapservice
from . import connectionserver, bootstrapservice
class OnionrServices:
def __init__(self, onionr_core):
assert isinstance(onionr_core, core.Core)
self._core = onionr_core
self.servers = {}
self.clients = {}
self.shutdown = False
return
def create_server(self):
return
def create_server(self, peer, address):
assert self._core._utils.validateID(address)
BOOTSTRAP_TRIES = 10
TRY_WAIT = 3
for x in range(BOOTSTRAP_TRIES):
if self._core._utils.doGetRequest('http://' + address + '/ping') == 'pong!':
connectionserver.ConnectionServer(peer, address, core_inst=self._core)
return True
else:
time.sleep(TRY_WAIT)
else:
return False
def create_client(self, peer):
# Create ephemeral onion service to bootstrap connection
address = bootstrapservice.bootstrap_client_service(peer)

View File

@ -23,7 +23,7 @@ from flask import Flask
import core
from netcontroller import getOpenPort
def bootstrap_client_service(peer, core_inst=None):
def bootstrap_client_service(peer, core_inst=None, bootstrap_timeout=120):
'''
Bootstrap client services
'''
@ -32,10 +32,10 @@ def bootstrap_client_service(peer, core_inst=None):
if not core_inst._utils.validatePubKey(peer):
raise ValueError('Peer must be valid base32 ed25519 public key')
http_server = WSGIServer(('127.0.0.1', bootstrap_port), bootstrap_app, log=None)
bootstrap_port = getOpenPort()
bootstrap_app = flask.Flask(__name__)
bootstrap_app = Flask(__name__)
http_server = WSGIServer(('127.0.0.1', bootstrap_port), bootstrap_app, log=None)
bootstrap_address = ''
@ -50,14 +50,14 @@ def bootstrap_client_service(peer, core_inst=None):
bootstrap_address = address
http_server.stop()
with Controller.from_port() as controller:
with Controller.from_port(port=core_inst.config.get('tor.controlPort')) as controller:
# Connect to the Tor process for Onionr
controller.authenticate()
controller.authenticate(core_inst.config.get('tor.controlpassword'))
# Create the v3 onion service
response = controller.create_ephemeral_hidden_service({80: bootstrap_port}, await_publication = True, key_type='ED25519-V3')
response = controller.create_ephemeral_hidden_service({80: bootstrap_port}, await_publication = True, key_content = 'ED25519-V3')
core_inst.insertBlock(response.hostname, header='con', sign=True, encryptType='asym',
asymPeer=peer, disableForward=True)
core_inst.insertBlock(response.service_id, header='con', sign=True, encryptType='asym',
asymPeer=peer, disableForward=True, expire=(core_inst._utils.getEpoch() + bootstrap_timeout))
# Run the bootstrap server
http_server.serve_forever()

View File

@ -1,4 +1,27 @@
import stem, flask
import core
class ConnectionServer:
def __init__(self):
return
def __init__(self, peer, address, core_inst=None):
if core_inst is None:
self.core_inst = core.Core()
else:
self.core_inst = core_inst
if not core_inst._utils.validatePubKey(peer):
raise ValueError('Peer must be valid base32 ed25519 public key')
service_app = flask.Flask(__name__)
service_port = getOpenPort()
http_server = WSGIServer(('127.0.0.1', service_port), service_app, log=None)
@service_app.route('/ping')
def get_ping():
return "pong!"
with Controller.from_port(port=core_inst.config.get('tor.controlPort')) as controller:
# Connect to the Tor process for Onionr
controller.authenticate(core_inst.config.get('tor.controlpassword'))
# Create the v3 onion service
response = controller.create_ephemeral_hidden_service({80: service_port}, await_publication = True, key_type='ED25519-V3')
logger.info('hosting on ' + response.service_id)
http_server.serve_forever()

View File

@ -46,6 +46,8 @@ def on_processblocks(api, data=None):
myBlock = api.data['block']
blockType = api.data['type']
logger.info('blockType is ' + blockType)
utils = api.get_utils()
core = api.get_core()
# Process specific block types
@ -54,26 +56,12 @@ def on_processblocks(api, data=None):
if api.data['validSig'] == True:
_processForwardKey(api, myBlock)
# socket blocks
elif blockType == 'socket':
elif blockType == 'con':
if api.data['validSig'] == True and myBlock.decrypted: # we check if it is decrypted as a way of seeing if it was for us
logger.info('Detected socket advertised to us...')
try:
address = myBlock.getMetadata('address')
except KeyError:
raise onionrexceptions.MissingAddress("Missing address for new socket")
try:
port = myBlock.getMetadata('port')
except KeyError:
raise ValueError("Missing port for new socket")
try:
reason = myBlock.getMetadata('reason')
except KeyError:
raise ValueError("Missing socket reason")
socketInfo = json.dumps({'peer': api.data['signer'], 'address': address, 'port': port, 'create': False, 'reason': reason})
api.get_core().daemonQueueAdd('addSocket', socketInfo)
else:
logger.warn("socket is not for us or is invalid")
myBlock.bcontent = utils.bytesToStr(myBlock.bcontent)
if utils.validateID('%s.onion' % (myBlock.bcontent,)):
logger.info('Detected socket advertised to us...')
core.keyStore.put('con', (myBlock.content, myBlock.signer))
def on_init(api, data = None):