From 82213561b853fe3c2a1932ac5603e4fbb2f04602 Mon Sep 17 00:00:00 2001 From: KF7EEL Date: Sun, 13 Jun 2021 09:54:33 -0700 Subject: [PATCH] clean code, PROXY now works --- bridge.py | 99 ++++++++++++++++++++++++++++++++++++++++++- config.py | 20 ++++++++- user_managment/app.py | 52 +++++++++++++++++------ 3 files changed, 155 insertions(+), 16 deletions(-) diff --git a/bridge.py b/bridge.py index 8997e72..4ddd092 100755 --- a/bridge.py +++ b/bridge.py @@ -58,6 +58,13 @@ import logging logger = logging.getLogger(__name__) import os, ast import json, requests + +# User for different functions that need to be running: APRS, Proxy, etc +import threading + +# Hotspot Proxy stuff +from hotspot_proxy_v2 import Proxy + # Does anybody read this stuff? There's a PEP somewhere that says I should do this. __author__ = 'Cortney T. Buffington, N0MJS' __copyright__ = 'Copyright (c) 2016-2019 Cortney T. Buffington, N0MJS and the K0USY Group' @@ -168,6 +175,50 @@ def download_config(L_CONFIG_FILE, cli_file): logger.error('Config server unreachable, defaulting to local config') return config.build_config(cli_file) + +# From hotspot_proxy2, FreeDMR +def hotspot_proxy(listen_port, port_start, port_stop): + Master = "127.0.0.1" + ListenPort = listen_port + DestportStart = port_start + DestPortEnd = port_stop + Timeout = 30 + Stats = True + Debug = False + BlackList = [1234567] + + + CONNTRACK = {} + + for port in range(DestportStart,DestPortEnd+1,1): + CONNTRACK[port] = False + + + reactor.listenUDP(ListenPort,Proxy(Master,ListenPort,CONNTRACK,BlackList,Timeout,Debug,DestportStart,DestPortEnd)) + + def loopingErrHandle(failure): + logger.error('(GLOBAL) STOPPING REACTOR TO AVOID MEMORY LEAK: Unhandled error innowtimed loop.\n {}'.format(failure)) + reactor.stop() + + def stats(): + count = 0 + nowtime = time() + for port in CONNTRACK: + if CONNTRACK[port]: + count = count+1 + + totalPorts = DestPortEnd - DestportStart + freePorts = totalPorts - count + + print("{} ports out of {} in use ({} free)".format(count,totalPorts,freePorts)) + + + + if Stats == True: + stats_task = task.LoopingCall(stats) + statsa = stats_task.start(30) + statsa.addErrback(loopingErrHandle) + # Module gobal varaibles # Dictionary for dynamically mapping unit (subscriber) to a system. @@ -1269,7 +1320,50 @@ if __name__ == '__main__': logger.info('(REPORT) TCP Socket reporting not configured') # HBlink instance creation - logger.info('(GLOBAL) HBlink \'bridge.py\' -- SYSTEM STARTING...') + logger.info('(GLOBAL) HBNet \'bridge.py\' -- SYSTEM STARTING...') + + # Generate list of Enabled MODE: PROXY masters + proxy_master_list = [] + for i in CONFIG['SYSTEMS']: + if CONFIG['SYSTEMS'][i]['ENABLED'] == True: + if CONFIG['SYSTEMS'][i]['MODE'] == 'PROXY': + proxy_master_list.append(i) + # Start proxy as a thread (if enabled in config) for each set of MASTERs + for m in proxy_master_list: + if CONFIG['SYSTEMS'][m]['EXTERNAL_PROXY_SCRIPT'] == False: + proxy_thread = threading.Thread(target=hotspot_proxy, args=(CONFIG['SYSTEMS'][m]['EXTERNAL_PORT'],CONFIG['SYSTEMS'][m]['INTERNAL_PORT_START'],CONFIG['SYSTEMS'][m]['INTERNAL_PORT_STOP'],)) + proxy_thread.daemon = True + proxy_thread.start() + logger.info('Started thread for PROXY for MASTER set: ' + m) + + #Build Master configs from list + for i in proxy_master_list: + n_systems = CONFIG['SYSTEMS'][i]['INTERNAL_PORT_STOP'] - CONFIG['SYSTEMS'][i]['INTERNAL_PORT_START'] + n_count = 0 + while n_count < n_systems: + CONFIG['SYSTEMS'].update({i + '-' + str(n_count): { + 'MODE': 'MASTER', + 'ENABLED': True, + 'STATIC_APRS_POSITION_ENABLED': CONFIG['SYSTEMS'][i]['STATIC_APRS_POSITION_ENABLED'], + 'REPEAT': CONFIG['SYSTEMS'][i]['REPEAT'], + 'MAX_PEERS': 1, + 'IP': '127.0.0.1', + 'PORT': CONFIG['SYSTEMS'][i]['INTERNAL_PORT_START'] + n_count, + 'PASSPHRASE': CONFIG['SYSTEMS'][i]['PASSPHRASE'], + 'GROUP_HANGTIME': CONFIG['SYSTEMS'][i]['GROUP_HANGTIME'], + 'USE_ACL': CONFIG['SYSTEMS'][i]['USE_ACL'], + 'REG_ACL': CONFIG['SYSTEMS'][i]['REG_ACL'], + 'SUB_ACL': CONFIG['SYSTEMS'][i]['SUB_ACL'], + 'TGID_TS1_ACL': CONFIG['SYSTEMS'][i]['TG1_ACL'], + 'TGID_TS2_ACL': CONFIG['SYSTEMS'][i]['TG2_ACL'] + }}) + CONFIG['SYSTEMS'][i + '-' + str(n_count)].update({'PEERS': {}}) + systems[i + '-' + str(n_count)] = routerHBP(i + '-' + str(n_count), CONFIG, report_server) + n_count = n_count + 1 + # Remove original MASTER stanza to prevent errors + CONFIG['SYSTEMS'].pop(i) + logger.info('Generated MASTER instances for proxy set: ' + i) + for system in CONFIG['SYSTEMS']: if CONFIG['SYSTEMS'][system]['ENABLED']: if CONFIG['SYSTEMS'][system]['MODE'] == 'OPENBRIDGE': @@ -1293,7 +1387,8 @@ if __name__ == '__main__': stream_trimmer = stream_trimmer_task.start(5) stream_trimmer.addErrback(loopingErrHandle) - + logger.info('Unit calls will be bridged to: ' + str(UNIT)) + print(CONFIG['SYSTEMS']) # Download burn list with open(CONFIG['USER_MANAGER']['BURN_FILE'], 'w') as f: f.write(str(download_burnlist(CONFIG))) diff --git a/config.py b/config.py index 30b4ba1..cbfe3c6 100755 --- a/config.py +++ b/config.py @@ -296,7 +296,25 @@ def build_config(_config_file): 'TG1_ACL': config.get(section, 'TGID_ACL'), 'TG2_ACL': 'PERMIT:ALL' }}) - print( CONFIG['SYSTEMS'][section]) + elif config.get(section, 'MODE') == 'PROXY': + CONFIG['SYSTEMS'].update({section: { + 'MODE': config.get(section, 'MODE'), + 'ENABLED': config.getboolean(section, 'ENABLED'), + 'EXTERNAL_PROXY_SCRIPT': config.getboolean(section, 'EXTERNAL_PROXY_SCRIPT'), + 'STATIC_APRS_POSITION_ENABLED': config.getboolean(section, 'STATIC_APRS_POSITION_ENABLED'), + 'REPEAT': config.getboolean(section, 'REPEAT'), + 'PASSPHRASE': bytes(config.get(section, 'PASSPHRASE'), 'utf-8'), + 'EXTERNAL_PORT': config.getint(section, 'EXTERNAL_PORT'), + 'INTERNAL_PORT_START': config.getint(section, 'INTERNAL_PORT_START'), + 'INTERNAL_PORT_STOP': config.getint(section, 'INTERNAL_PORT_STOP'), + 'GROUP_HANGTIME': config.getint(section, 'GROUP_HANGTIME'), + 'USE_ACL': config.getboolean(section, 'USE_ACL'), + 'REG_ACL': config.get(section, 'REG_ACL'), + 'SUB_ACL': config.get(section, 'SUB_ACL'), + 'TG1_ACL': config.get(section, 'TG1_ACL'), + 'TG2_ACL': config.get(section, 'TG2_ACL') + }}) + CONFIG['SYSTEMS'][section].update({'PEERS': {}}) except configparser.Error as err: sys.exit('Error processing configuration file -- {}'.format(err)) diff --git a/user_managment/app.py b/user_managment/app.py index dc92a58..8cf2fac 100644 --- a/user_managment/app.py +++ b/user_managment/app.py @@ -327,6 +327,7 @@ def create_app(): use_acl = db.Column(db.Boolean(), nullable=False, server_default='1') sub_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') tg_acl = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') + enable_unit = db.Column(db.Boolean(), nullable=False, server_default='1') server = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') notes = db.Column(db.String(100, collation='NOCASE'), nullable=False, server_default='') @@ -1771,6 +1772,7 @@ def create_app(): # print(s.name) i = MasterList.query.filter_by(server=_name).all() o = OBP.query.filter_by(server=_name).all() + p = ProxyList.query.filter_by(server=_name).all() print('get masters') master_config_list = {} ## master_config_list['SYSTEMS'] = {} @@ -1780,6 +1782,7 @@ def create_app(): master_config_list.update({m.name: { 'MODE': 'MASTER', 'ENABLED': m.active, + 'USE_USER_MAN': m.enable_um, 'STATIC_APRS_POSITION_ENABLED': m.static_positions, 'REPEAT': m.repeat, 'MAX_PEERS': m.max_peers, @@ -1795,16 +1798,16 @@ def create_app(): }}) master_config_list[m.name].update({'PEERS': {}}) for obp in o: - print(type(obp.network_id)) +## print(type(obp.network_id)) master_config_list.update({obp.name: { 'MODE': 'OPENBRIDGE', 'ENABLED': obp.enabled, 'NETWORK_ID': obp.network_id, #int(obp.network_id).to_bytes(4, 'big'), 'IP': gethostbyname(obp.ip), 'PORT': obp.port, -## 'PASSPHRASE': bytes(obp.passphrase.ljust(20,'\x00')[:20], 'utf-8'), -## 'TARGET_SOCK': (obp.target_ip, obp.target_port), -## 'TARGET_IP': gethostbyname(obp.target_ip), + 'PASSPHRASE': bytes(obp.passphrase.ljust(20,'\x00')[:20], 'utf-8'), + 'TARGET_SOCK': (obp.target_ip, obp.target_port), + 'TARGET_IP': gethostbyname(obp.target_ip), 'TARGET_PORT': obp.target_port, 'BOTH_SLOTS': obp.both_slots, 'USE_ACL': obp.use_acl, @@ -1812,6 +1815,27 @@ def create_app(): 'TG1_ACL': obp.tg_acl, 'TG2_ACL': 'PERMIT:ALL' }}) + for pr in p: + master_config_list.update({pr.name: { + 'MODE': 'PROXY', + 'ENABLED': pr.active, + 'EXTERNAL_PROXY_SCRIPT': pr.external_proxy, + 'STATIC_APRS_POSITION_ENABLED': pr.static_positions, + 'USE_USER_MAN': pr.enable_um, + 'REPEAT': pr.repeat, + 'PASSPHRASE': bytes(pr.passphrase, 'utf-8'), + 'EXTERNAL_PORT': pr.external_port, + 'INTERNAL_PORT_START': pr.internal_start_port, + 'INTERNAL_PORT_STOP': pr.internal_stop_port, + 'GROUP_HANGTIME': pr.group_hang_time, + 'USE_ACL': pr.use_acl, + 'REG_ACL': pr.reg_acl, + 'SUB_ACL': pr.sub_acl, + 'TG1_ACL': pr.tg1_acl, + 'TG2_ACL': pr.tg2_acl + }}) + master_config_list[pr.name].update({'PEERS': {}}) + print(master_config_list) return master_config_list @@ -1865,9 +1889,9 @@ def create_app(): db.session.commit() def edit_master(_mode, _name, _server, _static_positions, _repeat, _active, _max_peers, _ip, _port, _enable_um, _passphrase, _group_hang_time, _use_acl, _reg_acl, _sub_acl, _tg1_acl, _tg2_acl, _enable_unit, _notes, _external_proxy, _int_start_port, _int_stop_port, _network_id, _target_ip, _target_port, _both_slots): - print(_mode) - print(_server) - print(_name) +## print(_mode) +#### print(_server) +## print(_name) if _mode == 'MASTER': ## print(_name) m = MasterList.query.filter_by(server=_server).filter_by(name=_name).first() @@ -1891,6 +1915,8 @@ def create_app(): m.notes = _notes db.session.commit() if _mode == 'OBP': + print(_enable_unit) +## print(enable_unit) o = OBP.query.filter_by(server=_server).filter_by(name=_name).first() o.enabled = _active o.network_id = _network_id @@ -1904,11 +1930,12 @@ def create_app(): o.sub_acl = _sub_acl o.tg1_acl = _tg1_acl o.tg2_acl = _tg2_acl + o.enable_unit = _enable_unit o.notes = _notes db.session.commit() if _mode == 'PROXY': - print(_int_start_port) - print(_int_stop_port) +## print(_int_start_port) +## print(_int_stop_port) p = ProxyList.query.filter_by(server=_server).filter_by(name=_name).first() p.name = _name p.static_positions = _static_positions @@ -2017,6 +2044,7 @@ def create_app(): use_acl = _use_acl, sub_acl = _sub_acl, tg_acl = _tg1_acl, + enable_unit = _enable_unit, server = _server, notes = _notes, ) @@ -2894,8 +2922,6 @@ def create_app():

