cleanup, work, and bugfixes for direct connections

This commit is contained in:
Kevin Froman 2019-03-24 22:32:17 -05:00
parent b9beef3cce
commit dfbb0a512c
5 changed files with 57 additions and 13 deletions

View File

@ -39,7 +39,7 @@ class FDSafeHandler(WSGIHandler):
except Timeout as ex: except Timeout as ex:
raise raise
def setBindIP(filePath): def setBindIP(filePath, writeOut=True):
'''Set a random localhost IP to a specified file (intended for private or public API localhost IPs)''' '''Set a random localhost IP to a specified file (intended for private or public API localhost IPs)'''
if config.get('general.random_bind_ip', True): if config.get('general.random_bind_ip', True):
hostOctets = [str(127), str(random.randint(0x02, 0xFF)), str(random.randint(0x02, 0xFF)), str(random.randint(0x02, 0xFF))] hostOctets = [str(127), str(random.randint(0x02, 0xFF)), str(random.randint(0x02, 0xFF)), str(random.randint(0x02, 0xFF))]
@ -55,8 +55,9 @@ def setBindIP(filePath):
s.close() s.close()
else: else:
data = '127.0.0.1' data = '127.0.0.1'
with open(filePath, 'w') as bindFile: if writeOut:
bindFile.write(data) with open(filePath, 'w') as bindFile:
bindFile.write(data)
return data return data
class PublicAPI: class PublicAPI:

View File

@ -215,7 +215,10 @@ class Block:
''' '''
if self.exists(): if self.exists():
os.remove(self.getBlockFile()) try:
os.remove(self.getBlockFile())
except TypeError:
pass
self.getCore().removeBlock(self.getHash()) self.getCore().removeBlock(self.getHash())
return True return True
return False return False

View File

@ -16,8 +16,10 @@ class OnionrServices:
assert self._core._utils.validateID(address) assert self._core._utils.validateID(address)
BOOTSTRAP_TRIES = 10 BOOTSTRAP_TRIES = 10
TRY_WAIT = 3 TRY_WAIT = 3
base_url = 'http://%s/' % (address,)
socks = self._core.config.get('tor.socksport')
for x in range(BOOTSTRAP_TRIES): for x in range(BOOTSTRAP_TRIES):
if self._core._utils.doGetRequest('http://' + address + '/ping', port=self._core.config.get('tor.socksport')) == 'pong!': if self._core._utils.doGetRequest(base_url + 'ping', port=socks, ignoreAPI=True) == 'pong!':
connectionserver.ConnectionServer(peer, address, core_inst=self._core) connectionserver.ConnectionServer(peer, address, core_inst=self._core)
else: else:
time.sleep(TRY_WAIT) time.sleep(TRY_WAIT)

View File

