Implemented path request ingress burst control and egress limiting

This commit is contained in:
Mark Qvist
2026-05-09 04:43:22 +02:00
parent e03c4ee455
commit f827d945be
6 changed files with 27 additions and 16 deletions
+2 -1
View File
@@ -661,10 +661,11 @@ class InterfaceDiscovery():
RNS.log(f"Auto-connecting discovered {interface_type} {interface_name}")
interface.autoconnect_hash = endpoint_hash
interface.autoconnect_source = info["network_id"]
mode = RNS.Interfaces.Interface.Interface.MODE_GATEWAY if RNS.Reticulum.transport_enabled() else None
ar_target = RNS.Reticulum.get_instance()._default_ar_target() if RNS.Reticulum.transport_enabled() else None
ar_penalty = RNS.Reticulum.get_instance()._default_ar_penalty() if RNS.Reticulum.transport_enabled() else None
ar_grace = RNS.Reticulum.get_instance()._default_ar_grace() if RNS.Reticulum.transport_enabled() else None
RNS.Reticulum.get_instance()._add_interface(interface, ifac_netname=ifac_netname, ifac_netkey=ifac_netkey, configured_bitrate=5E6,
RNS.Reticulum.get_instance()._add_interface(interface, mode=mode, ifac_netname=ifac_netname, ifac_netkey=ifac_netkey, configured_bitrate=5E6,
announce_rate_target=ar_target, announce_rate_grace=ar_grace, announce_rate_penalty=ar_penalty)
self.monitor_interface(interface)
+1 -1
View File
@@ -263,7 +263,7 @@ class BackboneInterface(Interface):
try: BackboneInterface.epoll.unregister(fileno)
except Exception as e:
RNS.log(f"An error occurred while deregistering file descriptor {fileno}: {e}", RNS.LOG_WARNING)
RNS.log(f"An error occurred while deregistering file descriptor {fileno}: {e}", RNS.LOG_DEBUG)
@staticmethod
def deregister_listeners():
+2 -2
View File
@@ -76,12 +76,12 @@ class Interface:
IC_BURST_FREQ_NEW = 3
IC_BURST_FREQ = 10
IC_PR_BURST_FREQ_NEW = 3
IC_PR_BURST_FREQ = 10
IC_PR_BURST_FREQ = 8
IC_BURST_HOLD = 15
IC_BURST_PENALTY = 15
IC_HELD_RELEASE_INTERVAL = 5
IC_DEQUE_MIN_SAMPLE = 2
IC_BURST_MIN_SAMPLES = 8
IC_BURST_MIN_SAMPLES = 6
EC_PR_FREQ = 5
EGRESS_CONTROL = False
+19 -9
View File
@@ -920,6 +920,7 @@ class Transport:
try:
for interface in Transport.interfaces:
interface.should_ingress_limit()
interface.should_ingress_limit_pr()
interface.process_held_announces()
if interface.phy_keepalive: interface.send_keepalive()
Transport.interface_last_jobs = time.time()
@@ -2182,8 +2183,7 @@ class Transport:
RNS.log("Invalid link request proof in transport for link "+RNS.prettyhexrep(packet.destination_hash)+", dropping proof.", RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
except Exception as e:
RNS.log("Error while transporting link request proof. The contained exception was: "+str(e), RNS.LOG_ERROR)
RNS.log("Could not transport link request proof. The contained exception was: "+str(e), RNS.LOG_WARNING)
else:
RNS.log("Link request proof received on wrong interface, not transporting it.", RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
else:
@@ -2895,15 +2895,16 @@ class Transport:
@staticmethod
def path_request(destination_hash, is_from_local_client, attached_interface, requestor_transport_id=None, tag=None):
should_search_for_unknown = False
should_ingress_limit = False
if attached_interface != None:
if RNS.Reticulum.transport_enabled() and attached_interface.mode in RNS.Interfaces.Interface.Interface.DISCOVER_PATHS_FOR:
should_search_for_unknown = True
interface_str = " on "+str(attached_interface)
else: interface_str = ""
should_ingress_limit = attached_interface.should_ingress_limit_pr()
if RNS.Reticulum.transport_enabled():
if attached_interface.mode in RNS.Interfaces.Interface.Interface.DISCOVER_PATHS_FOR: should_search_for_unknown = True
RNS.log("Path request for "+RNS.prettyhexrep(destination_hash)+interface_str, RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
if RNS.sl(RNS.LOG_DEBUG):
interface_str = f" on {attached_interface}"
RNS.log(f"Path request for {RNS.prettyhexrep(destination_hash)}{interface_str}", RNS.LOG_DEBUG)
destination_exists_on_local_client = False
if len(Transport.local_client_interfaces) > 0:
@@ -3000,6 +3001,15 @@ class Transport:
if destination_hash in Transport.discovery_path_requests:
RNS.log("There is already a waiting path request for "+RNS.prettyhexrep(destination_hash)+" on behalf of path request"+interface_str, RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
else:
# Abort recursive path request if receiving
# interface has PR burst active, or should
# otherwise ingress limit path requests.
if should_ingress_limit:
if RNS.sl(RNS.LOG_DEBUG):
interface_str = f" for {attached_interface}" if attached_interface else ""
RNS.log(f"Not sending recursive path request{interface_str} due to active ingress limiting", RNS.LOG_DEBUG)
return
# Forward path request on all interfaces
# except the requestor interface
RNS.log("Attempting to discover unknown path to "+RNS.prettyhexrep(destination_hash)+" on behalf of path request"+interface_str, RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
@@ -3009,7 +3019,7 @@ class Transport:
for interface in Transport.interfaces:
if not interface == attached_interface:
if interface.should_egress_limit_pr():
RNS.log(f"Not sending recursive path request on {interface} due to active egress limiting", RNS.LOG_DEBUG) if RNS.sl(RNS.LOG_DEBUG) else None
RNS.log(f"Not sending recursive path request on {interface} due to active egress limiting", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
else:
# Use the previously extracted tag from this path request
# on the new path requests as well, to avoid potential loops
+1 -1
View File
@@ -556,7 +556,7 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=
pburst_str = ""
if "pr_burst_active" in ifstat and ifstat["pr_burst_active"]:
for_str = RNS.prettytime(time.time()-ifstat["pr_burst_activated"])
pburst_str = f" burst for {for_str}"
pburst_str = f"burst for {for_str}"
rxb_str = ""+RNS.prettysize(ifstat["rxb"])
txb_str = ""+RNS.prettysize(ifstat["txb"])
+2 -2
View File
@@ -1460,10 +1460,10 @@ but all the parameters are exposed for configuration if needed.
* | The ``ic_pr_burst_freq_new`` option sets the maximum path request
ingress frequency for newly spawned interfaces. Defaults to ``3``
announces per second.
path requests per second.
* | The ``ic_pr_burst_freq`` option sets the maximum path request
ingress frequency for other interfaces. Defaults to ``10`` announces
ingress frequency for other interfaces. Defaults to ``8`` path requests
per second.
*If an interface exceeds its burst frequency, incoming path requests