From 83692f037ca1747e15d9856958e8dd1855874b63 Mon Sep 17 00:00:00 2001 From: Cort Buffington Date: Sun, 25 Nov 2018 15:07:55 -0600 Subject: [PATCH] Add maximum peer limit for master instances --- hb_config.py | 1 + hblink-SAMPLE.cfg | 5 ++++ hblink.py | 71 +++++++++++++++++++++++++---------------------- 3 files changed, 44 insertions(+), 33 deletions(-) diff --git a/hb_config.py b/hb_config.py index d7024fc..eebf04f 100755 --- a/hb_config.py +++ b/hb_config.py @@ -202,6 +202,7 @@ def build_config(_config_file): 'MODE': config.get(section, 'MODE'), 'ENABLED': config.getboolean(section, 'ENABLED'), 'REPEAT': config.getboolean(section, 'REPEAT'), + 'MAX_PEERS': config.getint(section, 'MAX_PEERS'), 'EXPORT_AMBE': config.getboolean(section, 'EXPORT_AMBE'), 'IP': gethostbyname(config.get(section, 'IP')), 'PORT': config.getint(section, 'PORT'), diff --git a/hblink-SAMPLE.cfg b/hblink-SAMPLE.cfg index 4e08e91..46b40d0 100755 --- a/hblink-SAMPLE.cfg +++ b/hblink-SAMPLE.cfg @@ -142,12 +142,17 @@ TGID_ACL: PERMIT:ALL # and unused by anything else. # Repeat - if True, the master repeats traffic to peers, False, it does nothing. # +# MAX_PEERS -- maximun number of peers that may be connect to this master +# at any given time. This is very handy if you're allowing hotspots to +# connect, or using a limited computer like a Raspberry Pi. +# # ACLs: # See comments in the GLOBAL stanza [MASTER-1] MODE: MASTER ENABLED: True REPEAT: True +MAX_PEERS: 10 EXPORT_AMBE: False IP: PORT: 54000 diff --git a/hblink.py b/hblink.py index b03674d..1ff847a 100755 --- a/hblink.py +++ b/hblink.py @@ -370,41 +370,46 @@ class HBSYSTEM(DatagramProtocol): elif _command == 'RPTL': # RPTLogin -- a repeater wants to login _peer_id = _data[4:8] - # Check for valid Radio ID - if acl_check(_peer_id, self._CONFIG['GLOBAL']['REG_ACL']) and acl_check(_peer_id, self._config['REG_ACL']): - # Build the configuration data strcuture for the peer - self._peers.update({_peer_id: { - 'CONNECTION': 'RPTL-RECEIVED', - 'PINGS_RECEIVED': 0, - 'LAST_PING': time(), - 'SOCKADDR': _sockaddr, - 'IP': _sockaddr[0], - 'PORT': _sockaddr[1], - 'SALT': randint(0,0xFFFFFFFF), - 'RADIO_ID': str(int(ahex(_peer_id), 16)), - 'CALLSIGN': '', - 'RX_FREQ': '', - 'TX_FREQ': '', - 'TX_POWER': '', - 'COLORCODE': '', - 'LATITUDE': '', - 'LONGITUDE': '', - 'HEIGHT': '', - 'LOCATION': '', - 'DESCRIPTION': '', - 'SLOTS': '', - 'URL': '', - 'SOFTWARE_ID': '', - 'PACKAGE_ID': '', - }}) - logger.info('(%s) Repeater Logging in with Radio ID: %s, %s:%s', self._system, int_id(_peer_id), _sockaddr[0], _sockaddr[1]) - _salt_str = hex_str_4(self._peers[_peer_id]['SALT']) - self.send_peer(_peer_id, 'RPTACK'+_salt_str) - self._peers[_peer_id]['CONNECTION'] = 'CHALLENGE_SENT' - logger.info('(%s) Sent Challenge Response to %s for login: %s', self._system, int_id(_peer_id), self._peers[_peer_id]['SALT']) + # Check to see if we've reached the maximum number of allowed peers + if len(self._peers < self._config['MAX_PEERS']): + # Check for valid Radio ID + if acl_check(_peer_id, self._CONFIG['GLOBAL']['REG_ACL']) and acl_check(_peer_id, self._config['REG_ACL']): + # Build the configuration data strcuture for the peer + self._peers.update({_peer_id: { + 'CONNECTION': 'RPTL-RECEIVED', + 'PINGS_RECEIVED': 0, + 'LAST_PING': time(), + 'SOCKADDR': _sockaddr, + 'IP': _sockaddr[0], + 'PORT': _sockaddr[1], + 'SALT': randint(0,0xFFFFFFFF), + 'RADIO_ID': str(int(ahex(_peer_id), 16)), + 'CALLSIGN': '', + 'RX_FREQ': '', + 'TX_FREQ': '', + 'TX_POWER': '', + 'COLORCODE': '', + 'LATITUDE': '', + 'LONGITUDE': '', + 'HEIGHT': '', + 'LOCATION': '', + 'DESCRIPTION': '', + 'SLOTS': '', + 'URL': '', + 'SOFTWARE_ID': '', + 'PACKAGE_ID': '', + }}) + logger.info('(%s) Repeater Logging in with Radio ID: %s, %s:%s', self._system, int_id(_peer_id), _sockaddr[0], _sockaddr[1]) + _salt_str = hex_str_4(self._peers[_peer_id]['SALT']) + self.send_peer(_peer_id, 'RPTACK'+_salt_str) + self._peers[_peer_id]['CONNECTION'] = 'CHALLENGE_SENT' + logger.info('(%s) Sent Challenge Response to %s for login: %s', self._system, int_id(_peer_id), self._peers[_peer_id]['SALT']) + else: + self.transport.write('MSTNAK'+_peer_id, _sockaddr) + logger.warning('(%s) Invalid Login from Radio ID: %s Denied by Registation ACL', self._system, int_id(_peer_id)) else: self.transport.write('MSTNAK'+_peer_id, _sockaddr) - logger.warning('(%s) Invalid Login from Radio ID: %s Denied by Registation ACL', self._system, int_id(_peer_id)) + logger.warning('(%s) Registration denied from Radio ID: %s Maximum number of peers exceeded', self._system, int_id(_peer_id)) elif _command == 'RPTK': # Repeater has answered our login challenge _peer_id = _data[4:8]