From bff5f8a186092a27df9ee86555281f0674e71577 Mon Sep 17 00:00:00 2001 From: Simon Date: Sun, 25 Sep 2022 15:24:35 +0100 Subject: [PATCH] remove ipsc_proxy - it has it's own repo --- ipsc_proxy.py | 264 -------------------------------------------------- 1 file changed, 264 deletions(-) delete mode 100644 ipsc_proxy.py diff --git a/ipsc_proxy.py b/ipsc_proxy.py deleted file mode 100644 index 7f40a0e..0000000 --- a/ipsc_proxy.py +++ /dev/null @@ -1,264 +0,0 @@ -############################################################################### -# Copyright (C) 2020 Simon Adlem, G7RZU -# -# 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, write to the Free Software Foundation, -# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA -############################################################################### - -from twisted.internet.protocol import DatagramProtocol -from twisted.internet import reactor, task -from time import time -from dmr_utils3.utils import int_id -import random -import ipaddress -import os -from setproctitle import setproctitle -from datetime import datetime -#from ipsc_const import * - -# Does anybody read this stuff? There's a PEP somewhere that says I should do this. -__author__ = 'Simon Adlem - G7RZU' -__copyright__ = 'Copyright (c) Simon Adlem, G7RZU 2022' -__credits__ = 'Jon Lee, G4TSN; Norman Williams, M6NBP' -__license__ = 'GNU GPLv3' -__maintainer__ = 'Simon Adlem G7RZU' -__email__ = 'simon@gb7fr.org.uk' - -def IsIPv4Address(ip): - try: - ipaddress.IPv4Address(ip) - return True - except ValueError as errorCode: - pass - return False - -def IsIPv6Address(ip): - try: - ipaddress.IPv6Address(ip) - return True - except ValueError as errorCode: - pass - -class Proxy(DatagramProtocol): - - def __init__(self,Master,ListenPort,connTrack,peerTrack,blackList,IPBlackList,Timeout,Debug,ClientInfo,DestportStart,DestPortEnd): - self.master = Master - self.connTrack = connTrack - self.peerTrack = peerTrack - self.timeout = Timeout - self.debug = Debug - self.clientinfo = ClientInfo - self.blackList = blackList - self.IPBlackList = IPBlackList - self.destPortStart = DestportStart - self.destPortEnd = DestPortEnd - self.numPorts = DestPortEnd - DestportStart - - - def reaper(self,_peer_id): - if self.debug: - print("dead",_peer_id) - if self.clientinfo: - print(f"{datetime.now().replace(microsecond=0)} Client: ID:{str(int_id(_peer_id)).rjust(9)} IP:{self.peerTrack[_peer_id]['shost'].rjust(15)} Port:{self.peerTrack[_peer_id]['sport']} Removed.") - self.connTrack[self.peerTrack[_peer_id]['dport']] = False - del self.peerTrack[_peer_id] - - def datagramReceived(self, data, addr): - - _peer_id = False - - host,port = addr - - nowtime = time() - - Debug = self.debug - - if host in self.IPBlackList: - return - - #If the packet comes from the master - if host == self.master: - - _command = data[0:1] - _peer_id = data[1:5] - - if self.debug: - print(data) - if _peer_id in self.peerTrack: - self.transport.write(data,(self.peerTrack[_peer_id]['shost'],self.peerTrack[_peer_id]['sport'])) - - return - - - else: - _command = data[0:1] - _peer_id = data[1:5] - - if _peer_id in self.peerTrack: - _dport = self.peerTrack[_peer_id]['dport'] - self.peerTrack[_peer_id]['sport'] = port - self.peerTrack[_peer_id]['shost'] = host - self.transport.write(data, (self.master,_dport)) - self.peerTrack[_peer_id]['timer'].reset(self.timeout) - if self.debug: - print(data) - return - - else: - if int_id(_peer_id) in self.blackList: - return - # Make a list with the available ports - _ports_avail = [port for port in self.connTrack if not self.connTrack[port]] - if _ports_avail: - _dport = random.choice(_ports_avail) - else: - return - self.connTrack[_dport] = _peer_id - self.peerTrack[_peer_id] = {} - self.peerTrack[_peer_id]['dport'] = _dport - self.peerTrack[_peer_id]['sport'] = port - self.peerTrack[_peer_id]['shost'] = host - self.peerTrack[_peer_id]['timer'] = reactor.callLater(self.timeout,self.reaper,_peer_id) - self.transport.write(data, (self.master,_dport)) - - if self.clientinfo: - print(f'{datetime.now().replace(microsecond=0)} New client: ID:{str(int_id(_peer_id)).rjust(9)} IP:{host.rjust(15)} Port:{port}, assigned to port:{_dport}.') - if self.debug: - print(data) - return - - -if __name__ == '__main__': - - import signal - import configparser - import argparse - import sys - import json - - #Set process title early - setproctitle(__file__) - - # Change the current directory to the location of the application - os.chdir(os.path.dirname(os.path.realpath(sys.argv[0]))) - - # CLI argument parser - handles picking up the config file from the command line, and sending a "help" message - parser = argparse.ArgumentParser() - parser.add_argument('-c', '--config', action='store', dest='CONFIG_FILE', help='/full/path/to/config.file (usually freedmr.cfg)') - cli_args = parser.parse_args() - - - # Ensure we have a path for the config file, if one wasn't specified, then use the execution directory - if not cli_args.CONFIG_FILE: - cli_args.CONFIG_FILE = os.path.dirname(os.path.abspath(__file__))+'/freedmr.cfg' - - _config_file = cli_args.CONFIG_FILE - - config = configparser.ConfigParser() - - if not config.read(_config_file): - print('Configuration file \''+_config_file+'\' is not a valid configuration file!') - - try: - - Master = config.get('IPSC_PROXY','Master') - ListenPort = config.getint('IPSC_PROXY','ListenPort') - ListenIP = config.get('IPSC_PROXY','ListenIP') - DestportStart = config.getint('IPSC_PROXY','DestportStart') - DestPortEnd = config.getint('IPSC_PROXY','DestPortEnd') - Timeout = config.getint('IPSC_PROXY','Timeout') - Stats = config.getboolean('IPSC_PROXY','Stats') - Debug = config.getboolean('IPSC_PROXY','Debug') - ClientInfo = config.getboolean('IPSC_PROXY','ClientInfo') - BlackList = json.loads(config.get('IPSC_PROXY','BlackList')) - IPBlackList = json.loads(config.get('IPSC_PROXY','IPBlackList')) - - except configparser.Error as err: - print('Error processing configuration file -- {}'.format(err)) - - print('Using default config') -#*** CONFIG HERE *** - - Master = "127.0.0.1" - ListenPort = 55005 - #'' = all IPv4, '::' = all IPv4 and IPv6 (Dual Stack) - ListenIP = '' - DestportStart = 59000 - DestPortEnd = 59001 - Timeout = 30 - Stats = True - Debug = True - ClientInfo = True - BlackList = [1234567] - #e.g. {10.0.0.1: 0, 10.0.0.2: 0} - IPBlackList = {} - -#******************* - - CONNTRACK = {} - PEERTRACK = {} - - # Set up the signal handler - def sig_handler(_signal, _frame): - print('(GLOBAL) SHUTDOWN: IPSC_PROXY IS TERMINATING WITH SIGNAL {}'.format(str(_signal))) - reactor.stop() - - # Set signal handers so that we can gracefully exit if need be - for sig in [signal.SIGINT, signal.SIGTERM]: - signal.signal(sig, sig_handler) - - #Override static config from Environment - if 'FDIPSC_PROXY_STATS' in os.environ: - Stats = bool(os.environ['FDIPSC_PROXY_STATS']) - #if 'FDIPSC_PROXY_DEBUG' in os.environ: - # Debug = bool(os.environ['FDIPSC_PROXY_DEBUG']) - if 'FDIPSC_PROXY_CLIENTINFO' in os.environ: - ClientInfo = bool(os.environ['FDIPSC_PROXY_CLIENTINFO']) - if 'FDIPSC_PROXY_LISTENPORT' in os.environ: - ListenPort = int(os.environ['FDIPSC_PROXY_LISTENPORT']) - - for port in range(DestportStart,DestPortEnd+1,1): - CONNTRACK[port] = False - - #If we are listening IPv6 and Master is an IPv4 IPv4Address - #IPv6ify the address. - if ListenIP == '::' and IsIPv4Address(Master): - Master = '::ffff:' + Master - - reactor.listenUDP(ListenPort,Proxy(Master,ListenPort,CONNTRACK,PEERTRACK,BlackList,IPBlackList,Timeout,Debug,ClientInfo,DestportStart,DestPortEnd),interface=ListenIP) - - def loopingErrHandle(failure): - print('(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) - - reactor.run() -