Redirecting in 3 seconds.

''' if request.args.get('edit_xlx') == 'save': - print(request.args.get('edit_xlx') == 'save') - print(request.args.get('server')) peer_edit('xlx', request.args.get('server'), request.args.get('name'), peer_enabled, peer_loose, request.form.get('ip'), request.form.get('port'), request.form.get('master_ip'), request.form.get('master_port'), request.form.get('passphrase'), request.form.get('callsign'), request.form.get('radio_id'), request.form.get('rx'), request.form.get('tx'), request.form.get('tx_power'), request.form.get('cc'), request.form.get('lat'), request.form.get('lon'), request.form.get('height'), request.form.get('location'), request.form.get('description'), request.form.get('slots'), request.form.get('url'), request.form.get('group_hangtime'), request.form.get('xlxmodule'), request.form.get('options'), use_acl, request.form.get('sub_acl'), request.form.get('tgid_ts1_acl'), request.form.get('tgid_ts2_acl')) content = '''

XLX PEER changed.

Redirecting in 3 seconds.

@@ -3164,7 +3190,7 @@ def create_app(): enable_unit = False both_slots = True if request.form.get('enabled') == 'True': - active = True + enabled = True if request.form.get('use_acl') == 'True': use_acl = True if request.form.get('enable_unit') == 'True': @@ -3246,7 +3272,6 @@ def create_app():  Active:   @@ -3751,6 +3776,7 @@ def create_app():  Enable Unit Calls: