mirror of
https://github.com/markqvist/Reticulum.git
synced 2026-05-19 06:14:47 -07:00
Added interface discovery source filtering by network identity
This commit is contained in:
@@ -161,6 +161,11 @@ class InterfaceAnnounceHandler:
|
|||||||
|
|
||||||
def received_announce(self, destination_hash, announced_identity, app_data):
|
def received_announce(self, destination_hash, announced_identity, app_data):
|
||||||
try:
|
try:
|
||||||
|
discovery_sources = RNS.Reticulum.interface_discovery_sources()
|
||||||
|
if discovery_sources and not announced_identity.hash in discovery_sources:
|
||||||
|
RNS.log(f"Interface discovered from non-authorized network identity {RNS.prettyhexrep(announced_identity.hash)}, ignoring", RNS.LOG_DEBUG)
|
||||||
|
return
|
||||||
|
|
||||||
if app_data and len(app_data) > self.stamper.STAMP_SIZE+1:
|
if app_data and len(app_data) > self.stamper.STAMP_SIZE+1:
|
||||||
flags = app_data[0]
|
flags = app_data[0]
|
||||||
app_data = app_data[1:]
|
app_data = app_data[1:]
|
||||||
@@ -314,12 +319,19 @@ class InterfaceDiscovery():
|
|||||||
def list_discovered_interfaces(self):
|
def list_discovered_interfaces(self):
|
||||||
now = time.time()
|
now = time.time()
|
||||||
discovered_interfaces = []
|
discovered_interfaces = []
|
||||||
|
discovery_sources = RNS.Reticulum.interface_discovery_sources()
|
||||||
for filename in os.listdir(self.storagepath):
|
for filename in os.listdir(self.storagepath):
|
||||||
try:
|
try:
|
||||||
filepath = os.path.join(self.storagepath, filename)
|
filepath = os.path.join(self.storagepath, filename)
|
||||||
with open(filepath, "rb") as f: info = msgpack.unpackb(f.read())
|
with open(filepath, "rb") as f: info = msgpack.unpackb(f.read())
|
||||||
|
should_remove = False
|
||||||
heard_delta = now-info["last_heard"]
|
heard_delta = now-info["last_heard"]
|
||||||
if heard_delta > self.THRESHOLD_REMOVE:
|
|
||||||
|
if heard_delta > self.THRESHOLD_REMOVE: should_remove = True
|
||||||
|
elif discovery_sources and not "network_id" in info: should_remove = True
|
||||||
|
elif discovery_sources and not bytes.fromhex(info["network_id"]) in discovery_sources: should_remove = True
|
||||||
|
|
||||||
|
if should_remove:
|
||||||
os.unlink(filepath)
|
os.unlink(filepath)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@@ -333,6 +345,7 @@ class InterfaceDiscovery():
|
|||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log(f"Error while loading discovered interface data: {e}", RNS.LOG_ERROR)
|
RNS.log(f"Error while loading discovered interface data: {e}", RNS.LOG_ERROR)
|
||||||
|
RNS.log(f"The interface data file {os.path.join(self.storagepath, filename)} may be corrupt", RNS.LOG_ERROR)
|
||||||
RNS.trace_exception(e)
|
RNS.trace_exception(e)
|
||||||
|
|
||||||
discovered_interfaces.sort(key=lambda info: (info["status_code"], info["value"], info["last_heard"]), reverse=True)
|
discovered_interfaces.sort(key=lambda info: (info["status_code"], info["value"], info["last_heard"]), reverse=True)
|
||||||
|
|||||||
@@ -262,6 +262,7 @@ class Reticulum:
|
|||||||
Reticulum.__required_discovery_value = None
|
Reticulum.__required_discovery_value = None
|
||||||
Reticulum.__publish_blackhole = False
|
Reticulum.__publish_blackhole = False
|
||||||
Reticulum.__blackhole_sources = []
|
Reticulum.__blackhole_sources = []
|
||||||
|
Reticulum.__interface_sources = []
|
||||||
|
|
||||||
Reticulum.panic_on_interface_error = False
|
Reticulum.panic_on_interface_error = False
|
||||||
|
|
||||||
@@ -566,6 +567,15 @@ class Reticulum:
|
|||||||
except Exception as e: raise ValueError(f"Invalid identity hash for remote blackhole source: {hexhash}")
|
except Exception as e: raise ValueError(f"Invalid identity hash for remote blackhole source: {hexhash}")
|
||||||
if not source_identity_hash in Reticulum.__blackhole_sources: Reticulum.__blackhole_sources.append(source_identity_hash)
|
if not source_identity_hash in Reticulum.__blackhole_sources: Reticulum.__blackhole_sources.append(source_identity_hash)
|
||||||
|
|
||||||
|
if option == "interface_discovery_sources":
|
||||||
|
v = self.config["reticulum"].as_list(option)
|
||||||
|
for hexhash in v:
|
||||||
|
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
|
||||||
|
if len(hexhash) != dest_len: raise ValueError(f"Identity hash length for interface discovery source {hexhash} is invalid, must be {dest_len} hexadecimal characters ({dest_len//2} bytes).")
|
||||||
|
try: source_identity_hash = bytes.fromhex(hexhash)
|
||||||
|
except Exception as e: raise ValueError(f"Invalid identity hash for interface discovery source: {hexhash}")
|
||||||
|
if not source_identity_hash in Reticulum.__interface_sources: Reticulum.__interface_sources.append(source_identity_hash)
|
||||||
|
|
||||||
if RNS.compiled: RNS.log("Reticulum running in compiled mode", RNS.LOG_DEBUG)
|
if RNS.compiled: RNS.log("Reticulum running in compiled mode", RNS.LOG_DEBUG)
|
||||||
else: RNS.log("Reticulum running in interpreted mode", RNS.LOG_DEBUG)
|
else: RNS.log("Reticulum running in interpreted mode", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
@@ -1524,6 +1534,16 @@ class Reticulum:
|
|||||||
"""
|
"""
|
||||||
return Reticulum.__blackhole_sources
|
return Reticulum.__blackhole_sources
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def interface_discovery_sources():
|
||||||
|
"""
|
||||||
|
Returns the list of network identity hashes from which
|
||||||
|
interfaces are discovered.
|
||||||
|
|
||||||
|
:returns: A list of identity hashes.
|
||||||
|
"""
|
||||||
|
return Reticulum.__interface_sources
|
||||||
|
|
||||||
# Default configuration file:
|
# Default configuration file:
|
||||||
__default_rns_config__ = '''# This is the default Reticulum config file.
|
__default_rns_config__ = '''# This is the default Reticulum config file.
|
||||||
# You should probably edit it to include any additional,
|
# You should probably edit it to include any additional,
|
||||||
|
|||||||
@@ -160,22 +160,6 @@ instance_name = default
|
|||||||
# remote_management_allowed = 9fb6d773498fb3feda407ed8ef2c3229, 2d882c5586e548d79b5af27bca1776dc
|
# remote_management_allowed = 9fb6d773498fb3feda407ed8ef2c3229, 2d882c5586e548d79b5af27bca1776dc
|
||||||
|
|
||||||
|
|
||||||
# You can configure whether Reticulum should discover
|
|
||||||
# available interfaces from other Transport Instances over
|
|
||||||
# the network. If this option is enabled, Reticulum will
|
|
||||||
# collect interface information discovered from the network.
|
|
||||||
|
|
||||||
# discover_interfaces = No
|
|
||||||
|
|
||||||
|
|
||||||
# To prevent interface discovery spamming, a valid crypto-
|
|
||||||
# graphic stamp is required per announced interface. You
|
|
||||||
# can configure the minimum required value to accept as
|
|
||||||
# valid for discovered interfaces.
|
|
||||||
|
|
||||||
# required_discovery_value = 14
|
|
||||||
|
|
||||||
|
|
||||||
# For easier management, discovery and configuration of
|
# For easier management, discovery and configuration of
|
||||||
# networks with many individual transport instances,
|
# networks with many individual transport instances,
|
||||||
# you can specify a network identity to be used across
|
# you can specify a network identity to be used across
|
||||||
@@ -189,6 +173,42 @@ instance_name = default
|
|||||||
# network_identity = ~/.reticulum/storage/identity/network
|
# network_identity = ~/.reticulum/storage/identity/network
|
||||||
|
|
||||||
|
|
||||||
|
# You can configure whether Reticulum should discover
|
||||||
|
# available interfaces from other Transport Instances over
|
||||||
|
# the network. If this option is enabled, Reticulum will
|
||||||
|
# collect interface information discovered from the network.
|
||||||
|
|
||||||
|
# discover_interfaces = No
|
||||||
|
|
||||||
|
|
||||||
|
# If you only want to discover interfaces from specific
|
||||||
|
# networks, you can provide a list of network identities
|
||||||
|
# from which to discover interfaces. If this option is not
|
||||||
|
# provided, interfaces will be discovered from all transport
|
||||||
|
# instances on all connected networks.
|
||||||
|
|
||||||
|
# interface_discovery_sources = 78616ff7c4b8d3886d67d494b440f333, cb127015e13aa6ea1e0a606cdc9123d0
|
||||||
|
|
||||||
|
|
||||||
|
# It is possible to automatically bring up and connect new
|
||||||
|
# interfaces discovered over the network. This option is
|
||||||
|
# disabled by default, but allows you to specify a maximum
|
||||||
|
# number of discovered interfaces to automatically connect.
|
||||||
|
# Additionally, if this option is enabled, Reticulum will
|
||||||
|
# also try to autoconnect available auto-discovered inter-
|
||||||
|
# faces on startup, up to the maximum number specified.
|
||||||
|
|
||||||
|
# autoconnect_discovered_interfaces = 0
|
||||||
|
|
||||||
|
|
||||||
|
# To prevent interface discovery spamming, a valid crypto-
|
||||||
|
# graphic stamp is required per announced interface. You
|
||||||
|
# can configure the minimum required value to accept as
|
||||||
|
# valid for discovered interfaces.
|
||||||
|
|
||||||
|
# required_discovery_value = 14
|
||||||
|
|
||||||
|
|
||||||
# You can configure Reticulum to panic and forcibly close
|
# You can configure Reticulum to panic and forcibly close
|
||||||
# if an unrecoverable interface error occurs, such as the
|
# if an unrecoverable interface error occurs, such as the
|
||||||
# hardware device for an interface disappearing. This is
|
# hardware device for an interface disappearing. This is
|
||||||
|
|||||||
@@ -215,29 +215,33 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=
|
|||||||
location = f"{lat}, {lon}{height}"
|
location = f"{lat}, {lon}{height}"
|
||||||
else: location = "Unknown"
|
else: location = "Unknown"
|
||||||
|
|
||||||
|
transport_id = None
|
||||||
network = None
|
network = None
|
||||||
|
if "transport_id" in i: transport_id = i["transport_id"]
|
||||||
if "transport_id" in i and "network_id" in i and i["transport_id"] != i["network_id"]:
|
if "transport_id" in i and "network_id" in i and i["transport_id"] != i["network_id"]:
|
||||||
network = i["network_id"]
|
network = i["network_id"]
|
||||||
|
|
||||||
if idx > 0: print("\n"+"="*32+"\n")
|
if idx > 0: print("\n"+"="*32+"\n")
|
||||||
if network: print(f"Network ID : {network}")
|
if network: print(f"Network ID : {network}")
|
||||||
print(f"Name : {name}")
|
if transport_id: print(f"Transport ID : {transport_id}")
|
||||||
print(f"Type : {if_type}")
|
|
||||||
print(f"Status : {status_display}")
|
|
||||||
print(f"Transport : {transport_str}")
|
|
||||||
print(f"Distance : {i['hops']} hop{'' if i['hops'] == 1 else 's'}")
|
|
||||||
print(f"Discovered : {discovered_display}")
|
|
||||||
print(f"Last Heard : {last_heard_display}")
|
|
||||||
print(f"Location : {location}")
|
|
||||||
|
|
||||||
if "frequency" in i: print(f"Frequency : {i['frequency']:,} Hz")
|
print(f"Name : {name}")
|
||||||
if "bandwidth" in i: print(f"Bandwidth : {i['bandwidth']:,} Hz")
|
print(f"Type : {if_type}")
|
||||||
if "sf" in i: print(f"Sprd.Factor : {i['sf']}")
|
print(f"Status : {status_display}")
|
||||||
if "cr" in i: print(f"Coding Rate : {i['cr']}")
|
print(f"Transport : {transport_str}")
|
||||||
if "modulation" in i: print(f"Modulation : {i['modulation']}")
|
print(f"Distance : {i['hops']} hop{'' if i['hops'] == 1 else 's'}")
|
||||||
if "reachable_on" in i: print(f"Address : {i['reachable_on']}:{i['port']}")
|
print(f"Discovered : {discovered_display}")
|
||||||
|
print(f"Last Heard : {last_heard_display}")
|
||||||
|
print(f"Location : {location}")
|
||||||
|
|
||||||
print(f"Stamp Value : {i['value']}")
|
if "frequency" in i: print(f"Frequency : {i['frequency']:,} Hz")
|
||||||
|
if "bandwidth" in i: print(f"Bandwidth : {i['bandwidth']:,} Hz")
|
||||||
|
if "sf" in i: print(f"Sprd. Factor : {i['sf']}")
|
||||||
|
if "cr" in i: print(f"Coding Rate : {i['cr']}")
|
||||||
|
if "modulation" in i: print(f"Modulation : {i['modulation']}")
|
||||||
|
if "reachable_on" in i: print(f"Address : {i['reachable_on']}:{i['port']}")
|
||||||
|
|
||||||
|
print(f"Stamp Value : {i['value']}")
|
||||||
|
|
||||||
print(f"\nConfiguration Entry:")
|
print(f"\nConfiguration Entry:")
|
||||||
config_lines = i["config_entry"].split('\n')
|
config_lines = i["config_entry"].split('\n')
|
||||||
|
|||||||
Reference in New Issue
Block a user