* lan server including discovery and publishing added (only ping implemented in server)

This commit is contained in:
Kevin Froman 2020-03-16 02:28:41 -05:00
parent 92c4109572
commit 3aec35ef33
9 changed files with 99 additions and 45 deletions

View File

@ -7,7 +7,6 @@ from threading import Thread
if TYPE_CHECKING:
from toomanyobjs import TooMany
from . import server
from .client import Client
from .discover import learn_services, advertise_service
"""
@ -31,11 +30,10 @@ class LANManager:
def __init__(self, too_many: "TooMany"):
self.too_many = too_many
self.peers: "exploded IP Address string" = set()
self.peers: "exploded IP Address string" = []
def start(self):
Thread(target=learn_services, args=[[]], daemon=True).start()
Thread(target=learn_services, args=[self.peers], daemon=True).start()
Thread(target=advertise_service, daemon=True).start()
#Thread(tra)

View File

@ -70,13 +70,16 @@ def learn_services(lan_service_list: List):
# no return intended, list modified by reference
def advertise_service():
def advertise_service(specific_ips=None):
# regarding socket.IP_MULTICAST_TTL
# ---------------------------------
# for all packets sent, after three hops on the network the packet will not
# be re-sent/broadcast (see https://www.tldp.org/HOWTO/Multicast-HOWTO-6.html)
MULTICAST_TTL = 3
ips = '-'.join(lan_ips)
if specific_ips is None:
ips = '-'.join(lan_ips)
else:
ips = '-'.join(specific_ips)
sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_MULTICAST_TTL, MULTICAST_TTL)

View File

@ -17,3 +17,10 @@ for adapter in get_adapters():
else:
lan_ips.append(ip.exploded)
for ip in lan_ips:
if '192.168' in ip:
best_ip = ip
break
else:
best_ip = lan_ips[0]

View File

@ -4,6 +4,14 @@ LAN transport server thread
"""
from gevent.pywsgi import WSGIServer
from flask import Flask
from flask import Response
from gevent import sleep
from httpapi.fdsafehandler import FDSafeHandler
from netcontroller import get_open_port
import config
from coredb.blockmetadb import get_block_list
from lan.getip import lan_ips, best_ip
"""
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
@ -24,10 +32,24 @@ class LANServer:
def __init__(self, shared_state):
app = Flask(__name__)
self.app = app
self.host = config.get('lan.bind_ip', '')
self.server = None
if self.host == '':
self.host = best_ip
self.port = None
@app.route("/")
@app.route('/blist/<time>')
def get_block_list_for_lan(time):
return Response(get_block_list(dateRec=time).split('\n'))
@app.route("/ping")
def ping():
return "pong!"
return Response("pong!")
def start_server(self):
self.server = WSGIServer((self.host, get_open_port()),
self.app, log=None,
handler_class=FDSafeHandler)
self.port = self.server.server_port
self.server.serve_forever()
def start_server():
return

View File

@ -37,6 +37,7 @@ from netcontroller.torcontrol.onionservicecreator import create_onion_service
from .quotes import QUOTE
from utils.boxprint import bordered
from lan import LANManager
from lan.server import LANServer
"""
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
@ -123,37 +124,37 @@ def daemon():
use_existing_tor = config.get('tor.use_existing_tor', False)
if not offline_mode:
if config.get('transports.tor', True):
if use_existing_tor:
try:
os.mkdir(filepaths.tor_hs_loc)
except FileExistsError:
pass
net.socksPort = config.get('tor.existing_socks_port')
try:
net.myID = create_onion_service(
port=net.apiServerIP + ':' + str(net.hsPort))[0]
except IncorrectPassword:
logger.error('Invalid Tor control password', terminal=True)
localcommand.local_command('shutdown')
cleanup.delete_run_files()
sys.exit(1)
if use_existing_tor:
try:
os.mkdir(filepaths.tor_hs_loc)
except FileExistsError:
pass
net.socksPort = config.get('tor.existing_socks_port')
try:
net.myID = create_onion_service(
port=net.apiServerIP + ':' + str(net.hsPort))[0]
except IncorrectPassword:
logger.error('Invalid Tor control password', terminal=True)
localcommand.local_command('shutdown')
cleanup.delete_run_files()
sys.exit(1)
if not net.myID.endswith('.onion'):
net.myID += '.onion'
with open(filepaths.tor_hs_address_file, 'w') as tor_file:
tor_file.write(net.myID)
else:
logger.info('Tor is starting...', terminal=True)
if not net.startTor():
localcommand.local_command('shutdown')
cleanup.delete_run_files()
sys.exit(1)
if len(net.myID) > 0 and security_level == 0:
logger.debug('Started .onion service: %s' %
(logger.colors.underline + net.myID))
else:
logger.debug('.onion service disabled')
if not net.myID.endswith('.onion'):
net.myID += '.onion'
with open(filepaths.tor_hs_address_file, 'w') as tor_file:
tor_file.write(net.myID)
else:
logger.info('Tor is starting...', terminal=True)
if not net.startTor():
localcommand.local_command('shutdown')
cleanup.delete_run_files()
sys.exit(1)
if len(net.myID) > 0 and security_level == 0:
logger.debug('Started .onion service: %s' %
(logger.colors.underline + net.myID))
else:
logger.debug('.onion service disabled')
logger.info('Using public key: %s' %
(logger.colors.underline +
@ -163,6 +164,7 @@ def daemon():
events.event('init', threaded=False)
events.event('daemon_start')
Thread(target=LANServer(shared_state).start_server, daemon=True).start()
LANManager(shared_state).start()
communicator.startCommunicator(shared_state)

View File

@ -13,6 +13,7 @@ from .webpasstest import webpass_test
from .osver import test_os_ver_endpoint
from .clearnettor import test_clearnet_tor_request
from .housekeeping import test_inserted_housekeeping
from .lanservertest import test_lan_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
@ -36,7 +37,8 @@ RUN_TESTS = [uicheck.check_ui,
webpass_test,
test_os_ver_endpoint,
test_clearnet_tor_request,
test_inserted_housekeeping
test_inserted_housekeeping,
test_lan_server
]
SUCCESS_FILE = os.path.dirname(os.path.realpath(__file__)) + '/../../tests/runtime-result.txt'
@ -59,13 +61,19 @@ class OnionrRunTestManager:
try:
for i in RUN_TESTS:
last = i
logger.info("[RUNTIME TEST] " + last.__name__ + " started",
terminal=True)
i(self)
logger.info("[RUNTIME TEST] " + last.__name__ + " passed")
logger.info("[RUNTIME TEST] " + last.__name__ + " passed",
terminal=True)
except (ValueError, AttributeError):
logger.error(last.__name__ + ' failed')
logger.error(last.__name__ + ' failed assertions', terminal=True)
except Exception as e:
logger.error(last.__name__ + ' failed with non-asserting exception')
logger.error(str(e))
else:
ep = str(epoch.get_epoch())
logger.info(f'All runtime tests passed at {ep}')
logger.info(f'All runtime tests passed at {ep}', terminal=True)
with open(SUCCESS_FILE, 'w') as f:
f.write(ep)

View File

@ -0,0 +1,14 @@
import requests
from lan.getip import best_ip
def test_lan_server(testmanager):
for i in range(1024, 65536):
try:
if requests.get(f"http://{best_ip}:{i}/ping").text == 'pong!':
break
except requests.exceptions.ConnectionError:
pass
else:
raise ValueError

View File

@ -1 +1 @@
1584165158
1584339902