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 :-)
This commit is contained in:
Simon 2021-06-18 01:52:13 +01:00
parent a205a1eaaa
commit 09a3015f77
3 changed files with 39 additions and 16 deletions

View File

@ -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))

View File

@ -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 &&

View File

@ -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):