From 2f7129681629070110f993faab4234583a7256ed Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Sun, 17 Apr 2022 19:07:32 +0200 Subject: [PATCH] Basic interface rate estimation --- RNS/Interfaces/AutoInterface.py | 9 ++++++++- RNS/Interfaces/LocalInterface.py | 2 ++ RNS/Reticulum.py | 14 +++++++++++++- RNS/Transport.py | 3 ++- RNS/Utilities/rnstatus.py | 26 ++++++++++++++++++++++++-- 5 files changed, 49 insertions(+), 5 deletions(-) diff --git a/RNS/Interfaces/AutoInterface.py b/RNS/Interfaces/AutoInterface.py index 5e2c498..16427a9 100644 --- a/RNS/Interfaces/AutoInterface.py +++ b/RNS/Interfaces/AutoInterface.py @@ -46,7 +46,9 @@ class AutoInterface(Interface): DARWIN_IGNORE_IFS = ["awdl0", "llw0", "lo0", "en5"] ANDROID_IGNORE_IFS = ["dummy0", "lo", "tun0"] - def __init__(self, owner, name, group_id=None, discovery_scope=None, discovery_port=None, data_port=None, allowed_interfaces=None, ignored_interfaces=None): + BITRATE_GUESS = 10*1000*1000 + + def __init__(self, owner, name, group_id=None, discovery_scope=None, discovery_port=None, data_port=None, allowed_interfaces=None, ignored_interfaces=None, configured_bitrate=None): import importlib if importlib.util.find_spec('netifaces') != None: import netifaces @@ -217,6 +219,11 @@ class AutoInterface(Interface): time.sleep(peering_wait) + if configured_bitrate != None: + self.bitrate = configured_bitrate + else: + self.bitrate = AutoInterface.BITRATE_GUESS + self.online = True diff --git a/RNS/Interfaces/LocalInterface.py b/RNS/Interfaces/LocalInterface.py index 57a995d..613a887 100644 --- a/RNS/Interfaces/LocalInterface.py +++ b/RNS/Interfaces/LocalInterface.py @@ -76,6 +76,7 @@ class LocalClientInterface(Interface): self.connect() self.owner = owner + self.bitrate = 1000*1000*1000 self.online = True self.writing = False @@ -284,6 +285,7 @@ class LocalServerInterface(Interface): thread.setDaemon(True) thread.start() + self.bitrate = 1000*1000*1000 self.online = True diff --git a/RNS/Reticulum.py b/RNS/Reticulum.py index 4f4db57..19bb3f2 100755 --- a/RNS/Reticulum.py +++ b/RNS/Reticulum.py @@ -705,12 +705,24 @@ class Reticulum: else: ifstats["i2p_b32"] = None + if hasattr(interface, "bitrate"): + if interface.bitrate != None: + ifstats["bitrate"] = interface.bitrate + else: + ifstats["bitrate"] = None + + if hasattr(interface, "peers"): + if interface.peers != None: + ifstats["peers"] = len(interface.peers) + else: + ifstats["peers"] = None + ifstats["name"] = str(interface) ifstats["rxb"] = interface.rxb ifstats["txb"] = interface.txb ifstats["status"] = interface.online ifstats["mode"] = interface.mode - + stats.append(ifstats) return stats diff --git a/RNS/Transport.py b/RNS/Transport.py index 6a2ad65..e0fdf75 100755 --- a/RNS/Transport.py +++ b/RNS/Transport.py @@ -551,6 +551,7 @@ class Transport: if packet.attached_interface == None and interface.mode == RNS.Interfaces.Interface.Interface.MODE_ACCESS_POINT: RNS.log("Blocking announce broadcast on "+str(interface)+" due to AP mode", RNS.LOG_DEBUG) should_transmit = False + # TODO: Add capacity limit based on interface bandwidth if should_transmit: if not stored_hash: @@ -923,7 +924,7 @@ class Transport: local_rebroadcasts = 0 block_rebroadcasts = False attached_interface = None - retransmit_timeout = now + math.pow(Transport.PATHFINDER_C, packet.hops) + (PATHFINDER_D*packet.hops) + (RNS.rand() * Transport.PATHFINDER_RW) + retransmit_timeout = now + math.pow(Transport.PATHFINDER_C, packet.hops) + (Transport.PATHFINDER_D*packet.hops) + (RNS.rand() * Transport.PATHFINDER_RW) if packet.receiving_interface.mode == RNS.Interfaces.Interface.Interface.MODE_ACCESS_POINT: expires = now + Transport.AP_PATH_TIME diff --git a/RNS/Utilities/rnstatus.py b/RNS/Utilities/rnstatus.py index c0d8e09..f45b0f4 100644 --- a/RNS/Utilities/rnstatus.py +++ b/RNS/Utilities/rnstatus.py @@ -87,17 +87,23 @@ def program_setup(configdir, dispall=False, verbosity = 0): print(" {n}".format(n=ifstat["name"])) print(" Status : {ss}".format(ss=ss)) - + if clients != None: print(" "+clients_string) if not (name.startswith("Shared Instance[") or name.startswith("TCPInterface[Client") or name.startswith("LocalInterface[")): print(" Mode : {mode}".format(mode=modestr)) + if "bitrate" in ifstat and ifstat["bitrate"] != None: + print(" Rate : {ss}".format(ss=speed_str(ifstat["bitrate"]))) + + if "peers" in ifstat and ifstat["peers"] != None: + print(" Peers : {np} reachable".format(np=ifstat["peers"])) + if "i2p_b32" in ifstat: print(" I2P B32 : {ep}".format(ep=str(ifstat["i2p_b32"]))) - print(" RX : {rxb}\n TX : {txb}".format(rxb=size_str(ifstat["rxb"]), txb=size_str(ifstat["txb"]))) + print(" Traffic : ↑ {txb}\n ↓ {rxb}".format(rxb=size_str(ifstat["rxb"]), txb=size_str(ifstat["txb"]))) print("") @@ -133,5 +139,21 @@ def main(): print("") exit() +def speed_str(num, suffix='bps'): + units = ['','k','M','G','T','P','E','Z'] + last_unit = 'Y' + + if suffix == 'Bps': + num /= 8 + units = ['','K','M','G','T','P','E','Z'] + last_unit = 'Y' + + for unit in units: + if abs(num) < 1000.0: + return "%3.2f %s%s" % (num, unit, suffix) + num /= 1000.0 + + return "%.2f %s%s" % (num, last_unit, suffix) + if __name__ == "__main__": main()