From 09a3015f77499074f3578c3eb286abc64096ae19 Mon Sep 17 00:00:00 2001 From: Simon Date: Fri, 18 Jun 2021 01:52:13 +0100 Subject: [PATCH] Don't error on unresolvable hostname in TARGET_IP Allow null TARGET_IP - Waits for first keepalive to update - use for endpoints that are on a dynamic or unknown IP Support IPv6 for OBP - to listen IPv6 set IP: :: or other valid ipv6 address IPv6 addresses can be used in TARGET_IP or will be resolved from DNS Note, might cause confusion if the target has an IPv6 address and we don't take note of this and specify ipv4 explicitly if needs be. IPv6 Needs some testing :-) --- config.py | 21 ++++++++++++++++----- docker-configs/docker_install.sh | 2 +- hblink.py | 32 ++++++++++++++++++++++---------- 3 files changed, 39 insertions(+), 16 deletions(-) diff --git a/config.py b/config.py index 91aa477..2a8c50f 100755 --- a/config.py +++ b/config.py @@ -30,7 +30,7 @@ import configparser import sys import const -from socket import gethostbyname +import socket # Does anybody read this stuff? There's a PEP somewhere that says I should do this. __author__ = 'Cortney T. Buffington, N0MJS' @@ -272,7 +272,7 @@ def build_config(_config_file): 'ENABLED': config.getboolean(section, 'ENABLED'), 'REPEAT': config.getboolean(section, 'REPEAT'), 'MAX_PEERS': config.getint(section, 'MAX_PEERS'), - 'IP': gethostbyname(config.get(section, 'IP')), + 'IP': config.get(section, 'IP'), 'PORT': config.getint(section, 'PORT'), 'PASSPHRASE': bytes(config.get(section, 'PASSPHRASE'), 'utf-8'), 'GROUP_HANGTIME': config.getint(section, 'GROUP_HANGTIME'), @@ -297,11 +297,11 @@ def build_config(_config_file): 'MODE': config.get(section, 'MODE'), 'ENABLED': config.getboolean(section, 'ENABLED'), 'NETWORK_ID': config.getint(section, 'NETWORK_ID').to_bytes(4, 'big'), - 'IP': gethostbyname(config.get(section, 'IP')), + 'IP': config.get(section, 'IP'), 'PORT': config.getint(section, 'PORT'), 'PASSPHRASE': bytes(config.get(section, 'PASSPHRASE').ljust(20,'\x00')[:20], 'utf-8'), - 'TARGET_SOCK': (gethostbyname(config.get(section, 'TARGET_IP')), config.getint(section, 'TARGET_PORT')), - 'TARGET_IP': gethostbyname(config.get(section, 'TARGET_IP')), + #'TARGET_SOCK': (gethostbyname(config.get(section, 'TARGET_IP')), config.getint(section, 'TARGET_PORT')), + 'TARGET_IP': config.get(section, 'TARGET_IP'), 'TARGET_PORT': config.getint(section, 'TARGET_PORT'), 'USE_ACL': config.getboolean(section, 'USE_ACL'), 'SUB_ACL': config.get(section, 'SUB_ACL'), @@ -311,6 +311,17 @@ def build_config(_config_file): 'ENHANCED_OBP': config.getboolean(section, 'ENHANCED_OBP') }}) + try: + addr_info = socket.getaddrinfo(CONFIG['SYSTEMS'][section]['TARGET_IP'],CONFIG['SYSTEMS'][section]['TARGET_PORT'],socket.AF_UNSPEC, socket.IPPROTO_IP) + + family, socktype, proto, canonname, sockaddr = addr_info[0] + CONFIG['SYSTEMS'][section]['TARGET_SOCK'] = sockaddr + CONFIG['SYSTEMS'][section]['TARGET_IP'] = sockaddr[0] + + except: + CONFIG['SYSTEMS'][section]['TARGET_IP'] = False + CONFIG['SYSTEMS'][section]['TARGET_SOCK'] = (CONFIG['SYSTEMS'][section]['TARGET_IP'], CONFIG['SYSTEMS'][section]['TARGET_PORT']) + except configparser.Error as err: sys.exit('Error processing configuration file -- {}'.format(err)) diff --git a/docker-configs/docker_install.sh b/docker-configs/docker_install.sh index c789cfd..4129cec 100755 --- a/docker-configs/docker_install.sh +++ b/docker-configs/docker_install.sh @@ -5,7 +5,7 @@ echo FreeDMR Docker installer... echo Installing required packages... apt-get -y install docker.io && #apt-get -y install docker-compose && -apt-get -y install conntrack && +apt-get -y install conntrack && echo Set userland-proxy to false... echo '{ "userland-proxy": false}' > /etc/docker/daemon.json && diff --git a/hblink.py b/hblink.py index 892d92f..034c85b 100755 --- a/hblink.py +++ b/hblink.py @@ -120,6 +120,7 @@ class OPENBRIDGE(DatagramProtocol): def startProtocol(self): + logger.info('(%s) Starting OBP. TARGET_IP: %s, TARGET_PORT: %s',self._system, self._config['TARGET_IP'], self._config['TARGET_PORT']) if self._config['ENHANCED_OBP']: logger.debug('(%s) *BridgeControl* starting KeepAlive timer',self._system) self._bcka_task = task.LoopingCall(self.send_bcka) @@ -130,7 +131,7 @@ class OPENBRIDGE(DatagramProtocol): logger.info('(%s) is mode OPENBRIDGE. No De-Registration required, continuing shutdown', self._system) def send_system(self, _packet): - if _packet[:4] == DMRD: + if _packet[:4] == DMRD and self._config['TARGET_IP']: #_packet = _packet[:11] + self._config['NETWORK_ID'] + _packet[15:] _packet = b''.join([_packet[:11], self._CONFIG['GLOBAL']['SERVER_ID'], _packet[15:]]) #_packet += hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest() @@ -139,19 +140,30 @@ class OPENBRIDGE(DatagramProtocol): # KEEP THE FOLLOWING COMMENTED OUT UNLESS YOU'RE DEBUGGING DEEPLY!!!! #logger.debug('(%s) TX Packet to OpenBridge %s:%s -- %s', self._system, self._config['TARGET_IP'], self._config['TARGET_PORT'], ahex(_packet)) else: - logger.error('(%s) OpenBridge system was asked to send non DMRD packet with send_system(): %s', self._system, _packet) + + if not self._config['TARGET_IP']: + logger.debug('(%s) Not sent packet as TARGET_IP not currently known') + else: + logger.error('(%s) OpenBridge system was asked to send non DMRD packet with send_system(): %s', self._system, _packet) def send_bcka(self): - _packet = BCKA - _packet = b''.join([_packet[:4], (hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest())]) - self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT'])) - logger.debug('(%s) *BridgeControl* sent KeepAlive',self._system) + if self._config['TARGET_IP']: + _packet = BCKA + _packet = b''.join([_packet[:4], (hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest())]) + self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT'])) + logger.debug('(%s) *BridgeControl* sent KeepAlive',self._system) + else: + logger.debug('(%s) *BridgeControl* not sending KeepAlive, TARGET_IP currently not known',self._system) + def send_bcsq(self,_tgid,_stream_id): - _packet = b''.join([BCSQ, _tgid, _stream_id]) - _packet = b''.join([_packet, (hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest())]) - self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT'])) - logger.debug('(%s) *BridgeControl* sent BCSQ Source Quench, TG: %s, Stream ID: %s',self._system,int_id(_tgid), int_id(_stream_id)) + if self._config['TARGET_IP']: + _packet = b''.join([BCSQ, _tgid, _stream_id]) + _packet = b''.join([_packet, (hmac_new(self._config['PASSPHRASE'],_packet,sha1).digest())]) + self.transport.write(_packet, (self._config['TARGET_IP'], self._config['TARGET_PORT'])) + logger.debug('(%s) *BridgeControl* sent BCSQ Source Quench, TG: %s, Stream ID: %s',self._system,int_id(_tgid), int_id(_stream_id)) + else: + logger.debug('(%s) *BridgeControl* Not sent BCSQ Source Quench TARGET_IP not known , TG: %s, Stream ID: %s',self._system,int_id(_tgid)) def dmrd_received(self, _peer_id, _rf_src, _dst_id, _seq, _slot, _call_type, _frame_type, _dtype_vseq, _stream_id, _data):