@ -17,11 +17,12 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>. along with this program. If not, see <https://www.gnu.org/licenses/>.
''' '''
import time
from gevent.pywsgi import WSGIServer, WSGIHandler from gevent.pywsgi import WSGIServer, WSGIHandler
from stem.control import Controller from stem.control import Controller
from flask import Flask from flask import Flask
import core import core
from netcontroller import getOpenPort from netcontroller import getOpenPort
def bootstrap_client_service(peer, core_inst=None, bootstrap_timeout=300): def bootstrap_client_service(peer, core_inst=None, bootstrap_timeout=300):
''' '''
@ -38,6 +39,7 @@ def bootstrap_client_service(peer, core_inst=None, bootstrap_timeout=300):
http_server = WSGIServer(('127.0.0.1', bootstrap_port), bootstrap_app, log=None) http_server = WSGIServer(('127.0.0.1', bootstrap_port), bootstrap_app, log=None)
bootstrap_address = '' bootstrap_address = ''
shutdown = False
@bootstrap_app.route('/ping') @bootstrap_app.route('/ping')
def get_ping(): def get_ping():
@ -48,20 +50,22 @@ def bootstrap_client_service(peer, core_inst=None, bootstrap_timeout=300):
if core_inst._utils.validateID(address): if core_inst._utils.validateID(address):
# Set the bootstrap address then close the server # Set the bootstrap address then close the server
bootstrap_address = address bootstrap_address = address
http_server.stop() shutdown = True
return "success"
with Controller.from_port(port=core_inst.config.get('tor.controlPort')) as controller: with Controller.from_port(port=core_inst.config.get('tor.controlPort')) as controller:
# Connect to the Tor process for Onionr # Connect to the Tor process for Onionr
controller.authenticate(core_inst.config.get('tor.controlpassword')) controller.authenticate(core_inst.config.get('tor.controlpassword'))
# Create the v3 onion service # Create the v3 onion service
#response = controller.create_ephemeral_hidden_service({80: bootstrap_port}, await_publication = True, key_content = 'ED25519-V3')
response = controller.create_ephemeral_hidden_service({80: bootstrap_port}, key_type = 'NEW', await_publication = True) response = controller.create_ephemeral_hidden_service({80: bootstrap_port}, key_type = 'NEW', await_publication = True)
core_inst.insertBlock(response.service_id, header='con', sign=True, encryptType='asym', core_inst.insertBlock(response.service_id, header='con', sign=True, encryptType='asym',
asymPeer=peer, disableForward=True, expire=(core_inst._utils.getEpoch() + bootstrap_timeout)) asymPeer=peer, disableForward=True, expire=(core_inst._utils.getEpoch() + bootstrap_timeout))
# Run the bootstrap server # Run the bootstrap server
http_server.serve_forever() threading.Thread(target=http_server.serve_forever).start()
# This line reached when server is shutdown by being bootstrapped # This line reached when server is shutdown by being bootstrapped
while not shutdown and not core_inst.killSockets:
time.sleep(1)
# Now that the bootstrap server has received a server, return the address # Now that the bootstrap server has received a server, return the address
return bootstrap_address return bootstrap_address

View File

@ -1,5 +1,30 @@
import stem, flask '''
import core Onionr - P2P Anonymous Storage Network
This module does the second part of the bootstrap block handshake and creates the API server
'''
'''
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
'''
import threading, time
from gevent.pywsgi import WSGIServer, WSGIHandler
from stem.control import Controller
from flask import Flask
import core, logger
from netcontroller import getOpenPort
from api import setBindIP
class ConnectionServer: class ConnectionServer:
def __init__(self, peer, address, core_inst=None): def __init__(self, peer, address, core_inst=None):
if core_inst is None: if core_inst is None:
@ -10,10 +35,15 @@ class ConnectionServer:
if not core_inst._utils.validatePubKey(peer): if not core_inst._utils.validatePubKey(peer):
raise ValueError('Peer must be valid base32 ed25519 public key') raise ValueError('Peer must be valid base32 ed25519 public key')
service_app = flask.Flask(__name__) socks = core_inst.config.get('tor.socksport') # Load config for Tor socks port for proxy
service_app = Flask(__name__) # Setup Flask app for server.
service_port = getOpenPort() service_port = getOpenPort()
service_ip = setBindIP()
http_server = WSGIServer(('127.0.0.1', service_port), service_app, log=None) http_server = WSGIServer(('127.0.0.1', service_port), service_app, log=None)
# TODO define basic endpoints useful for direct connections like stats
# TODO load endpoints from plugins
@service_app.route('/ping') @service_app.route('/ping')
def get_ping(): def get_ping():
return "pong!" return "pong!"
@ -23,5 +53,9 @@ class ConnectionServer:
controller.authenticate(core_inst.config.get('tor.controlpassword')) controller.authenticate(core_inst.config.get('tor.controlpassword'))
# Create the v3 onion service # Create the v3 onion service
response = controller.create_ephemeral_hidden_service({80: service_port}, await_publication = True, key_type='NEW') response = controller.create_ephemeral_hidden_service({80: service_port}, await_publication = True, key_type='NEW')
self.core_inst._utils.doPostRequest('http://' + address + '/bs/' + response.service_id, port=socks)
logger.info('hosting on ' + response.service_id) logger.info('hosting on ' + response.service_id)
http_server.serve_forever() threading.Thread(target=http_server.serve_forever).start()
while not self.core_inst.killSockets:
time.sleep(1)
http_server.stop()