From d25ea38c8402e67e4f458d33646d26cad2f6f6cb Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Sat, 22 Aug 2026 22:41:03 +0200 Subject: [PATCH] Added PPS stats to rnstatus. Don't count local shared instance in traffic totals. --- RNS/Reticulum.py | 2 ++ RNS/Transport.py | 22 +++++++++++++++++++++- RNS/Utilities/rnstatus.py | 13 ++++++++++--- 3 files changed, 33 insertions(+), 4 deletions(-) diff --git a/RNS/Reticulum.py b/RNS/Reticulum.py index 89b9bd40..7ecd6a71 100755 --- a/RNS/Reticulum.py +++ b/RNS/Reticulum.py @@ -1583,6 +1583,8 @@ class Reticulum: stats["ptxs"] = RNS.Transport.pr_speed_tx stats["prxf"] = RNS.Transport.pr_freq_rx stats["ptxf"] = RNS.Transport.pr_freq_tx + stats["rxpps"] = RNS.Transport.rx_pps + stats["txpps"] = RNS.Transport.tx_pps stats["rxqt"] = qsnapshot[0] stats["rxqd"] = qsnapshot[1][0] stats["rxqa"] = qsnapshot[1][1] diff --git a/RNS/Transport.py b/RNS/Transport.py index 19d65919..2e50f95d 100755 --- a/RNS/Transport.py +++ b/RNS/Transport.py @@ -281,6 +281,10 @@ class Transport: pr_speed_tx = 0 pr_freq_rx = 0 pr_freq_tx = 0 + rx_packets = 0 + tx_packets = 0 + rx_pps = 0 + tx_pps = 0 traffic_captured = None lowest_interface_bitrate = None highest_interface_bitrate = None @@ -509,7 +513,7 @@ class Transport: Transport.probe_destination = None RNS.log("Transport instance "+str(Transport.identity)+" started", RNS.LOG_VERBOSE) if RNS.sl(RNS.LOG_VERBOSE) else None - Transport.start_time = time.time() + Transport.start_time = time.time() # Sort interfaces according to bitrate Transport.prioritize_interfaces() @@ -578,6 +582,8 @@ class Transport: @staticmethod def count_traffic_loop(): + rxp = 0; txp = 0; cts = None + while True: time.sleep(1) try: @@ -588,6 +594,7 @@ class Transport: for interface in Transport.interfaces: if not hasattr(interface, "parent_interface") or interface.parent_interface == None: + if hasattr(interface, "is_local_shared_instance"): continue if hasattr(interface, "transport_traffic_counter"): now = time.time() @@ -630,7 +637,18 @@ class Transport: interface.transport_traffic_counter = { "ts": time.time(), "rxb": interface.rxb, "txb": interface.txb, "arxb": interface.arxb, "atxb": interface.atxb, "prxb": interface.prxb, "ptxb": interface.ptxb } + if not Transport.start_time: rpps = 0; tpps = 0 + else: + if not cts: ts = Transport.start_time + else: ts = cts + cts = time.time(); td = cts - ts + rpps = (Transport.rx_packets - rxp) / td + tpps = (Transport.tx_packets - txp) / td + rxp = Transport.rx_packets + txp = Transport.tx_packets + Transport.rx_pps = int(round(rpps)) + Transport.tx_pps = int(round(tpps)) Transport.traffic_rxb += rxb Transport.traffic_txb += txb Transport.speed_rx = rxs @@ -1276,6 +1294,7 @@ class Transport: interface.process_outgoing(masked_raw) else: interface.process_outgoing(raw) + Transport.tx_packets += 1 except Exception as e: RNS.log("Error while transmitting on "+str(interface)+". The contained exception was: "+str(e), RNS.LOG_ERROR) @@ -1705,6 +1724,7 @@ class Transport: if not Transport.packet_filter(packet): return interface.packet_filter_hit() traffic_class = tc or Transport.TC_DATA + Transport.rx_packets += 1 packet.receiving_interface = interface packet.hops += 1 diff --git a/RNS/Utilities/rnstatus.py b/RNS/Utilities/rnstatus.py index 1da09bd2..80d4ea97 100644 --- a/RNS/Utilities/rnstatus.py +++ b/RNS/Utilities/rnstatus.py @@ -155,7 +155,7 @@ def get_remote_status(destination_hash, include_lstats, identity, no_output=Fals def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json=False, astats=False, pstats=False, lstats=False, sorting=None, sort_reverse=False, remote=None, management_identity=None, must_exit=True, rns_instance=None, traffic_totals=False, discovered_interfaces=False, config_entries=False, burst_filter=False, blocked_ips=False, - queue_stats=False, remote_timeout=RNS.Transport.PATH_REQUEST_TIMEOUT): + queue_stats=False, pps=False, remote_timeout=RNS.Transport.PATH_REQUEST_TIMEOUT): if remote: require_shared = False else: require_shared = True @@ -736,6 +736,12 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= if stats["rxs"] > 0: rxstat = f"{rxstat}, {int(drxpct)}% data ({RNS.prettyspeed(drxs)})" if stats["txs"] > 0: txstat = f"{txstat}, {int(dtxpct)}% data ({RNS.prettyspeed(dtxs)})" + if pps: + rpps = RNS.prettysize(stats['rxpps'], suffix="pps") + tpps = RNS.prettysize(stats['txpps'], suffix="pps") + rxstat = f"{rxstat}, {rpps}" + txstat = f"{txstat}, {tpps}" + print(f"\n Totals : {txstat}\n {rxstat}") if pstats: @@ -830,6 +836,7 @@ def main(must_exit=True, rns_instance=None): parser.add_argument("-B", "--burst", action="store_true", help="only show interfaces with active bursts", default=False) parser.add_argument("-b", "--blocked-ips", action="store_true", help="show blocked IPs per interface", default=False) parser.add_argument("-t", "--totals", action="store_true", help="display traffic totals", default=False) + parser.add_argument("-p", "--pps", action="store_true", help="display packets per second in totals", default=False) parser.add_argument("-q", "--queues", action="store_true", help="display queue stats", default=False) parser.add_argument("-s", "--sort", action="store", help="sort interfaces by [rate, traffic, rx, tx, rxs, txs, announces, arx, atx, arxc, atxc, held, prx, ptx, prxc, ptxc, pvs, ivs, flt]", default=None, type=str) parser.add_argument("-r", "--reverse", action="store_true", help="reverse sorting", default=False) @@ -869,7 +876,7 @@ def main(must_exit=True, rns_instance=None): astats=args.announce_stats, pstats=args.pr_stats, lstats=args.link_stats, sorting=args.sort, sort_reverse=args.reverse, remote=args.R, management_identity=args.i, remote_timeout=args.w, must_exit=False, rns_instance=reticulum, traffic_totals=args.totals, discovered_interfaces=args.discovered, config_entries=args.D, burst_filter=args.burst, - blocked_ips=args.blocked_ips, queue_stats=args.queues) + blocked_ips=args.blocked_ips, queue_stats=args.queues, pps=args.pps) finally: sys.stdout = old_stdout @@ -887,7 +894,7 @@ def main(must_exit=True, rns_instance=None): astats=args.announce_stats, pstats=args.pr_stats, lstats=args.link_stats, sorting=args.sort, sort_reverse=args.reverse, remote=args.R, management_identity=args.i, remote_timeout=args.w, must_exit=must_exit, rns_instance=rns_instance, traffic_totals=args.totals, discovered_interfaces=args.discovered, config_entries=args.D, burst_filter=args.burst, - blocked_ips=args.blocked_ips, queue_stats=args.queues) + blocked_ips=args.blocked_ips, queue_stats=args.queues, pps=args.pps) except KeyboardInterrupt: print("")