added flood fill work, misc bug fixes and removing communicator timers
parent
04105a2b70
commit
bbd76da333
|
@ -5,7 +5,7 @@ This file registers blueprints for the private api server
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
from gevent import sleep
|
from gevent import sleep
|
||||||
|
|
||||||
from httpapi import security, friendsapi, profilesapi, configapi, insertblock
|
from httpapi import security, friendsapi, configapi, insertblock
|
||||||
from httpapi import miscclientapi, onionrsitesapi, apiutils
|
from httpapi import miscclientapi, onionrsitesapi, apiutils
|
||||||
from httpapi import directconnections
|
from httpapi import directconnections
|
||||||
from httpapi import themeapi
|
from httpapi import themeapi
|
||||||
|
@ -33,7 +33,6 @@ def register_private_blueprints(private_api, app):
|
||||||
app.register_blueprint(security.client.ClientAPISecurity(
|
app.register_blueprint(security.client.ClientAPISecurity(
|
||||||
private_api).client_api_security_bp)
|
private_api).client_api_security_bp)
|
||||||
app.register_blueprint(friendsapi.friends)
|
app.register_blueprint(friendsapi.friends)
|
||||||
app.register_blueprint(profilesapi.profile_BP)
|
|
||||||
app.register_blueprint(configapi.config_BP)
|
app.register_blueprint(configapi.config_BP)
|
||||||
app.register_blueprint(insertblock.ib)
|
app.register_blueprint(insertblock.ib)
|
||||||
app.register_blueprint(miscclientapi.getblocks.client_get_blocks)
|
app.register_blueprint(miscclientapi.getblocks.client_get_blocks)
|
||||||
|
|
|
@ -86,12 +86,10 @@ class OnionrCommunicatorDaemon:
|
||||||
# extends our upload list and saves our list when Onionr exits
|
# extends our upload list and saves our list when Onionr exits
|
||||||
uploadqueue.UploadQueue(self)
|
uploadqueue.UploadQueue(self)
|
||||||
|
|
||||||
# Timers to periodically lookup new blocks and download them
|
add_onionr_thread(
|
||||||
lookup_blocks_timer = OnionrCommunicatorTimers(
|
|
||||||
self,
|
|
||||||
lookupblocks.lookup_blocks_from_communicator,
|
lookupblocks.lookup_blocks_from_communicator,
|
||||||
config.get('timers.lookupBlocks', 25),
|
[self.shared_state], 25, 3)
|
||||||
my_args=[self], requires_peer=True, max_threads=1)
|
|
||||||
|
|
||||||
"""The block download timer is accessed by the block lookup function
|
"""The block download timer is accessed by the block lookup function
|
||||||
to trigger faster download starts"""
|
to trigger faster download starts"""
|
||||||
|
@ -99,11 +97,7 @@ class OnionrCommunicatorDaemon:
|
||||||
self, self.getBlocks, config.get('timers.getBlocks', 10),
|
self, self.getBlocks, config.get('timers.getBlocks', 10),
|
||||||
requires_peer=True, max_threads=5)
|
requires_peer=True, max_threads=5)
|
||||||
|
|
||||||
# Timer to reset the longest offline peer
|
add_onionr_thread(onlinepeers.clear_offline_peer, [self.kv], 58)
|
||||||
# so contact can be attempted again
|
|
||||||
OnionrCommunicatorTimers(
|
|
||||||
self, onlinepeers.clear_offline_peer, 58, my_args=[self],
|
|
||||||
max_threads=1)
|
|
||||||
|
|
||||||
# Timer to cleanup old blocks
|
# Timer to cleanup old blocks
|
||||||
blockCleanupTimer = OnionrCommunicatorTimers(
|
blockCleanupTimer = OnionrCommunicatorTimers(
|
||||||
|
@ -180,7 +174,6 @@ class OnionrCommunicatorDaemon:
|
||||||
# Adjust initial timer triggers
|
# Adjust initial timer triggers
|
||||||
cleanupTimer.count = (cleanupTimer.frequency - 60)
|
cleanupTimer.count = (cleanupTimer.frequency - 60)
|
||||||
blockCleanupTimer.count = (blockCleanupTimer.frequency - 2)
|
blockCleanupTimer.count = (blockCleanupTimer.frequency - 2)
|
||||||
lookup_blocks_timer = (lookup_blocks_timer.frequency - 2)
|
|
||||||
|
|
||||||
shared_state.add(self)
|
shared_state.add(self)
|
||||||
|
|
||||||
|
|
|
@ -23,9 +23,8 @@ if TYPE_CHECKING:
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def clear_offline_peer(comm_inst: 'OnionrCommunicatorDaemon'):
|
def clear_offline_peer(kv: 'DeadSimpleKV'):
|
||||||
"""Remove the longest offline peer to retry later."""
|
"""Remove the longest offline peer to retry later."""
|
||||||
kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV")
|
|
||||||
try:
|
try:
|
||||||
removed = kv.get('offlinePeers').pop(0)
|
removed = kv.get('offlinePeers').pop(0)
|
||||||
except IndexError:
|
except IndexError:
|
||||||
|
@ -33,4 +32,4 @@ def clear_offline_peer(comm_inst: 'OnionrCommunicatorDaemon'):
|
||||||
else:
|
else:
|
||||||
logger.debug('Removed ' + removed +
|
logger.debug('Removed ' + removed +
|
||||||
' from offline list, will try them again.')
|
' from offline list, will try them again.')
|
||||||
comm_inst.decrementThreadCount('clear_offline_peer')
|
|
||||||
|
|
|
@ -39,7 +39,7 @@ blacklist = onionrblacklist.OnionrBlackList()
|
||||||
storage_counter = StorageCounter()
|
storage_counter = StorageCounter()
|
||||||
|
|
||||||
|
|
||||||
def lookup_blocks_from_communicator(comm_inst):
|
def lookup_blocks_from_communicator(shared_state: 'TooMany'):
|
||||||
logger.info('Looking up new blocks')
|
logger.info('Looking up new blocks')
|
||||||
tryAmount = 2
|
tryAmount = 2
|
||||||
newBlocks = ''
|
newBlocks = ''
|
||||||
|
@ -50,7 +50,7 @@ def lookup_blocks_from_communicator(comm_inst):
|
||||||
maxBacklog = 1560
|
maxBacklog = 1560
|
||||||
lastLookupTime = 0 # Last time we looked up a particular peer's list
|
lastLookupTime = 0 # Last time we looked up a particular peer's list
|
||||||
new_block_count = 0
|
new_block_count = 0
|
||||||
kv: "DeadSimpleKV" = comm_inst.shared_state.get_by_string("DeadSimpleKV")
|
kv: "DeadSimpleKV" = shared_state.get_by_string("DeadSimpleKV")
|
||||||
for i in range(tryAmount):
|
for i in range(tryAmount):
|
||||||
# Defined here to reset it each time, time offset is added later
|
# Defined here to reset it each time, time offset is added later
|
||||||
listLookupCommand = 'getblocklist'
|
listLookupCommand = 'getblocklist'
|
||||||
|
@ -87,7 +87,7 @@ def lookup_blocks_from_communicator(comm_inst):
|
||||||
listLookupCommand += '?date=%s' % (lastLookupTime,)
|
listLookupCommand += '?date=%s' % (lastLookupTime,)
|
||||||
try:
|
try:
|
||||||
newBlocks = peeraction.peer_action(
|
newBlocks = peeraction.peer_action(
|
||||||
comm_inst.shared_state,
|
shared_state,
|
||||||
peer, listLookupCommand) # get list of new block hashes
|
peer, listLookupCommand) # get list of new block hashes
|
||||||
except Exception as error:
|
except Exception as error:
|
||||||
logger.warn(
|
logger.warn(
|
||||||
|
@ -124,6 +124,3 @@ def lookup_blocks_from_communicator(comm_inst):
|
||||||
logger.info(
|
logger.info(
|
||||||
f'Discovered {new_block_count} new block{block_string}',
|
f'Discovered {new_block_count} new block{block_string}',
|
||||||
terminal=True)
|
terminal=True)
|
||||||
comm_inst.download_blocks_timer.count = \
|
|
||||||
int(comm_inst.download_blocks_timer.frequency * 0.99)
|
|
||||||
comm_inst.decrementThreadCount('lookup_blocks_from_communicator')
|
|
||||||
|
|
|
@ -8,6 +8,7 @@ import platform
|
||||||
|
|
||||||
from flask import Response, Blueprint, request, send_from_directory, abort
|
from flask import Response, Blueprint, request, send_from_directory, abort
|
||||||
from flask import g
|
from flask import g
|
||||||
|
from gevent import sleep
|
||||||
import unpaddedbase32
|
import unpaddedbase32
|
||||||
|
|
||||||
from httpapi import apiutils
|
from httpapi import apiutils
|
||||||
|
@ -138,10 +139,6 @@ class PrivateEndpoints:
|
||||||
return Response(
|
return Response(
|
||||||
bytesconverter.bytes_to_str(mnemonickeys.get_base32(words)))
|
bytesconverter.bytes_to_str(mnemonickeys.get_base32(words)))
|
||||||
|
|
||||||
@private_endpoints_bp.route('/gettorsocks')
|
|
||||||
def get_tor_socks():
|
|
||||||
return Response(str(g.too_many.get(NetController).socksPort))
|
|
||||||
|
|
||||||
@private_endpoints_bp.route('/setonboarding', methods=['POST'])
|
@private_endpoints_bp.route('/setonboarding', methods=['POST'])
|
||||||
def set_onboarding():
|
def set_onboarding():
|
||||||
return Response(
|
return Response(
|
||||||
|
@ -151,11 +148,25 @@ class PrivateEndpoints:
|
||||||
def get_os_system():
|
def get_os_system():
|
||||||
return Response(platform.system().lower())
|
return Response(platform.system().lower())
|
||||||
|
|
||||||
|
@private_endpoints_bp.route('/gettorsocks')
|
||||||
|
def get_tor_socks():
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
return Response(
|
||||||
|
str(
|
||||||
|
g.too_many.get_by_string(
|
||||||
|
'NetController').socksPort))
|
||||||
|
except KeyError:
|
||||||
|
sleep(0.1)
|
||||||
|
|
||||||
@private_endpoints_bp.route('/torready')
|
@private_endpoints_bp.route('/torready')
|
||||||
def is_tor_ready():
|
def is_tor_ready():
|
||||||
"""If Tor is starting up, the web UI is not ready to be used."""
|
"""If Tor is starting up, the web UI is not ready to be used."""
|
||||||
return Response(
|
try:
|
||||||
str(g.too_many.get(NetController).readyState).lower())
|
return Response(
|
||||||
|
str(g.too_many.get_by_string('NetController').readyState).lower())
|
||||||
|
except KeyError:
|
||||||
|
return Response("false")
|
||||||
|
|
||||||
@private_endpoints_bp.route('/gettoraddress')
|
@private_endpoints_bp.route('/gettoraddress')
|
||||||
def get_tor_address():
|
def get_tor_address():
|
||||||
|
|
|
@ -1,27 +0,0 @@
|
||||||
'''
|
|
||||||
Onionr - Private P2P Communication
|
|
||||||
|
|
||||||
This file creates http endpoints for user profile pages
|
|
||||||
'''
|
|
||||||
'''
|
|
||||||
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/>.
|
|
||||||
'''
|
|
||||||
from flask import Blueprint, Response, request, abort
|
|
||||||
from . import profiles
|
|
||||||
|
|
||||||
profile_BP = Blueprint('profile_BP', __name__)
|
|
||||||
|
|
||||||
@profile_BP.route('/profile/get/<pubkey>', endpoint='profiles')
|
|
||||||
def get_profile_page(pubkey):
|
|
||||||
return Response(pubkey)
|
|
|
@ -1,2 +0,0 @@
|
||||||
def get_latest_user_profile(pubkey):
|
|
||||||
return ''
|
|
|
@ -10,6 +10,7 @@ from onionrtypes import LANIP
|
||||||
import logger
|
import logger
|
||||||
from coredb.blockmetadb import get_block_list
|
from coredb.blockmetadb import get_block_list
|
||||||
from onionrblocks.blockimporter import import_block_from_data
|
from onionrblocks.blockimporter import import_block_from_data
|
||||||
|
import onionrexceptions
|
||||||
from ..server import ports
|
from ..server import ports
|
||||||
|
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
@ -37,9 +38,12 @@ def _lan_work(peer: LANIP):
|
||||||
blocks = requests.get(url + 'blist/0').text.splitlines()
|
blocks = requests.get(url + 'blist/0').text.splitlines()
|
||||||
for block in blocks:
|
for block in blocks:
|
||||||
if block not in our_blocks:
|
if block not in our_blocks:
|
||||||
import_block_from_data(
|
try:
|
||||||
requests.get(
|
import_block_from_data(
|
||||||
url + f'get/{block}', stream=True).raw.read(6000000))
|
requests.get(
|
||||||
|
url + f'get/{block}', stream=True).raw.read(6000000))
|
||||||
|
except onionrexceptions.InvalidMetadata:
|
||||||
|
logger.warn(f"Could not get {block} from lan peer")
|
||||||
|
|
||||||
for port in ports:
|
for port in ports:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -145,8 +145,8 @@ class NetController:
|
||||||
except ValueError:
|
except ValueError:
|
||||||
# Happens if int() check is not valid
|
# Happens if int() check is not valid
|
||||||
logger.error("torPid.txt contained invalid integer. " +
|
logger.error("torPid.txt contained invalid integer. " +
|
||||||
"This indicates corruption " +
|
"This indicates corruption " +
|
||||||
"and should not be bypassed for security reasons")
|
"and should not be bypassed for security reasons")
|
||||||
return
|
return
|
||||||
os.remove(self.dataDir + 'torPid.txt')
|
os.remove(self.dataDir + 'torPid.txt')
|
||||||
except ProcessLookupError:
|
except ProcessLookupError:
|
||||||
|
|
|
@ -1,17 +1,25 @@
|
||||||
from typing import Callable
|
from typing import Callable
|
||||||
from typing import Iterable
|
from typing import Iterable
|
||||||
|
|
||||||
|
import traceback
|
||||||
from threading import Thread
|
from threading import Thread
|
||||||
|
|
||||||
from time import sleep
|
from time import sleep
|
||||||
|
|
||||||
|
import logger
|
||||||
|
|
||||||
|
|
||||||
def _onionr_thread(func: Callable, args: Iterable,
|
def _onionr_thread(func: Callable, args: Iterable,
|
||||||
sleep_secs: int, initial_sleep):
|
sleep_secs: int, initial_sleep):
|
||||||
if initial_sleep:
|
if initial_sleep:
|
||||||
sleep(initial_sleep)
|
sleep(initial_sleep)
|
||||||
while True:
|
while True:
|
||||||
func(*args)
|
try:
|
||||||
|
func(*args)
|
||||||
|
except Exception as _: # noqa
|
||||||
|
logger.warn(
|
||||||
|
"Onionr thread exception \n" + traceback.format_exc(),
|
||||||
|
terminal=True)
|
||||||
sleep(sleep_secs)
|
sleep(sleep_secs)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -44,14 +44,14 @@ def test_clearnet_tor_request(testmanager):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
leak_result: str = do_get_request(
|
leak_result: str = do_get_request(
|
||||||
'https://onionr.net/404',
|
'https://example.com/notvalidpage',
|
||||||
port=socks_port, ignoreAPI=True).lower()
|
port=socks_port, ignoreAPI=True).lower()
|
||||||
except AttributeError:
|
except AttributeError:
|
||||||
leak_result = ""
|
leak_result = ""
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.warn(str(e))
|
logger.warn(str(e))
|
||||||
try:
|
try:
|
||||||
if 'not found' in leak_result:
|
if 'example' in leak_result:
|
||||||
logger.error('Tor was able to request a clearnet site')
|
logger.error('Tor was able to request a clearnet site')
|
||||||
raise ValueError('Tor was able to request a clearnet site')
|
raise ValueError('Tor was able to request a clearnet site')
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
|
|
@ -45,7 +45,9 @@ class _Importer(FileSystemEventHandler):
|
||||||
os.remove(event.src_path)
|
os.remove(event.src_path)
|
||||||
try:
|
try:
|
||||||
import_block_from_data(block_data)
|
import_block_from_data(block_data)
|
||||||
except onionrexceptions.DataExists:
|
except(
|
||||||
|
onionrexceptions.DataExists,
|
||||||
|
onionrexceptions.BlockMetaEntryExists) as _:
|
||||||
return
|
return
|
||||||
if block_data_location in event.src_path:
|
if block_data_location in event.src_path:
|
||||||
try:
|
try:
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
from typing import List
|
||||||
|
|
||||||
|
from onionrutils.localcommand import local_command
|
||||||
|
from .neighbors import identify_neighbors
|
||||||
|
|
||||||
|
|
||||||
|
def stream_pool():
|
||||||
|
|
||||||
|
peers = lioc
|
||||||
|
|
|
@ -0,0 +1,38 @@
|
||||||
|
from secrets import token_bytes
|
||||||
|
from typing import TYPE_CHECKING
|
||||||
|
import socket
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from stem.control import Controller
|
||||||
|
|
||||||
|
from onionrtypes import OnionAddressString
|
||||||
|
|
||||||
|
import yam
|
||||||
|
|
||||||
|
|
||||||
|
def peer_tunnel(tor_controller: Controller, peer):
|
||||||
|
socks_port = tor_controller.get_conf('SocksPort')
|
||||||
|
|
||||||
|
class Connected:
|
||||||
|
connected = False
|
||||||
|
|
||||||
|
send_buffer = []
|
||||||
|
rec_buffer = []
|
||||||
|
rec_address = None
|
||||||
|
|
||||||
|
yam.client(1, peer, socks_port, send_buffer, rec_buffer, Connected)
|
||||||
|
with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
|
||||||
|
ip = '127.0.0.1'
|
||||||
|
s.bind((ip, 0))
|
||||||
|
s.listen(1)
|
||||||
|
port = s.getsockname()[1]
|
||||||
|
serv = tor_controller.create_ephemeral_hidden_service(
|
||||||
|
{1337: '127.0.0.1:' + str(port)},
|
||||||
|
key_content='ED25519-V3',
|
||||||
|
await_publication=True,
|
||||||
|
)
|
||||||
|
rec_address = serv.service_id
|
||||||
|
conn, addr = s.accept()
|
||||||
|
yam.server(1, tor_controller, conn, send_buffer, rec_buffer, Connected)
|
||||||
|
|
||||||
|
|
|
@ -1,16 +0,0 @@
|
||||||
import sys, os
|
|
||||||
sys.path.append(".")
|
|
||||||
sys.path.append("src/")
|
|
||||||
import unittest, uuid
|
|
||||||
TEST_DIR = 'testdata/%s-%s' % (uuid.uuid4(), os.path.basename(__file__)) + '/'
|
|
||||||
print("Test directory:", TEST_DIR)
|
|
||||||
os.environ["ONIONR_HOME"] = TEST_DIR
|
|
||||||
from onionrsetup import setup_config
|
|
||||||
setup_config()
|
|
||||||
import config
|
|
||||||
|
|
||||||
class TestRandomBindIP(unittest.TestCase):
|
|
||||||
def test_random_bind_ip_default_setting(self):
|
|
||||||
self.assertTrue(config.get('general.random_bind_ip'))
|
|
||||||
|
|
||||||
unittest.main()
|
|
Loading…
Reference in New Issue