diff --git a/scripts/disable-dev-config.py b/scripts/disable-dev-config.py index cd471377..685b21ab 100755 --- a/scripts/disable-dev-config.py +++ b/scripts/disable-dev-config.py @@ -24,6 +24,8 @@ conf['log']['file']['remove_on_exit'] = True conf['transports']['lan'] = True conf['transports']['tor'] = True conf['transports']['sneakernet'] = True +conf['statistics']['i_dont_want_privacy'] = False +conf['statistics']['server'] = '' json.dump(conf, open('static-data/default_config.json', 'w'), sort_keys=True, indent=4) diff --git a/scripts/enable-dev-config.py b/scripts/enable-dev-config.py index 6cdaeaf0..d547843e 100755 --- a/scripts/enable-dev-config.py +++ b/scripts/enable-dev-config.py @@ -27,6 +27,9 @@ conf['onboarding']['done'] = True conf['general']['minimum_block_pow'] = block_pow conf['general']['minimum_send_pow'] = block_pow conf['log']['file']['remove_on_exit'] = False +if input('Stat reporting? y/n') == 'y': + conf['statistics']['i_dont_want_privacy'] = True + conf['statistics']['server'] = input('Statistics server') json.dump(conf, open('static-data/default_config.json', 'w'), sort_keys=True, indent=4) diff --git a/scripts/stats-server.py b/scripts/stats-server.py new file mode 100755 index 00000000..76d04953 --- /dev/null +++ b/scripts/stats-server.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python3 +"""Onionr - Private P2P Communication. + +LAN transport server thread +""" +import sys +import os +os.chdir('../') +sys.path.append("src/") +from gevent.pywsgi import WSGIServer +from flask import Flask +from flask import Response +from flask import request +import stem +from stem.control import Controller +from netcontroller import getopenport +import json +""" + 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 . +""" + +#passw = secrets.token_hex(32) +port_num = int(input('tor control port')) +web_port = getopenport.get_open_port() + + +app = Flask(__name__) + +STATS_FILE = 'stats.json' + +@app.route('/sendstats/', methods = ['POST']) +def get_stats(node): + try: + with open(STATS_FILE, 'r') as f: + try: + data = json.loads(f.read()) + except json.decoder.JSONDecodeError: + raise FileNotFoundError + except FileNotFoundError: + data = {} + data[node] = request.get_data().decode('utf-8') + + with open(STATS_FILE, 'w') as f: + data = json.dumps(data) + f.write(data) + + return Response('ok') + +with Controller.from_port(port = port_num) as controller: + controller.authenticate(input('pass for tor')) # provide the password here if you set one + hs = controller.create_ephemeral_hidden_service( + {80: web_port}, + key_type = 'NEW', + key_content = 'ED25519-V3', + await_publication=True, + detached=True) + hs = hs.service_id + print(f'stats server {hs}') + + server = WSGIServer(('127.0.0.1', web_port), app, log=None) + server.serve_forever() + diff --git a/src/lan/client/__init__.py b/src/lan/client/__init__.py index 74e904c1..b7d5b913 100644 --- a/src/lan/client/__init__.py +++ b/src/lan/client/__init__.py @@ -41,5 +41,5 @@ class Client: - better_sleep(self.pull_delay) + better_sleep(self.poll_delay) diff --git a/src/onionrcommands/daemonlaunch/__init__.py b/src/onionrcommands/daemonlaunch/__init__.py index 6b1374b1..3c6390df 100755 --- a/src/onionrcommands/daemonlaunch/__init__.py +++ b/src/onionrcommands/daemonlaunch/__init__.py @@ -38,6 +38,7 @@ from utils.boxprint import bordered from lan import LANManager from lan.server import LANServer from sneakernet import sneakernet_import_thread +from onionrstatistics.devreporting import statistics_reporter """ 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 @@ -172,6 +173,8 @@ def daemon(): LANManager(shared_state).start() if config.get('transports.sneakernet', True): Thread(target=sneakernet_import_thread, daemon=True).start() + + Thread(target=statistics_reporter, args=[shared_state], daemon=True).start() communicator.startCommunicator(shared_state) clean_ephemeral_services() diff --git a/src/onionrstatistics/devreporting/__init__.py b/src/onionrstatistics/devreporting/__init__.py new file mode 100644 index 00000000..e9047832 --- /dev/null +++ b/src/onionrstatistics/devreporting/__init__.py @@ -0,0 +1,26 @@ +import config +from utils.bettersleep import better_sleep +from utils.gettransports import get as get_transports +from onionrutils import basicrequests +from onionrutils import epoch + +import json + +def statistics_reporter(shared_state): + server = config.get('statistics.server', '') + if not config.get('statistics.i_dont_want_privacy', False) or \ + not server: return + + def compile_data(): + return { + 'time': epoch.get_epoch(), + 'adders': get_transports(), + 'peers': shared_state.get_by_string('OnionrCommunicatorDaemon').onlinePeers + } + + while True: + better_sleep(5) + data = compile_data() + basicrequests.do_post_request( + f'http://{server}/sendstats/' + get_transports()[0], + data=json.dumps(data)) diff --git a/static-data/default_config.json b/static-data/default_config.json index e7b38ea9..4845e67a 100755 --- a/static-data/default_config.json +++ b/static-data/default_config.json @@ -48,6 +48,10 @@ ], "enabled": [] }, + "statistics": { + "i_dont_want_privacy": false, + "server": "" + }, "timers": { "getBlocks": 10, "lookupBlocks": 25