diff --git a/RNS/Interfaces/BackboneInterface.py b/RNS/Interfaces/BackboneInterface.py index a0d20764..4684d5f2 100644 --- a/RNS/Interfaces/BackboneInterface.py +++ b/RNS/Interfaces/BackboneInterface.py @@ -523,17 +523,25 @@ class BackboneInterface(Interface): return True - def received_announce(self, from_spawned=False): - if from_spawned: self.ia_freq_deque.append(time.time()) + def received_announce(self, size=0, from_spawned=False): + if from_spawned: + self.ia_freq_deque.append(time.time()) + self.arxb += size - def sent_announce(self, from_spawned=False): - if from_spawned: self.oa_freq_deque.append(time.time()) + def sent_announce(self, size=0, from_spawned=False): + if from_spawned: + self.oa_freq_deque.append(time.time()) + self.atxb += size - def received_path_request(self, from_spawned=False): - if from_spawned: self.ip_freq_deque.append(time.time()) + def received_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.ip_freq_deque.append(time.time()) + self.prxb += size - def sent_path_request(self, from_spawned=False): - if from_spawned: self.op_freq_deque.append(time.time()) + def sent_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.op_freq_deque.append(time.time()) + self.ptxb += size def process_outgoing(self, data): pass diff --git a/RNS/Interfaces/I2PInterface.py b/RNS/Interfaces/I2PInterface.py index 381e50c5..f8a562c6 100644 --- a/RNS/Interfaces/I2PInterface.py +++ b/RNS/Interfaces/I2PInterface.py @@ -871,17 +871,25 @@ class I2PInterface(Interface): def process_outgoing(self, data): pass - def received_announce(self, from_spawned=False): - if from_spawned: self.ia_freq_deque.append(time.time()) + def received_announce(self, size=0, from_spawned=False): + if from_spawned: + self.ia_freq_deque.append(time.time()) + self.arxb += size - def sent_announce(self, from_spawned=False): - if from_spawned: self.oa_freq_deque.append(time.time()) + def sent_announce(self, size=0, from_spawned=False): + if from_spawned: + self.oa_freq_deque.append(time.time()) + self.atxb += size - def received_path_request(self, from_spawned=False): - if from_spawned: self.ip_freq_deque.append(time.time()) + def received_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.ip_freq_deque.append(time.time()) + self.prxb += size - def sent_path_request(self, from_spawned=False): - if from_spawned: self.op_freq_deque.append(time.time()) + def sent_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.op_freq_deque.append(time.time()) + self.ptxb += size def detach(self): RNS.log("Detaching "+str(self), RNS.LOG_DEBUG) diff --git a/RNS/Interfaces/Interface.py b/RNS/Interfaces/Interface.py index 421e1952..543d5275 100755 --- a/RNS/Interfaces/Interface.py +++ b/RNS/Interfaces/Interface.py @@ -97,6 +97,10 @@ class Interface: def __init__(self): self.rxb = 0 self.txb = 0 + self.arxb = 0 + self.atxb = 0 + self.prxb = 0 + self.ptxb = 0 self.gravity = 0 self.created = time.time() self.detached = False @@ -258,25 +262,29 @@ class Interface: RNS.log("An error occurred while processing held announces for "+str(self), RNS.LOG_ERROR) RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR) - def received_announce(self, from_spawned=False): + def received_announce(self, size=0, from_spawned=False): + self.arxb += size self.ia_freq_deque.append(time.time()) if hasattr(self, "parent_interface") and self.parent_interface != None: - self.parent_interface.received_announce(from_spawned=True) + self.parent_interface.received_announce(size=size, from_spawned=True) - def sent_announce(self, from_spawned=False): + def sent_announce(self, size=0, from_spawned=False): + self.atxb += size self.oa_freq_deque.append(time.time()) if hasattr(self, "parent_interface") and self.parent_interface != None: - self.parent_interface.sent_announce(from_spawned=True) + self.parent_interface.sent_announce(size=size, from_spawned=True) - def received_path_request(self, from_spawned=False): + def received_path_request(self, size=0, from_spawned=False): + self.prxb += size self.ip_freq_deque.append(time.time()) if hasattr(self, "parent_interface") and self.parent_interface != None: - self.parent_interface.received_path_request(from_spawned=True) + self.parent_interface.received_path_request(size=size, from_spawned=True) - def sent_path_request(self, from_spawned=False): + def sent_path_request(self, size=0, from_spawned=False): + self.ptxb += size self.op_freq_deque.append(time.time()) if hasattr(self, "parent_interface") and self.parent_interface != None: - self.parent_interface.sent_path_request(from_spawned=True) + self.parent_interface.sent_path_request(size=size, from_spawned=True) @property def ic_burst_count(self): return None @@ -351,12 +359,13 @@ class Interface: selected = entries[0] now = time.time() - tx_time = (len(selected["raw"])*8) / self.bitrate + tx_size = len(selected["raw"]) + tx_time = (tx_size*8) / self.bitrate wait_time = (tx_time / self.announce_cap) self.announce_allowed_at = now + wait_time self.process_outgoing(selected["raw"]) - self.sent_announce() + self.sent_announce(tx_size) if selected in self.announce_queue: self.announce_queue.remove(selected) diff --git a/RNS/Interfaces/LocalInterface.py b/RNS/Interfaces/LocalInterface.py index a214c124..8afa83a0 100644 --- a/RNS/Interfaces/LocalInterface.py +++ b/RNS/Interfaces/LocalInterface.py @@ -481,17 +481,25 @@ class LocalServerInterface(Interface): def process_outgoing(self, data): pass - def received_announce(self, from_spawned=False): - if from_spawned: self.ia_freq_deque.append(time.time()) + def received_announce(self, size=0, from_spawned=False): + if from_spawned: + self.ia_freq_deque.append(time.time()) + self.arxb += size - def sent_announce(self, from_spawned=False): - if from_spawned: self.oa_freq_deque.append(time.time()) + def sent_announce(self, size=0, from_spawned=False): + if from_spawned: + self.oa_freq_deque.append(time.time()) + self.atxb += size - def received_path_request(self, from_spawned=False): - if from_spawned: self.ip_freq_deque.append(time.time()) + def received_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.ip_freq_deque.append(time.time()) + self.prxb += size - def sent_path_request(self, from_spawned=False): - if from_spawned: self.op_freq_deque.append(time.time()) + def sent_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.op_freq_deque.append(time.time()) + self.ptxb += size def __str__(self): if self.socket_path: return "Shared Instance["+str(self.socket_path.replace("\0", ""))+"]" diff --git a/RNS/Interfaces/RNodeMultiInterface.py b/RNS/Interfaces/RNodeMultiInterface.py index d311e736..1ed8e772 100644 --- a/RNS/Interfaces/RNodeMultiInterface.py +++ b/RNS/Interfaces/RNodeMultiInterface.py @@ -543,17 +543,25 @@ class RNodeMultiInterface(Interface): if written != len(frame): raise IOError("Serial interface only wrote "+str(written)+" bytes of "+str(len(data))) - def received_announce(self, from_spawned=False): - if from_spawned: self.ia_freq_deque.append(time.time()) + def received_announce(self, size=0, from_spawned=False): + if from_spawned: + self.ia_freq_deque.append(time.time()) + self.arxb += size - def sent_announce(self, from_spawned=False): - if from_spawned: self.oa_freq_deque.append(time.time()) + def sent_announce(self, size=0, from_spawned=False): + if from_spawned: + self.oa_freq_deque.append(time.time()) + self.atxb += size - def received_path_request(self, from_spawned=False): - if from_spawned: self.ip_freq_deque.append(time.time()) + def received_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.ip_freq_deque.append(time.time()) + self.prxb += size - def sent_path_request(self, from_spawned=False): - if from_spawned: self.op_freq_deque.append(time.time()) + def sent_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.op_freq_deque.append(time.time()) + self.ptxb += size def readLoop(self): try: diff --git a/RNS/Interfaces/TCPInterface.py b/RNS/Interfaces/TCPInterface.py index 90c9ea3b..c0b66ba1 100644 --- a/RNS/Interfaces/TCPInterface.py +++ b/RNS/Interfaces/TCPInterface.py @@ -646,17 +646,25 @@ class TCPServerInterface(Interface): self.spawned_interfaces.append(spawned_interface) spawned_interface.read_loop() - def received_announce(self, from_spawned=False): - if from_spawned: self.ia_freq_deque.append(time.time()) + def received_announce(self, size=0, from_spawned=False): + if from_spawned: + self.ia_freq_deque.append(time.time()) + self.arxb += size - def sent_announce(self, from_spawned=False): - if from_spawned: self.oa_freq_deque.append(time.time()) + def sent_announce(self, size=0, from_spawned=False): + if from_spawned: + self.oa_freq_deque.append(time.time()) + self.atxb += size - def received_path_request(self, from_spawned=False): - if from_spawned: self.ip_freq_deque.append(time.time()) + def received_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.ip_freq_deque.append(time.time()) + self.prxb += size - def sent_path_request(self, from_spawned=False): - if from_spawned: self.op_freq_deque.append(time.time()) + def sent_path_request(self, size=0, from_spawned=False): + if from_spawned: + self.op_freq_deque.append(time.time()) + self.ptxb += size def process_outgoing(self, data): pass diff --git a/RNS/Reticulum.py b/RNS/Reticulum.py index 1754d966..7cf8ddd0 100755 --- a/RNS/Reticulum.py +++ b/RNS/Reticulum.py @@ -1471,6 +1471,26 @@ class Reticulum: else: ifstats["txs"] = 0 else: ifstats["txs"] = 0 + if hasattr(interface, "current_arx_speed"): + if interface.current_arx_speed != None: ifstats["arxs"] = interface.current_arx_speed + else: ifstats["arxs"] = 0 + else: ifstats["arxs"] = 0 + + if hasattr(interface, "current_atx_speed"): + if interface.current_atx_speed != None: ifstats["atxs"] = interface.current_atx_speed + else: ifstats["atxs"] = 0 + else: ifstats["atxs"] = 0 + + if hasattr(interface, "current_prx_speed"): + if interface.current_prx_speed != None: ifstats["prxs"] = interface.current_prx_speed + else: ifstats["prxs"] = 0 + else: ifstats["prxs"] = 0 + + if hasattr(interface, "current_ptx_speed"): + if interface.current_ptx_speed != None: ifstats["ptxs"] = interface.current_ptx_speed + else: ifstats["ptxs"] = 0 + else: ifstats["ptxs"] = 0 + if hasattr(interface, "peers"): if interface.peers != None: ifstats["peers"] = len(interface.peers) else: ifstats["peers"] = None @@ -1503,6 +1523,10 @@ class Reticulum: ifstats["type"] = str(type(interface).__name__) ifstats["rxb"] = interface.rxb ifstats["txb"] = interface.txb + ifstats["arxb"] = interface.arxb + ifstats["atxb"] = interface.atxb + ifstats["prxb"] = interface.prxb + ifstats["ptxb"] = interface.ptxb ifstats["incoming_announce_frequency"] = interface.incoming_announce_frequency() ifstats["outgoing_announce_frequency"] = interface.outgoing_announce_frequency() ifstats["incoming_pr_frequency"] = interface.incoming_pr_frequency() @@ -1537,6 +1561,14 @@ class Reticulum: stats["txb"] = RNS.Transport.traffic_txb stats["rxs"] = RNS.Transport.speed_rx stats["txs"] = RNS.Transport.speed_tx + stats["arxb"] = RNS.Transport.announce_rxb + stats["atxb"] = RNS.Transport.announce_txb + stats["arxs"] = RNS.Transport.announce_speed_rx + stats["atxs"] = RNS.Transport.announce_speed_tx + stats["prxb"] = RNS.Transport.pr_rxb + stats["ptxb"] = RNS.Transport.pr_txb + stats["prxs"] = RNS.Transport.pr_speed_rx + stats["ptxs"] = RNS.Transport.pr_speed_tx 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 eeebec0e..b2e3ca83 100755 --- a/RNS/Transport.py +++ b/RNS/Transport.py @@ -265,8 +265,16 @@ class Transport: traffic_rxb = 0 traffic_txb = 0 + announce_rxb = 0 + announce_txb = 0 + pr_rxb = 0 + pr_txb = 0 speed_rx = 0 speed_tx = 0 + announce_speed_rx = 0 + announce_speed_tx = 0 + pr_speed_rx = 0 + pr_speed_tx = 0 traffic_captured = None lowest_interface_bitrate = None highest_interface_bitrate = None @@ -541,9 +549,9 @@ class Transport: try: Transport.interfaces.sort(key=lambda interface: interface.bitrate, reverse=True) except Exception as e: RNS.log(f"Could not prioritize interfaces according to bitrate. The contained exception was: {e}", RNS.LOG_ERROR) try: Transport.lowest_interface_bitrate = min((interface.bitrate for interface in Transport.interfaces if interface.online and interface.bitrate)) - except Exception as e: RNS.log(f"Could not get lowest interface bitrate. The contained exception was: {e}", RNS.LOG_ERROR) + except Exception as e: RNS.log(f"Could not get lowest interface bitrate. The contained exception was: {e}", RNS.LOG_DEBUG) try: Transport.highest_interface_bitrate = max((interface.bitrate for interface in Transport.interfaces if interface.online and interface.bitrate)) - except Exception as e: RNS.log(f"Could not get highest interface bitrate. The contained exception was: {e}", RNS.LOG_ERROR) + except Exception as e: RNS.log(f"Could not get highest interface bitrate. The contained exception was: {e}", RNS.LOG_DEBUG) @staticmethod def enable_discovery(): @@ -567,31 +575,62 @@ class Transport: while True: time.sleep(1) try: - rxb = 0; txb = 0; - rxs = 0; txs = 0; + rxb = 0; txb = 0; rxs = 0; txs = 0; + arxb = 0; atxb = 0; arxs = 0; atxs = 0; + prxb = 0; ptxb = 0; prxs = 0; ptxs = 0; + for interface in Transport.interfaces: if not hasattr(interface, "parent_interface") or interface.parent_interface == None: if hasattr(interface, "transport_traffic_counter"): - now = time.time(); irxb = interface.rxb; itxb = interface.txb + now = time.time() + + irxb = interface.rxb; itxb = interface.txb + iarxb = interface.arxb; iatxb = interface.atxb + iprxb = interface.prxb; iptxb = interface.ptxb + tc = interface.transport_traffic_counter - rx_diff = irxb - tc["rxb"] - tx_diff = itxb - tc["txb"] ts_diff = now - tc["ts"] - rxb += rx_diff; crxs = (rx_diff*8)/ts_diff - txb += tx_diff; ctxs = (tx_diff*8)/ts_diff - interface.current_rx_speed = crxs; rxs += crxs - interface.current_tx_speed = ctxs; txs += ctxs - tc["rxb"] = irxb; - tc["txb"] = itxb; - tc["ts"] = now; + + rx_diff = irxb - tc["rxb"]; tx_diff = itxb - tc["txb"] + arx_diff = iarxb - tc["arxb"]; atx_diff = iatxb - tc["atxb"] + prx_diff = iprxb - tc["prxb"]; ptx_diff = iptxb - tc["ptxb"] + + rxb += rx_diff; crxs = (rx_diff*8)/ts_diff + txb += tx_diff; ctxs = (tx_diff*8)/ts_diff + arxb += arx_diff; carxs = (arx_diff*8)/ts_diff + atxb += atx_diff; catxs = (atx_diff*8)/ts_diff + prxb += prx_diff; cprxs = (prx_diff*8)/ts_diff + ptxb += ptx_diff; cptxs = (ptx_diff*8)/ts_diff + + interface.current_rx_speed = crxs; rxs += crxs + interface.current_tx_speed = ctxs; txs += ctxs + interface.current_arx_speed = carxs; arxs += carxs + interface.current_atx_speed = catxs; atxs += catxs + interface.current_prx_speed = cprxs; prxs += cprxs + interface.current_ptx_speed = cptxs; ptxs += cptxs + + tc["ts"] = now + tc["rxb"] = irxb; tc["txb"] = itxb + tc["arxb"] = iarxb; tc["atxb"] = iatxb + tc["prxb"] = iprxb; tc["ptxb"] = iptxb else: - interface.transport_traffic_counter = {"ts": time.time(), "rxb": interface.rxb, "txb": interface.txb} + 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 } - Transport.traffic_rxb += rxb - Transport.traffic_txb += txb - Transport.speed_rx = rxs - Transport.speed_tx = txs + Transport.traffic_rxb += rxb + Transport.traffic_txb += txb + Transport.speed_rx = rxs + Transport.speed_tx = txs + Transport.announce_rxb += arxb + Transport.announce_txb += atxb + Transport.announce_speed_rx = arxs + Transport.announce_speed_tx = atxs + Transport.pr_rxb += prxb + Transport.pr_txb += ptxb + Transport.pr_speed_rx = prxs + Transport.pr_speed_tx = ptxs except Exception as e: RNS.log(f"An error occurred while counting interface traffic: {e}", RNS.LOG_ERROR) @@ -1467,8 +1506,8 @@ class Transport: else: raw = Transport.mangle_hops(packet.raw, Transport.local_hops_delta, transport_insert=packet.header_type==RNS.Packet.HEADER_1) Transport.transmit(interface, raw) - if packet.packet_type == RNS.Packet.ANNOUNCE: interface.sent_announce() - if packet.destination.type == RNS.Destination.PLAIN and packet.is_outbound_pr: interface.sent_path_request() + if packet.packet_type == RNS.Packet.ANNOUNCE: interface.sent_announce(size=len(raw)) + if packet.destination.type == RNS.Destination.PLAIN and packet.is_outbound_pr: interface.sent_path_request(size=len(raw)) packet_sent(packet) sent = True @@ -1626,7 +1665,7 @@ class Transport: if not tc: traffic_class = Transport.TC_ANNOUNCE announce_signature_valid = RNS.Identity.validate_announce(packet, only_validate_signature=True) if not announce_signature_valid: return - elif packet.receiving_interface != None: packet.receiving_interface.received_announce() + elif packet.receiving_interface != None: packet.receiving_interface.received_announce(size=len(packet.raw)) announced_destination_known = packet.destination_hash in Transport.path_table if not announced_destination_known: @@ -1670,7 +1709,7 @@ class Transport: 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 return - if packet.receiving_interface: packet.receiving_interface.received_path_request() + if packet.receiving_interface: packet.receiving_interface.received_path_request(size=len(raw)) if interface.should_ingress_limit_pr(): traffic_class = Transport.TC_INGRESS_LIMITED diff --git a/RNS/Utilities/rnstatus.py b/RNS/Utilities/rnstatus.py index 304f37e1..1f768ed9 100644 --- a/RNS/Utilities/rnstatus.py +++ b/RNS/Utilities/rnstatus.py @@ -603,8 +603,16 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= cspec = "c" if clients == None and "peers" in ifstat and ifstat["peers"]: clients = ifstat["peers"]; cspec = "p" - if clients != None and clients > 0: pc_str = f"{RNS.prettyfrequency(ifstat['outgoing_announce_frequency']/clients, d=1, lpf=True)}/{cspec}" + if clients != None and clients > 0: pc_str = f" {RNS.prettyfrequency(ifstat['outgoing_announce_frequency']/clients, d=1, lpf=True)}/{cspec}" else: pc_str = "" + + if "prxs" in ifstat and "rxs" in ifstat and "ptxs" in ifstat and "txs" in ifstat: + arxspct = min(100.0, (ifstat["arxs"] / ifstat["rxs"])*100.0) if ifstat["rxs"] and ifstat["arxs"] else 0.0 + atxspct = min(100.0, (ifstat["atxs"] / ifstat["txs"])*100.0) if ifstat["txs"] and ifstat["atxs"] else 0.0 + apctstr = f"(↓{int(arxspct)}% / ↑{int(atxspct)}% of flow)" + if pc_str: pc_str = f"{pc_str} {apctstr}" + else: pc_str = f"{apctstr}" + asr = True psr = False @@ -620,8 +628,16 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= ipf = RNS.prettyfrequency(ipn,d=1, lpf=True)+"↓" cspec = "c" if clients == None and "peers" in ifstat and ifstat["peers"]: clients = ifstat["peers"]; cspec = "p" - if clients != None and clients > 0: rpc_str = f"{RNS.prettyfrequency(ifstat['outgoing_pr_frequency']/clients, d=1, lpf=True)}/{cspec}" + if clients != None and clients > 0: rpc_str = f" {RNS.prettyfrequency(ifstat['outgoing_pr_frequency']/clients, d=1, lpf=True)}/{cspec}" else: rpc_str = "" + + if "prxs" in ifstat and "rxs" in ifstat and "ptxs" in ifstat and "txs" in ifstat: + prxspct = min(100.0, (ifstat["prxs"] / ifstat["rxs"])*100.0) if ifstat["rxs"] and ifstat["prxs"] else 0.0 + ptxspct = min(100.0, (ifstat["ptxs"] / ifstat["txs"])*100.0) if ifstat["txs"] and ifstat["ptxs"] else 0.0 + ppctstr = f"(↓{int(prxspct)}% / ↑{int(ptxspct)}% of flow)" + if rpc_str: rpc_str = f"{rpc_str} {ppctstr}" + else: rpc_str = f"{ppctstr}" + psr = True if not asr: iaf = ""; oaf = "" @@ -638,11 +654,11 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= txb_str += (mlen-len(txb_str))*" " if psr: - print(f" Path Rqs. : {opf} {rpc_str}") + print(f" Path Rqs. : {opf} {rpc_str}") print(f" {ipf} {pburst_str}") if asr: - print(f" Announces : {oaf} {pc_str}") + print(f" Announces : {oaf} {pc_str}") print(f" {iaf} {art_str}{burst_str}") rxstat = rxb_str @@ -670,8 +686,50 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None, json= rxstat = rxb_str+" "+RNS.prettyspeed(stats["rxs"]) txstat = txb_str+" "+RNS.prettyspeed(stats["txs"]) + + if pstats or astats: + if "prxs" in stats and "ptxs" in stats and "arxs" in stats and "atxs" in stats: + parxs = stats["prxs"]+stats["arxs"] + patxs = stats["ptxs"]+stats["atxs"] + mrxpct = 100.0-min(100.0, (parxs / stats["rxs"])*100.0) if stats["rxs"] else 100.0 + mtxpct = 100.0-min(100.0, (patxs / stats["txs"])*100.0) if stats["txs"] else 100.0 + + if stats["rxs"] > 0: rxstat = f"{rxstat}, {int(mrxpct)}% data" + if stats["txs"] > 0: txstat = f"{txstat}, {int(mtxpct)}% data" + print(f"\n Totals : {txstat}\n {rxstat}") + if pstats: + if "prxb" in stats and "ptxb" in stats and "prxs" in stats and "ptxs" in stats: + prxb_str = "↓"+RNS.prettysize(stats["prxb"]) + ptxb_str = "↑"+RNS.prettysize(stats["ptxb"]) + strdiff = len(prxb_str)-len(ptxb_str) + if strdiff > 0: ptxb_str += " "*strdiff + elif strdiff < 0: prxb_str += " "*-strdiff + + prxspct = min(100.0, (stats["prxs"] / stats["rxs"])*100.0) if stats["rxs"] and stats["prxs"] else 0.0 + ptxspct = min(100.0, (stats["ptxs"] / stats["txs"])*100.0) if stats["txs"] and stats["ptxs"] else 0.0 + + prxstat = prxb_str+" "+RNS.prettyspeed(stats["prxs"])+f", {int(prxspct)}% of flow" + ptxstat = ptxb_str+" "+RNS.prettyspeed(stats["ptxs"])+f", {int(ptxspct)}% of flow" + print(f"\n Path Reqs. : {ptxstat}\n {prxstat}") + + if astats: + if "arxb" in stats and "atxb" in stats and "arxs" in stats and "atxs" in stats: + arxb_str = "↓"+RNS.prettysize(stats["arxb"]) + atxb_str = "↑"+RNS.prettysize(stats["atxb"]) + strdiff = len(arxb_str)-len(atxb_str) + if strdiff > 0: atxb_str += " "*strdiff + elif strdiff < 0: arxb_str += " "*-strdiff + + arxspct = min(100.0, (stats["arxs"] / stats["rxs"])*100.0) if stats["rxs"] and stats["arxs"] else 0.0 + atxspct = min(100.0, (stats["atxs"] / stats["txs"])*100.0) if stats["txs"] and stats["atxs"] else 0.0 + + arxstat = arxb_str+" "+RNS.prettyspeed(stats["arxs"])+f", {int(arxspct)}% of flow" + atxstat = atxb_str+" "+RNS.prettyspeed(stats["atxs"])+f", {int(atxspct)}% of flow" + print(f"\n Announces : {atxstat}\n {arxstat}") + + if queue_stats: tqdp = f", {stats['rxqtd']} dropped" if stats['rxqtd'] else "" dqdp = f", {stats['rxqdd']} dropped" if stats['rxqdd'] else ""