Improved announce propagation logic

This commit is contained in:
Mark Qvist
2026-06-25 19:53:06 +02:00
parent 276b7bb92f
commit 98817e3f9d
4 changed files with 60 additions and 39 deletions
+10 -1
View File
@@ -252,6 +252,7 @@ class Reticulum:
Reticulum.__network_identity = None
Reticulum.__transport_enabled = False
Reticulum.__static_transport_identity = False
Reticulum.__link_mtu_discovery = Reticulum.LINK_MTU_DISCOVERY
Reticulum.__remote_management_enabled = False
Reticulum.__use_implicit_proof = True
@@ -347,7 +348,7 @@ class Reticulum:
self.rpc_type = "AF_INET"
if self.rpc_key == None:
self.rpc_key = RNS.Identity.full_hash(RNS.Transport.identity.get_private_key())
self.rpc_key = RNS.Identity.full_hash(RNS.Transport.internal_identity().get_private_key())
if self.is_shared_instance:
self.rpc_listener = multiprocessing.connection.Listener(self.rpc_addr, family=self.rpc_type, authkey=self.rpc_key)
@@ -500,6 +501,10 @@ class Reticulum:
v = self.config["reticulum"].as_bool(option)
if v == True: Reticulum.__transport_enabled = True
if option == "static_transport_identity":
v = self.config["reticulum"].as_bool(option)
if v == True: Reticulum.__static_transport_identity = True
if option == "network_identity":
if Reticulum.__network_identity == None:
path = self.config["reticulum"][option]
@@ -1853,6 +1858,10 @@ class Reticulum:
def max_autoconnected_interfaces():
return Reticulum.__autoconnect_discovered_interfaces
@staticmethod
def static_transport_identity():
return Reticulum.__static_transport_identity
# Default configuration file:
__default_rns_config__ = '''# This is the default Reticulum config file.
# You should probably edit it to include any additional,
+31 -29
View File
@@ -207,8 +207,12 @@ class Transport:
identity = None
network_identity = None
_identity = None
_should_run = True
@staticmethod
def internal_identity(): return Transport._identity
@staticmethod
def start(reticulum_instance):
Transport.owner = reticulum_instance
@@ -226,6 +230,12 @@ class Transport:
else:
RNS.log("Loaded Transport Identity from storage", RNS.LOG_VERBOSE) if RNS.sl(RNS.LOG_VERBOSE) else None
Transport._identity = Transport.identity
if not RNS.Reticulum.transport_enabled() and not RNS.Reticulum.static_transport_identity():
Transport._identity = Transport.identity
Transport.identity = RNS.Identity()
RNS.log(f"Initialized ephemeral transport identity {RNS.prettyhexrep(Transport.identity.hash)}", RNS.LOG_VERBOSE) if RNS.sl(RNS.LOG_VERBOSE) else None
packet_hashlist_path = RNS.Reticulum.storagepath+"/packet_hashlist"
if not Transport.owner.is_connected_to_shared_instance:
if os.path.isfile(packet_hashlist_path):
@@ -1192,69 +1202,61 @@ class Transport:
if packet.packet_type == RNS.Packet.ANNOUNCE:
if packet.attached_interface == None:
ac_loglevel = RNS.LOG_EXTREME
from_interface = Transport.next_hop_interface(packet.destination_hash)
local_destination = None
with Transport.destinations_map_lock:
if packet.destination_hash in Transport.destinations_map:
local_destination = Transport.destinations_map[packet.destination_hash]
if from_interface == None:
RNS.log("Blocking announce broadcast on "+str(interface)+" since next hop interface doesn't exist", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
if not local_destination and from_interface == None:
RNS.log("Blocking announce broadcast on "+str(interface)+" since next hop interface doesn't exist", ac_loglevel) if RNS.sl(ac_loglevel) else None
should_transmit = False
elif interface.announces_from_internal == False and from_interface.mode == RNS.Interfaces.Interface.Interface.MODE_INTERNAL:
RNS.log("Blocking announce broadcast on "+str(interface)+" due to internal-mode next hop interface", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
elif not local_destination and interface.announces_from_internal == False and from_interface.mode == RNS.Interfaces.Interface.Interface.MODE_INTERNAL:
RNS.log("Blocking announce broadcast on "+str(interface)+" due to internal-mode next hop interface", ac_loglevel) if RNS.sl(ac_loglevel) else None
should_transmit = False
elif interface.mode == RNS.Interfaces.Interface.Interface.MODE_ACCESS_POINT:
RNS.log("Blocking announce broadcast on "+str(interface)+" due to AP mode", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
RNS.log("Blocking announce broadcast on "+str(interface)+" due to AP mode", ac_loglevel) if RNS.sl(ac_loglevel) else None
should_transmit = False
elif interface.mode == RNS.Interfaces.Interface.Interface.MODE_INTERNAL:
elif not local_destination and interface.mode == RNS.Interfaces.Interface.Interface.MODE_INTERNAL:
if not hasattr(from_interface, "mode"):
should_transmit = False
RNS.log("Blocking announce broadcast on "+str(interface)+" since next hop interface has no mode configured", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
RNS.log("Blocking announce broadcast on "+str(interface)+" since next hop interface has no mode configured", ac_loglevel) if RNS.sl(ac_loglevel) else None
else:
if from_interface.mode == RNS.Interfaces.Interface.Interface.MODE_ROAMING:
RNS.log("Blocking announce broadcast on "+str(interface)+" due to roaming-mode next-hop interface", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
should_transmit = False
elif from_interface.mode == RNS.Interfaces.Interface.Interface.MODE_BOUNDARY:
RNS.log("Blocking announce broadcast on "+str(interface)+" due to boundary-mode next-hop interface", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
if from_interface.mode == RNS.Interfaces.Interface.Interface.MODE_BOUNDARY:
RNS.log("Blocking announce broadcast on "+str(interface)+" due to boundary-mode next-hop interface", ac_loglevel) if RNS.sl(ac_loglevel) else None
should_transmit = False
elif interface.mode == RNS.Interfaces.Interface.Interface.MODE_ROAMING:
local_destination = None
with Transport.destinations_map_lock:
if packet.destination_hash in Transport.destinations_map:
local_destination = Transport.destinations_map[packet.destination_hash]
if local_destination != None:
# RNS.log("Allowing announce broadcast on roaming-mode interface from instance-local destination", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
# RNS.log("Allowing announce broadcast on roaming-mode interface from instance-local destination", ac_loglevel) if RNS.sl(ac_loglevel) else None
pass
else:
if not hasattr(from_interface, "mode"):
should_transmit = False
RNS.log("Blocking announce broadcast on "+str(interface)+" since next hop interface has no mode configured", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
RNS.log("Blocking announce broadcast on "+str(interface)+" since next hop interface has no mode configured", ac_loglevel) if RNS.sl(ac_loglevel) else None
else:
if from_interface.mode == RNS.Interfaces.Interface.Interface.MODE_ROAMING:
RNS.log("Blocking announce broadcast on "+str(interface)+" due to roaming-mode next-hop interface", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
RNS.log("Blocking announce broadcast on "+str(interface)+" due to roaming-mode next-hop interface", ac_loglevel) if RNS.sl(ac_loglevel) else None
should_transmit = False
elif from_interface.mode == RNS.Interfaces.Interface.Interface.MODE_BOUNDARY:
RNS.log("Blocking announce broadcast on "+str(interface)+" due to boundary-mode next-hop interface", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
RNS.log("Blocking announce broadcast on "+str(interface)+" due to boundary-mode next-hop interface", ac_loglevel) if RNS.sl(ac_loglevel) else None
should_transmit = False
elif interface.mode == RNS.Interfaces.Interface.Interface.MODE_BOUNDARY:
local_destination = None
with Transport.destinations_map_lock:
if packet.destination_hash in Transport.destinations_map:
local_destination = Transport.destinations_map[packet.destination_hash]
if local_destination != None:
# RNS.log("Allowing announce broadcast on boundary-mode interface from instance-local destination", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
# RNS.log("Allowing announce broadcast on boundary-mode interface from instance-local destination", ac_loglevel) if RNS.sl(ac_loglevel) else None
pass
else:
if not hasattr(from_interface, "mode"):
should_transmit = False
RNS.log("Blocking announce broadcast on "+str(interface)+" since next hop interface has no mode configured", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
RNS.log("Blocking announce broadcast on "+str(interface)+" since next hop interface has no mode configured", ac_loglevel) if RNS.sl(ac_loglevel) else None
else:
if from_interface.mode == RNS.Interfaces.Interface.Interface.MODE_ROAMING:
RNS.log("Blocking announce broadcast on "+str(interface)+" due to roaming-mode next-hop interface", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
RNS.log("Blocking announce broadcast on "+str(interface)+" due to roaming-mode next-hop interface", ac_loglevel) if RNS.sl(ac_loglevel) else None
should_transmit = False
else:
+16 -6
View File
@@ -100,7 +100,7 @@ __example_rns_config__ = '''# This is an example Reticulum config file.
# always-on. This directive is optional and can be removed
# for brevity.
enable_transport = No
enable_transport = no
# By default, the first program to launch the Reticulum
@@ -112,7 +112,7 @@ enable_transport = No
# user, and should generally be turned on. This directive
# is optional and can be removed for brevity.
share_instance = Yes
share_instance = yes
# If you want to run multiple *different* shared instances
@@ -178,7 +178,7 @@ instance_name = default
# the network. If this option is enabled, Reticulum will
# collect interface information discovered from the network.
# discover_interfaces = No
# discover_interfaces = no
# If you only want to discover interfaces from specific
@@ -215,7 +215,7 @@ instance_name = default
# an optional directive, and can be left out for brevity.
# This behaviour is disabled by default.
# panic_on_interface_error = No
# panic_on_interface_error = no
# When Transport is enabled, it is possible to allow the
@@ -226,14 +226,15 @@ instance_name = default
# Transport Instance, and printed to the log at startup.
# Optional, and disabled by default.
# respond_to_probes = No
# respond_to_probes = no
# You can publish your local list of blackholed identities
# for other transport instances to use for automatic,
# network-wide blackhole management.
# publish_blackhole = No
# publish_blackhole = no
# List of remote transport identities from which to auto-
# matically source lists of blackholed identities.
@@ -248,12 +249,21 @@ instance_name = default
# blackhole_sources = 521c87a83afb8f29e4455e77930b973b
# You can set the interval in minutes at which remote
# blackhole sources are updated. Defaults to one hour.
# blackhole_update_interval = 60
# When not running as a transport node, it is possible to
# force the use of the same, static transport identity
# for every instance start. Defaults to using a new identity
# at every instance start, if transport is disabled.
# static_transport_identity = no
[logging]
# Valid log levels are 0 through 7:
# 0: Log only critical information
+3 -3
View File
@@ -732,7 +732,7 @@ Or, represented in table form:
Full ────── ✓ ──┐ ┌── ✓ ── Full
AP ──────── ✓ ──┤ ├── ✕ ── AP
Boundary ── ✕ ──┼─> Roaming >──┼── ✕ ── Boundary
Internal ── ✕ ──┤ ├── ── Internal
Internal ── ✕ ──┤ ├── ── Internal
Roaming ─── ✕ ──┘ └── ✕ ── Roaming
Full ────── ✓ ──┐ ┌── ✓ ── Full
@@ -745,7 +745,7 @@ Or, represented in table form:
AP ──────── ✓ ──┤ ├── ✕ ── AP
Boundary ── ✕ ──┼─> Internal >─┼── ✓ ── Boundary
Internal ── ✓ ──┤ ├── ✓ ── Internal
Roaming ─── ──┘ └── ✕ ── Roaming
Roaming ─── ──┘ └── ✕ ── Roaming
dest → Full AP Boundary Roaming Gateway Internal
source ↓
@@ -754,7 +754,7 @@ Or, represented in table form:
AP ✓ ✕ ✓ ✓ ✓ ✓
Boundary ✓ ✕ ✓ ✕ ✓ ✕
Internal ✓ ✕ ✓ ✕ ✓ ✓
Roaming ✓ ✕ ✕ ✕ ✓
Roaming ✓ ✕ ✕ ✕ ✓
✓ Will rebroadcast announce
✕ Will not rebroadcast announce