* lan server including discovery and publishing added (only ping implemented in server)
This commit is contained in:
		
							parent
							
								
									92c4109572
								
							
						
					
					
						commit
						3aec35ef33
					
				
					 9 changed files with 99 additions and 45 deletions
				
			
		|  | @ -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) | ||||
| 
 | ||||
|  |  | |||
|  | @ -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) | ||||
|  |  | |||
|  | @ -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] | ||||
| 
 | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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) | ||||
| 
 | ||||
|  |  | |||
|  | @ -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) | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										14
									
								
								src/runtests/lanservertest.py
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										14
									
								
								src/runtests/lanservertest.py
									
										
									
									
									
										Normal 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 | ||||
|  | @ -1 +1 @@ | |||
| 1584165158 | ||||
| 1584339902 | ||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue