diff --git a/RNS/Reticulum.py b/RNS/Reticulum.py index 9b067e62..a93f97ec 100755 --- a/RNS/Reticulum.py +++ b/RNS/Reticulum.py @@ -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, diff --git a/RNS/Transport.py b/RNS/Transport.py index fdbaa616..9f4f37c3 100755 --- a/RNS/Transport.py +++ b/RNS/Transport.py @@ -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: diff --git a/RNS/Utilities/rnsd.py b/RNS/Utilities/rnsd.py index b7313922..2091f025 100755 --- a/RNS/Utilities/rnsd.py +++ b/RNS/Utilities/rnsd.py @@ -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 diff --git a/docs/source/understanding.rst b/docs/source/understanding.rst index abd2d273..2c842219 100644 --- a/docs/source/understanding.rst +++ b/docs/source/understanding.rst @@ -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