Use canonical Transport interface list add/removes. Improved announce cache cleaning. Adjusted logging.

This commit is contained in:
Mark Qvist
2026-05-15 17:08:22 +02:00
parent d5b64a4af3
commit e7a317f0a0
10 changed files with 44 additions and 39 deletions
+1 -1
View File
@@ -576,7 +576,7 @@ class InterfaceDiscovery():
def teardown_interface(self, interface):
interface.detach()
if interface in RNS.Transport.interfaces: RNS.Transport.interfaces.remove(interface)
RNS.Transport.remove_interface(interface)
if interface in self.monitored_interfaces: self.monitored_interfaces.remove(interface)
def autoconnect_count(self):
+2 -2
View File
@@ -574,7 +574,7 @@ class AutoInterface(Interface):
spawned_interface.mode = self.mode
spawned_interface.HW_MTU = self.HW_MTU
spawned_interface.online = True
RNS.Transport.interfaces.append(spawned_interface)
RNS.Transport.add_interface(spawned_interface)
if addr in self.spawned_interfaces:
self.spawned_interfaces[addr].detach()
self.spawned_interfaces[addr].teardown()
@@ -666,7 +666,7 @@ class AutoInterfacePeer(Interface):
except Exception as e:
RNS.log(f"Could not remove {self} from parent interface on detach. The contained exception was: {e}", RNS.LOG_ERROR)
if self in RNS.Transport.interfaces: RNS.Transport.interfaces.remove(self)
RNS.Transport.remove_interface(self)
class AutoInterfaceHandler(socketserver.BaseRequestHandler):
def __init__(self, callback, *args, **keys):
+3 -4
View File
@@ -454,7 +454,7 @@ class BackboneInterface(Interface):
spawned_interface.HW_MTU = self.HW_MTU
spawned_interface.online = True
RNS.log("Spawned new BackboneClient Interface: "+str(spawned_interface), RNS.LOG_VERBOSE)
RNS.Transport.interfaces.append(spawned_interface)
RNS.Transport.add_interface(spawned_interface)
while spawned_interface in self.spawned_interfaces: self.spawned_interfaces.remove(spawned_interface)
self.spawned_interfaces.append(spawned_interface)
BackboneInterface.add_client_socket(socket, spawned_interface)
@@ -769,9 +769,8 @@ class BackboneClientInterface(Interface):
while self in self.parent_interface.spawned_interfaces:
self.parent_interface.spawned_interfaces.remove(self)
if self in RNS.Transport.interfaces:
if not self.initiator:
RNS.Transport.interfaces.remove(self)
if not self.initiator:
RNS.Transport.remove_interface(self)
def __str__(self):
+4 -5
View File
@@ -826,9 +826,8 @@ class I2PInterfacePeer(Interface):
while self in self.parent_interface.spawned_interfaces:
self.parent_interface.spawned_interfaces.remove(self)
if self in RNS.Transport.interfaces:
if not self.initiator:
RNS.Transport.interfaces.remove(self)
if not self.initiator:
RNS.Transport.remove_interface(self)
def __str__(self):
@@ -940,7 +939,7 @@ class I2PInterface(Interface):
peer_interface.IN = True
peer_interface.parent_interface = self
peer_interface.parent_count = False
RNS.Transport.interfaces.append(peer_interface)
RNS.Transport.add_interface(peer_interface)
def incoming_connection(self, handler):
RNS.log("Accepting incoming I2P connection", RNS.LOG_VERBOSE)
@@ -993,7 +992,7 @@ class I2PInterface(Interface):
spawned_interface.mode = self.mode
spawned_interface.HW_MTU = self.HW_MTU
RNS.log("Spawned new I2PInterface Peer: "+str(spawned_interface), RNS.LOG_VERBOSE)
RNS.Transport.interfaces.append(spawned_interface)
RNS.Transport.add_interface(spawned_interface)
while spawned_interface in self.spawned_interfaces:
self.spawned_interfaces.remove(spawned_interface)
self.spawned_interfaces.append(spawned_interface)
+3 -4
View File
@@ -347,8 +347,7 @@ class LocalClientInterface(Interface):
self.OUT = False
self.IN = False
if self in RNS.Transport.interfaces:
RNS.Transport.interfaces.remove(self)
RNS.Transport.remove_interface(self)
if self in RNS.Transport.local_client_interfaces:
RNS.Transport.local_client_interfaces.remove(self)
@@ -458,7 +457,7 @@ class LocalServerInterface(Interface):
spawned_interface.socket_path = self.socket_path
if hasattr(self, "_force_bitrate"): spawned_interface._force_bitrate = self._force_bitrate
RNS.Transport.interfaces.append(spawned_interface)
RNS.Transport.add_interface(spawned_interface)
RNS.Transport.local_client_interfaces.append(spawned_interface)
BackboneInterface.add_client_socket(client_socket, spawned_interface)
self.clients += 1
@@ -474,7 +473,7 @@ class LocalServerInterface(Interface):
spawned_interface.parent_interface = self
spawned_interface.bitrate = self.bitrate
if hasattr(self, "_force_bitrate"): spawned_interface._force_bitrate = self._force_bitrate
RNS.Transport.interfaces.append(spawned_interface)
RNS.Transport.add_interface(spawned_interface)
RNS.Transport.local_client_interfaces.append(spawned_interface)
self.clients += 1
spawned_interface.read_loop()
+2 -3
View File
@@ -375,7 +375,7 @@ class RNodeMultiInterface(Interface):
interface.mode = self.mode
interface.HW_MTU = self.HW_MTU
interface.detected = True
RNS.Transport.interfaces.append(interface)
RNS.Transport.add_interface(interface)
RNS.log("Spawned new RNode subinterface: "+str(interface), RNS.LOG_VERBOSE)
self.clients += 1
@@ -909,8 +909,7 @@ class RNodeMultiInterface(Interface):
def teardown_subinterfaces(self):
for interface in self.subinterfaces:
if interface != 0:
if interface in RNS.Transport.interfaces:
RNS.Transport.interfaces.remove(interface)
RNS.Transport.remove_interface(interface)
self.subinterfaces[interface.index] = 0
def should_ingress_limit(self):
+3 -4
View File
@@ -436,9 +436,8 @@ class TCPClientInterface(Interface):
while self in self.parent_interface.spawned_interfaces:
self.parent_interface.spawned_interfaces.remove(self)
if self in RNS.Transport.interfaces:
if not self.initiator:
RNS.Transport.interfaces.remove(self)
if not self.initiator:
RNS.Transport.remove_interface(self)
def __str__(self):
@@ -627,7 +626,7 @@ class TCPServerInterface(Interface):
spawned_interface.HW_MTU = self.HW_MTU
spawned_interface.online = True
RNS.log("Spawned new TCPClient Interface: "+str(spawned_interface), RNS.LOG_VERBOSE)
RNS.Transport.interfaces.append(spawned_interface)
RNS.Transport.add_interface(spawned_interface)
while spawned_interface in self.spawned_interfaces:
self.spawned_interfaces.remove(spawned_interface)
self.spawned_interfaces.append(spawned_interface)
+2 -3
View File
@@ -981,7 +981,7 @@ class WeaveInterface(Interface):
spawned_interface.mode = self.mode
spawned_interface.HW_MTU = self.HW_MTU
spawned_interface._online = True
RNS.Transport.interfaces.append(spawned_interface)
RNS.Transport.add_interface(spawned_interface)
if endpoint_addr in self.spawned_interfaces:
self.spawned_interfaces[endpoint_addr].detach()
self.spawned_interfaces[endpoint_addr].teardown()
@@ -1097,5 +1097,4 @@ class WeaveInterfacePeer(Interface):
except Exception as e:
RNS.log(f"Could not remove {self} from parent interface on detach. The contained exception was: {e}", RNS.LOG_ERROR)
if self in RNS.Transport.interfaces:
RNS.Transport.interfaces.remove(self)
RNS.Transport.remove_interface(self)
+4 -4
View File
@@ -402,7 +402,7 @@ class Reticulum:
RNS.log("Existing shared instance required, but this instance started as shared instance. Aborting startup.", RNS.LOG_VERBOSE)
else:
RNS.Transport.interfaces.append(interface)
RNS.Transport.add_interface(interface)
self.shared_instance_interface = interface
self.is_shared_instance = True
RNS.log("Started shared instance interface: "+str(interface), RNS.LOG_DEBUG)
@@ -422,7 +422,7 @@ class Reticulum:
interface._force_bitrate = True
RNS.log(f"Forcing shared instance bitrate of {RNS.prettyspeed(interface.bitrate)}", RNS.LOG_WARNING)
interface.optimise_mtu()
RNS.Transport.interfaces.append(interface)
RNS.Transport.add_interface(interface)
self.is_shared_instance = False
self.is_standalone_instance = False
self.is_connected_to_shared_instance = True
@@ -915,7 +915,7 @@ class Reticulum:
interface.ifac_identity = RNS.Identity.from_bytes(interface.ifac_key)
interface.ifac_signature = interface.ifac_identity.sign(RNS.Identity.full_hash(interface.ifac_key))
RNS.Transport.interfaces.append(interface)
RNS.Transport.add_interface(interface)
interface.final_init()
interface = None
@@ -1077,7 +1077,7 @@ class Reticulum:
interface.ifac_identity = RNS.Identity.from_bytes(interface.ifac_key)
interface.ifac_signature = interface.ifac_identity.sign(RNS.Identity.full_hash(interface.ifac_key))
RNS.Transport.interfaces.append(interface)
RNS.Transport.add_interface(interface)
interface.final_init()
def _default_ar_target(self):
+20 -9
View File
@@ -417,6 +417,18 @@ class Transport:
gc.collect()
@staticmethod
def add_interface(interface):
with Transport.interfaces_lock:
if not interface in Transport.interfaces:
Transport.interfaces.append(interface)
@staticmethod
def remove_interface(interface):
with Transport.interfaces_lock:
if interface in Transport.interfaces:
Transport.interfaces.remove(interface)
@staticmethod
def set_network_identity(identity):
if not Transport.network_identity:
@@ -1594,7 +1606,7 @@ class Transport:
RNS.log(f"Clamping link MTU to {RNS.prettysize(path_mtu)}", RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
new_raw = new_raw[:-RNS.Link.LINK_MTU_SIZE]+clamped_mtu
except Exception as e:
RNS.log(f"Dropping link request packet. The contained exception was: {e}", RNS.LOG_WARNING)
RNS.log(f"Dropping link request packet. The contained exception was: {e}", RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
return
# Entry format is
@@ -2518,16 +2530,17 @@ class Transport:
def clean_announce_cache():
st = time.time()
target_path = os.path.join(RNS.Reticulum.cachepath, "announces")
with Transport.path_table_lock: active_paths = [Transport.path_table[dst_hash][6] for dst_hash in Transport.path_table]
with Transport.tunnels_lock: tunnel_paths = list(set([path_dict[dst_hash][6] for path_dict in [Transport.tunnels[tunnel_id][2] for tunnel_id in Transport.tunnels] for dst_hash in path_dict]))
cached_announce_hashes = os.listdir(target_path)
with Transport.path_table_lock: active_path_hashes = list(set([Transport.path_table[dst_hash][IDX_PT_PACKET] for dst_hash in Transport.path_table]))
with Transport.tunnels_lock: tunnel_path_hashes = list(set([path_dict[dst_hash][IDX_PT_PACKET] for path_dict in [Transport.tunnels[tunnel_id][IDX_TT_PATHS] for tunnel_id in Transport.tunnels] for dst_hash in path_dict]))
removed = 0; total = 0
for packet_hash in os.listdir(target_path):
for packet_hash in cached_announce_hashes:
remove = False
full_path = os.path.join(target_path, packet_hash)
if os.path.isfile(full_path):
try: target_hash = bytes.fromhex(packet_hash)
except: remove = True
if (not target_hash in active_paths) and (not target_hash in tunnel_paths): remove = True
if (not target_hash in active_path_hashes) and (not target_hash in tunnel_path_hashes): remove = True
if remove: os.unlink(full_path); removed += 1
total += 1
@@ -2889,10 +2902,8 @@ class Transport:
tag=tag_bytes)
else: RNS.log("Ignoring duplicate path request for "+RNS.prettyhexrep(destination_hash)+" with tag "+RNS.prettyhexrep(unique_tag), RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
else: RNS.log("Ignoring tagless path request for "+RNS.prettyhexrep(destination_hash), RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
except Exception as e: RNS.log("Error while handling path request. The contained exception was: "+str(e), RNS.LOG_ERROR)
except Exception as e: RNS.log(f"Error while handling path request. The contained exception was: {e}", RNS.LOG_ERROR)
@staticmethod
def path_request(destination_hash, is_from_local_client, attached_interface, requestor_transport_id=None, tag=None):
@@ -2933,7 +2944,7 @@ class Transport:
received_from = Transport.path_table[destination_hash][IDX_PT_RVCD_IF]
if packet == None:
RNS.log("Could not retrieve announce packet from cache while answering path request for "+RNS.prettyhexrep(destination_hash), RNS.LOG_WARNING)
RNS.log(f"Could not retrieve announce packet from cache while answering path request for {RNS.prettyhexrep(destination_hash)}, ignoring path request", RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
elif attached_interface.mode == RNS.Interfaces.Interface.Interface.MODE_ROAMING and attached_interface == received_from:
RNS.log("Not answering path request on roaming-mode interface, since next hop is on same roaming-mode interface", RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None