Merge branch 'optimize'
commit
9f66b5a6a3
|
|
@ -556,7 +556,8 @@ class Identity:
|
|||
if signal_blackholed: return "blackholed"
|
||||
else: return False
|
||||
|
||||
if announced_identity.pub != None and announced_identity.validate(signature, signed_data):
|
||||
if announced_identity.pub != None and (packet.announce_signature_validated or announced_identity.validate(signature, signed_data)):
|
||||
packet.announce_signature_validated = True
|
||||
if only_validate_signature:
|
||||
del announced_identity
|
||||
return True
|
||||
|
|
|
|||
|
|
@ -797,8 +797,9 @@ class BackboneClientInterface(Interface):
|
|||
def process_outgoing(self, data):
|
||||
if self.online and not self.detached:
|
||||
try:
|
||||
buffer_was_empty = len(self.transmit_buffer) == 0
|
||||
self.transmit_buffer += bytes([HDLC.FLAG])+HDLC.escape(data)+bytes([HDLC.FLAG])
|
||||
BackboneInterface.tx_ready(self)
|
||||
if buffer_was_empty: BackboneInterface.tx_ready(self)
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Exception occurred while transmitting via "+str(self)+", tearing down interface", RNS.LOG_ERROR)
|
||||
|
|
|
|||
|
|
@ -117,7 +117,8 @@ class Packet:
|
|||
__slots__ = "hops", "header", "header_type", "packet_type", "transport_type", "context", "context_flag", "destination"
|
||||
__slots__ += "transport_id", "data", "flags", "raw", "packed", "sent", "create_receipt", "receipt", "fromPacked", "MTU"
|
||||
__slots__ += "sent_at", "packet_hash", "ratchet_id", "attached_interface", "receiving_interface", "rssi", "snr", "q"
|
||||
__slots__ += "ciphertext", "plaintext", "destination_hash", "destination_type", "link", "map_hash", "is_outbound_pr", "traffic_class"
|
||||
__slots__ += "ciphertext", "plaintext", "destination_hash", "destination_type", "link", "map_hash", "is_outbound_pr"
|
||||
__slots__ += "traffic_class", "announce_signature_validated"
|
||||
|
||||
def __init__(self, destination, data, packet_type = DATA, context = NONE, transport_type = RNS.Transport.BROADCAST,
|
||||
header_type = HEADER_1, transport_id = None, attached_interface = None, create_receipt = True, context_flag=FLAG_UNSET):
|
||||
|
|
@ -160,6 +161,7 @@ class Packet:
|
|||
self.ratchet_id = None
|
||||
|
||||
self.traffic_class = None
|
||||
self.announce_signature_validated = None
|
||||
self.attached_interface = attached_interface
|
||||
self.receiving_interface = None
|
||||
self.is_outbound_pr = False
|
||||
|
|
@ -350,6 +352,10 @@ class Packet:
|
|||
|
||||
def getTruncatedHash(self): return RNS.Identity.truncated_hash(self.get_hashable_part())
|
||||
|
||||
@property
|
||||
def truncated_packet_hash(self):
|
||||
return self.packet_hash[:RNS.Reticulum.TRUNCATED_HASHLENGTH//8]
|
||||
|
||||
def get_hashable_part(self):
|
||||
hashable_part = bytes([self.raw[0] & 0b00001111])
|
||||
if self.header_type == Packet.HEADER_2: hashable_part += self.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
|
||||
|
|
@ -380,7 +386,7 @@ class Packet:
|
|||
|
||||
class ProofDestination:
|
||||
def __init__(self, packet):
|
||||
self.hash = packet.get_hash()[:RNS.Reticulum.TRUNCATED_HASHLENGTH//8];
|
||||
self.hash = packet.truncated_packet_hash;
|
||||
self.type = RNS.Destination.SINGLE
|
||||
|
||||
def encrypt(self, plaintext): return plaintext
|
||||
|
|
@ -405,8 +411,8 @@ class PacketReceipt:
|
|||
|
||||
# Creates a new packet receipt from a sent packet
|
||||
def __init__(self, packet):
|
||||
self.hash = packet.get_hash()
|
||||
self.truncated_hash = packet.getTruncatedHash()
|
||||
self.hash = packet.packet_hash
|
||||
self.truncated_hash = packet.truncated_packet_hash
|
||||
self.sent = True
|
||||
self.sent_at = time.time()
|
||||
self.proved = False
|
||||
|
|
|
|||
211
RNS/Transport.py
211
RNS/Transport.py
|
|
@ -164,6 +164,8 @@ class Transport:
|
|||
destinations_map = {} # Destination hash map of active destinations
|
||||
pending_links = [] # Links that are being established
|
||||
active_links = [] # Links that are active
|
||||
pending_links_map = {} # Link ID hash map of pending links
|
||||
active_links_map = {} # Link ID hash map of active links
|
||||
packet_hashlist = set() # A list of packet hashes for duplicate detection
|
||||
packet_hashlist_prev = set()
|
||||
receipts = [] # Receipts of all outgoing packets for proof processing
|
||||
|
|
@ -171,6 +173,7 @@ class Transport:
|
|||
# Notes on memory usage: 1 megabyte of memory can store approximately
|
||||
# 55.100 path table entries or approximately 22.300 link table entries.
|
||||
|
||||
link_fp_cache = {}
|
||||
announce_table = {} # A table for storing announces currently waiting to be retransmitted
|
||||
path_table = {} # A lookup table containing the next hop to a given destination
|
||||
reverse_table = {} # A lookup table for storing packet hashes used to return proofs and replies
|
||||
|
|
@ -714,14 +717,18 @@ class Transport:
|
|||
|
||||
closed_pending_links.append(link)
|
||||
|
||||
for closed_link in closed_pending_links: Transport.pending_links.remove(closed_link)
|
||||
for closed_link in closed_pending_links:
|
||||
Transport.pending_links.remove(closed_link)
|
||||
Transport.pending_links_map.pop(closed_link.link_id, None)
|
||||
|
||||
with Transport.active_links_lock:
|
||||
closed_links = []
|
||||
for link in Transport.active_links:
|
||||
if link.status == RNS.Link.CLOSED: closed_links.append(link)
|
||||
|
||||
for closed_link in closed_links: Transport.active_links.remove(closed_link)
|
||||
for closed_link in closed_links:
|
||||
Transport.active_links.remove(closed_link)
|
||||
Transport.active_links_map.pop(closed_link.link_id, None)
|
||||
|
||||
Transport.links_last_checked = time.time()
|
||||
|
||||
|
|
@ -2009,9 +2016,10 @@ class Transport:
|
|||
if packet.transport_id != None and packet.packet_type != RNS.Packet.ANNOUNCE:
|
||||
if not packet.transport_id == Transport.identity.hash: return
|
||||
else:
|
||||
if packet.destination_hash in Transport.path_table:
|
||||
next_hop = Transport.path_table[packet.destination_hash][IDX_PT_NEXT_HOP]
|
||||
remaining_hops = Transport.path_table[packet.destination_hash][IDX_PT_HOPS]
|
||||
path_entry = Transport.path_table.get(packet.destination_hash)
|
||||
if path_entry != None:
|
||||
next_hop = path_entry[IDX_PT_NEXT_HOP]
|
||||
remaining_hops = path_entry[IDX_PT_HOPS]
|
||||
|
||||
if remaining_hops > 1:
|
||||
# Just increase hop count and transmit
|
||||
|
|
@ -2044,7 +2052,7 @@ class Transport:
|
|||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[2:]
|
||||
|
||||
outbound_interface = Transport.path_table[packet.destination_hash][IDX_PT_RVCD_IF]
|
||||
outbound_interface = path_entry[IDX_PT_RVCD_IF]
|
||||
|
||||
if packet.packet_type == RNS.Packet.LINKREQUEST:
|
||||
now = time.time()
|
||||
|
|
@ -2096,11 +2104,11 @@ class Transport:
|
|||
outbound_interface, # 1: Outbound interface
|
||||
time.time() ] # 2: Timestamp
|
||||
|
||||
with Transport.reverse_table_lock: Transport.reverse_table[packet.getTruncatedHash()] = reverse_entry
|
||||
with Transport.reverse_table_lock: Transport.reverse_table[packet.truncated_packet_hash] = reverse_entry
|
||||
|
||||
if Transport.local_hops_delta != 0 and from_local_client and not to_local_client: new_raw = Transport.mangle_hops(new_raw, Transport.local_hops_delta)
|
||||
Transport.transmit(outbound_interface, new_raw)
|
||||
with Transport.path_table_lock: Transport.path_table[packet.destination_hash][IDX_PT_TIMESTAMP] = time.time()
|
||||
path_entry[IDX_PT_TIMESTAMP] = time.time()
|
||||
|
||||
else:
|
||||
# TODO: There should probably be some kind of REJECT
|
||||
|
|
@ -2151,25 +2159,18 @@ class Transport:
|
|||
Transport.transmit(outbound_interface, new_raw)
|
||||
Transport.link_table[packet.destination_hash][IDX_LT_TIMESTAMP] = time.time()
|
||||
|
||||
else:
|
||||
RNS.log(f"No-outbound return on link packet from {packet.receiving_interface}", RNS.LOG_WARNING) # TODO: Remove
|
||||
|
||||
# TODO: Can we return safely here? Test and possibly enable this at some point.
|
||||
return
|
||||
else: RNS.log(f"No-outbound return on link packet from {packet.receiving_interface}", RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
|
||||
|
||||
return
|
||||
|
||||
# Announce handling. Handles logic related to incoming
|
||||
# announces, queueing rebroadcasts of these, and removal
|
||||
# of queued announce rebroadcasts once handed to the next node.
|
||||
if packet.packet_type == RNS.Packet.ANNOUNCE:
|
||||
local_destination = None
|
||||
with Transport.destinations_map_lock:
|
||||
if packet.destination_hash in Transport.destinations_map:
|
||||
local_destination = Transport.destinations_map[packet.destination_hash]
|
||||
|
||||
announce_valid = RNS.Identity.validate_announce(packet)
|
||||
if not announce_valid: return packet.receiving_interface.protocol_violation("Invalid announce") if packet.receiving_interface else None
|
||||
|
||||
local_destination = Transport.destinations_map.get(packet.destination_hash)
|
||||
if local_destination == None and announce_valid:
|
||||
if packet.transport_id != None:
|
||||
received_from = packet.transport_id
|
||||
|
|
@ -2536,11 +2537,7 @@ class Transport:
|
|||
# Handling for link requests to local destinations
|
||||
elif packet.packet_type == RNS.Packet.LINKREQUEST and not link_request_handled:
|
||||
if packet.transport_id == None or packet.transport_id == Transport.identity.hash:
|
||||
destination = None
|
||||
with Transport.destinations_map_lock:
|
||||
if packet.destination_hash in Transport.destinations_map:
|
||||
destination = Transport.destinations_map[packet.destination_hash]
|
||||
|
||||
destination = Transport.destinations_map.get(packet.destination_hash)
|
||||
if destination and destination.type == packet.destination_type:
|
||||
path_mtu = RNS.Link.mtu_from_lr_packet(packet)
|
||||
mode = RNS.Link.mode_from_lr_packet(packet)
|
||||
|
|
@ -2570,39 +2567,31 @@ class Transport:
|
|||
# Handling for local data packets
|
||||
elif packet.packet_type == RNS.Packet.DATA:
|
||||
if packet.destination_type == RNS.Destination.LINK:
|
||||
with Transport.active_links_lock:
|
||||
for link in Transport.active_links:
|
||||
if link.link_id == packet.destination_hash:
|
||||
if link.attached_interface == packet.receiving_interface:
|
||||
packet.link = link
|
||||
if packet.context == RNS.Packet.CACHE_REQUEST:
|
||||
cached_packet = Transport.get_cached_packet(packet.data)
|
||||
if cached_packet != None:
|
||||
if not cached_packet.unpack(): return
|
||||
RNS.Packet(destination=link, data=cached_packet.data,
|
||||
packet_type=cached_packet.packet_type, context=cached_packet.context).send()
|
||||
|
||||
else: link.receive(packet)
|
||||
break
|
||||
|
||||
else:
|
||||
# In the strange and rare case that an interface
|
||||
# is partly malfunctioning, and a link-associated
|
||||
# packet is being received on an interface that
|
||||
# has failed sending, and transport has failed over
|
||||
# to another path, we remove this packet hash from
|
||||
# the filter hashlist so the link can receive the
|
||||
# packet when it finally arrives over another path.
|
||||
while packet.packet_hash in Transport.packet_hashlist:
|
||||
Transport.packet_hashlist.remove(packet.packet_hash)
|
||||
while packet.packet_hash in Transport.packet_hashlist_prev:
|
||||
Transport.packet_hashlist_prev.remove(packet.packet_hash)
|
||||
else:
|
||||
destination = None
|
||||
with Transport.destinations_map_lock:
|
||||
if packet.destination_hash in Transport.destinations_map:
|
||||
destination = Transport.destinations_map[packet.destination_hash]
|
||||
link = Transport.active_links_map.get(packet.destination_hash)
|
||||
if link != None:
|
||||
if link.attached_interface == packet.receiving_interface:
|
||||
packet.link = link
|
||||
if packet.context == RNS.Packet.CACHE_REQUEST:
|
||||
cached_packet = Transport.get_cached_packet(packet.data)
|
||||
if cached_packet != None:
|
||||
if not cached_packet.unpack(): return
|
||||
RNS.Packet(destination=link, data=cached_packet.data,
|
||||
packet_type=cached_packet.packet_type, context=cached_packet.context).send()
|
||||
|
||||
else: link.receive(packet)
|
||||
|
||||
else:
|
||||
# In the strange and rare case that an interface
|
||||
# is partly malfunctioning, and a link-associated
|
||||
# packet is being received on an interface that
|
||||
# has failed sending, and transport has failed over
|
||||
# to another path, we remove this packet hash from
|
||||
# the filter hashlist so the link can receive the
|
||||
# packet when it finally arrives over another path.
|
||||
while packet.packet_hash in Transport.packet_hashlist: Transport.packet_hashlist.remove(packet.packet_hash)
|
||||
while packet.packet_hash in Transport.packet_hashlist_prev: Transport.packet_hashlist_prev.remove(packet.packet_hash)
|
||||
else:
|
||||
destination = Transport.destinations_map.get(packet.destination_hash)
|
||||
if destination and destination.type == packet.destination_type:
|
||||
packet.destination = destination
|
||||
if destination.receive(packet):
|
||||
|
|
@ -2639,10 +2628,8 @@ class Transport:
|
|||
if peer_identity.validate(signature, signed_data) and not link_entry[IDX_LT_VALIDATED]:
|
||||
RNS.log(f"Re-balancing path to {RNS.prettyhexrep(link_destination)} from link-request proof ({link_entry[IDX_LT_REM_HOPS]}->{packet.hops})", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
link_entry[IDX_LT_REM_HOPS] = packet.hops
|
||||
with Transport.path_table_lock:
|
||||
if link_destination in Transport.path_table:
|
||||
path_entry = Transport.path_table[link_destination]
|
||||
path_entry[IDX_PT_HOPS] = packet.hops
|
||||
path_entry = Transport.path_table.get(link_destination)
|
||||
if path_entry: path_entry[IDX_PT_HOPS] = packet.hops
|
||||
|
||||
elif not link_entry[IDX_LT_VALIDATED]: RNS.log(f"Aborting link request proof path re-balancing for {RNS.prettyhexrep(link_destination)} on link {RNS.prettyhexrep(packet.destination_hash)} due to invalid signature", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
else: pass
|
||||
|
|
@ -2686,65 +2673,57 @@ class Transport:
|
|||
# Check if we can deliver it to a local pending link
|
||||
pending_link = None
|
||||
with Transport.pending_links_lock:
|
||||
for link in Transport.pending_links:
|
||||
if link.link_id == packet.destination_hash:
|
||||
if packet.hops != link.expected_hops and link.status == RNS.Link.PENDING and Transport.ALLOW_LINK_PATH_REBALANCE:
|
||||
RNS.log(f"Unbalanced link path ({packet.hops}/{link.expected_hops}) detected on link {link}, validating signature for re-balancing...", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
try:
|
||||
if len(packet.data) == RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2 or len(packet.data) == RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2+RNS.Link.LINK_MTU_SIZE:
|
||||
packet_data = packet.data
|
||||
signalling_bytes = b""
|
||||
confirmed_mtu = None
|
||||
mode = RNS.Link.mode_from_lp_packet(packet)
|
||||
if mode != link.mode: raise TypeError(f"Invalid link mode {mode} in link request proof")
|
||||
if len(packet_data) == RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2+RNS.Link.LINK_MTU_SIZE:
|
||||
confirmed_mtu = RNS.Link.mtu_from_lp_packet(packet)
|
||||
signalling_bytes = RNS.Link.signalling_bytes(confirmed_mtu, mode)
|
||||
packet_data = packet_data[:RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2]
|
||||
link = Transport.pending_links_map.get(packet.destination_hash)
|
||||
if link != None:
|
||||
if packet.hops != link.expected_hops and link.status == RNS.Link.PENDING and Transport.ALLOW_LINK_PATH_REBALANCE:
|
||||
RNS.log(f"Unbalanced link path ({packet.hops}/{link.expected_hops}) detected on link {link}, validating signature for re-balancing...", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
try:
|
||||
if len(packet.data) == RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2 or len(packet.data) == RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2+RNS.Link.LINK_MTU_SIZE:
|
||||
packet_data = packet.data
|
||||
signalling_bytes = b""
|
||||
confirmed_mtu = None
|
||||
mode = RNS.Link.mode_from_lp_packet(packet)
|
||||
if mode != link.mode: raise TypeError(f"Invalid link mode {mode} in link request proof")
|
||||
if len(packet_data) == RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2+RNS.Link.LINK_MTU_SIZE:
|
||||
confirmed_mtu = RNS.Link.mtu_from_lp_packet(packet)
|
||||
signalling_bytes = RNS.Link.signalling_bytes(confirmed_mtu, mode)
|
||||
packet_data = packet_data[:RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2]
|
||||
|
||||
peer_pub_bytes = packet_data[RNS.Identity.SIGLENGTH//8:RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2]
|
||||
peer_sig_pub_bytes = link.destination.identity.get_public_key()[RNS.Link.ECPUBSIZE//2:RNS.Link.ECPUBSIZE]
|
||||
peer_pub_bytes = packet_data[RNS.Identity.SIGLENGTH//8:RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2]
|
||||
peer_sig_pub_bytes = link.destination.identity.get_public_key()[RNS.Link.ECPUBSIZE//2:RNS.Link.ECPUBSIZE]
|
||||
|
||||
signed_data = link.link_id+peer_pub_bytes+peer_sig_pub_bytes+signalling_bytes
|
||||
signature = packet_data[:RNS.Identity.SIGLENGTH//8]
|
||||
signed_data = link.link_id+peer_pub_bytes+peer_sig_pub_bytes+signalling_bytes
|
||||
signature = packet_data[:RNS.Identity.SIGLENGTH//8]
|
||||
|
||||
if link.destination.identity.validate(signature, signed_data):
|
||||
with Transport.path_table_lock:
|
||||
if not link.rebalanced:
|
||||
RNS.log(f"Re-balancing path to {RNS.prettyhexrep(link.destination.hash)} at link terminus ({link.expected_hops}->{packet.hops})", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
link.rebalanced = time.time()
|
||||
link.expected_hops = packet.hops
|
||||
if link.destination.hash in Transport.path_table:
|
||||
path_entry = Transport.path_table[link.destination.hash]
|
||||
path_entry[IDX_PT_HOPS] = packet.hops
|
||||
RNS.log(f"Path table re-balanced for {RNS.prettyhexrep(link.destination.hash)}", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
if link.destination.identity.validate(signature, signed_data):
|
||||
if not link.rebalanced:
|
||||
RNS.log(f"Re-balancing path to {RNS.prettyhexrep(link.destination.hash)} at link terminus ({link.expected_hops}->{packet.hops})", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
link.rebalanced = time.time()
|
||||
link.expected_hops = packet.hops
|
||||
path_entry = Transport.path_table.get(link.destination.hash)
|
||||
if path_entry:
|
||||
path_entry[IDX_PT_HOPS] = packet.hops
|
||||
RNS.log(f"Path table re-balanced for {RNS.prettyhexrep(link.destination.hash)}", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
|
||||
else: RNS.log(f"Aborting path re-balancing at link terminus for {RNS.prettyhexrep(link.destination.hash)} on link {link} due to invalid signature", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
except Exception as e: RNS.log("Error while validating link request proof for path re-balancing at link terminus. The contained exception was: "+str(e), REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
else: RNS.log(f"Aborting path re-balancing at link terminus for {RNS.prettyhexrep(link.destination.hash)} on link {link} due to invalid signature", REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
except Exception as e: RNS.log("Error while validating link request proof for path re-balancing at link terminus. The contained exception was: "+str(e), REBALANCE_LOGLEVEL) if RNS.sl(REBALANCE_LOGLEVEL) else None
|
||||
|
||||
if packet.hops == link.expected_hops:
|
||||
# Add this packet to the filter hashlist if we
|
||||
# have determined that it's actually destined
|
||||
# for this system, and then validate the proof
|
||||
Transport.add_packet_hash(packet.packet_hash)
|
||||
pending_link = link
|
||||
break
|
||||
if packet.hops == link.expected_hops:
|
||||
# Add this packet to the filter hashlist if we
|
||||
# have determined that it's actually destined
|
||||
# for this system, and then validate the proof
|
||||
Transport.add_packet_hash(packet.packet_hash)
|
||||
pending_link = link
|
||||
|
||||
if pending_link: pending_link.validate_proof(packet)
|
||||
|
||||
elif packet.context == RNS.Packet.RESOURCE_PRF:
|
||||
with Transport.active_links_lock:
|
||||
for link in Transport.active_links:
|
||||
if link.link_id == packet.destination_hash:
|
||||
link.receive(packet)
|
||||
break
|
||||
link = Transport.active_links_map.get(packet.destination_hash)
|
||||
if link != None: link.receive(packet)
|
||||
else:
|
||||
if packet.destination_type == RNS.Destination.LINK:
|
||||
with Transport.active_links_lock:
|
||||
for link in Transport.active_links:
|
||||
if link.link_id == packet.destination_hash:
|
||||
packet.link = link
|
||||
break
|
||||
link = Transport.active_links_map.get(packet.destination_hash)
|
||||
if link != None: packet.link = link
|
||||
|
||||
if len(packet.data) == RNS.PacketReceipt.EXPL_LENGTH: proof_hash = packet.data[:RNS.Identity.HASHLENGTH//8]
|
||||
else: proof_hash = None
|
||||
|
|
@ -2947,9 +2926,13 @@ class Transport:
|
|||
def register_link(link):
|
||||
RNS.log("Registering link "+str(link), RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
|
||||
if link.initiator:
|
||||
with Transport.pending_links_lock: Transport.pending_links.append(link)
|
||||
with Transport.pending_links_lock:
|
||||
Transport.pending_links.append(link)
|
||||
Transport.pending_links_map[link.link_id] = link
|
||||
else:
|
||||
with Transport.active_links_lock: Transport.active_links.append(link)
|
||||
with Transport.active_links_lock:
|
||||
Transport.active_links.append(link)
|
||||
Transport.active_links_map[link.link_id] = link
|
||||
|
||||
@staticmethod
|
||||
def activate_link(link):
|
||||
|
|
@ -2958,10 +2941,14 @@ class Transport:
|
|||
if link in Transport.pending_links:
|
||||
if link.status != RNS.Link.ACTIVE: raise IOError("Invalid link state for link activation: "+str(link.status))
|
||||
Transport.pending_links.remove(link)
|
||||
with Transport.active_links_lock: Transport.active_links.append(link)
|
||||
Transport.pending_links_map.pop(link.link_id, None)
|
||||
with Transport.active_links_lock:
|
||||
Transport.active_links.append(link)
|
||||
Transport.active_links_map[link.link_id] = link
|
||||
|
||||
link.status = RNS.Link.ACTIVE
|
||||
else:
|
||||
RNS.log("Attempted to activate a link that was not in the pending table", RNS.LOG_ERROR)
|
||||
|
||||
else: RNS.log("Attempted to activate a link that was not in the pending table", RNS.LOG_ERROR)
|
||||
|
||||
@staticmethod
|
||||
def register_announce_handler(handler):
|
||||
|
|
|
|||
|
|
@ -588,18 +588,18 @@ class Profiler:
|
|||
name = tag["name"]
|
||||
stats_all = tag["stats_all"]; stats_1m = tag["stats_1m"]; stats_5m = tag["stats_5m"]; stats_30m = tag["stats_30m"]; stats_60m = tag["stats_60m"]
|
||||
results_str = f" {ind}{name}\n"
|
||||
results_str += f" {ind} Samples : {stats_all["count"]} from {stats_all["threads"]} thread{'s' if stats_all["threads"] > 1 else ''}\n"
|
||||
results_str += f" {ind} Samples : {stats_all['count']} from {stats_all['threads']} thread{'s' if stats_all['threads'] > 1 else ''}\n"
|
||||
if stats_all != None:
|
||||
results_str += f" {ind} {'Mean':^15} | {'Median':^15} | {'Min':^15} | {'Max':^15} | {'St. dev':^15} | {'Total':^15}\n"
|
||||
results_str += f" {ind} Stats : ({pst(stats_all["mean"]):^15} | {pst(stats_all["median"]):^15} | {pst(stats_all["min"]):^15} | {pst(stats_all["max"]):^15} | {pst(stats_all["stdev"]):^15} | {pst(stats_all["sum"]):^15})\n"
|
||||
results_str += f" {ind} Stats : ({pst(stats_all['mean']):^15} | {pst(stats_all['median']):^15} | {pst(stats_all['min']):^15} | {pst(stats_all['max']):^15} | {pst(stats_all['stdev']):^15} | {pst(stats_all['sum']):^15})\n"
|
||||
if stats_1m != None:
|
||||
results_str += f" {ind} 0-1m : ({pst(stats_1m["mean"]):^15} | {pst(stats_1m["median"]):^15} | {pst(stats_1m["min"]):^15} | {pst(stats_1m["max"]):^15} | {pst(stats_1m["stdev"]):^15} | {pst(stats_1m["sum"]):^15})\n"
|
||||
results_str += f" {ind} 0-1m : ({pst(stats_1m['mean']):^15} | {pst(stats_1m['median']):^15} | {pst(stats_1m['min']):^15} | {pst(stats_1m['max']):^15} | {pst(stats_1m['stdev']):^15} | {pst(stats_1m['sum']):^15})\n"
|
||||
if stats_5m != None:
|
||||
results_str += f" {ind} 1-5m : ({pst(stats_5m["mean"]):^15} | {pst(stats_5m["median"]):^15} | {pst(stats_5m["min"]):^15} | {pst(stats_5m["max"]):^15} | {pst(stats_5m["stdev"]):^15} | {pst(stats_5m["sum"]):^15})\n"
|
||||
results_str += f" {ind} 1-5m : ({pst(stats_5m['mean']):^15} | {pst(stats_5m['median']):^15} | {pst(stats_5m['min']):^15} | {pst(stats_5m['max']):^15} | {pst(stats_5m['stdev']):^15} | {pst(stats_5m['sum']):^15})\n"
|
||||
if stats_30m != None:
|
||||
results_str += f" {ind} 5-30m : ({pst(stats_30m["mean"]):^15} | {pst(stats_30m["median"]):^15} | {pst(stats_30m["min"]):^15} | {pst(stats_30m["max"]):^15} | {pst(stats_30m["stdev"]):^15} | {pst(stats_30m["sum"]):^15})\n"
|
||||
results_str += f" {ind} 5-30m : ({pst(stats_30m['mean']):^15} | {pst(stats_30m['median']):^15} | {pst(stats_30m['min']):^15} | {pst(stats_30m['max']):^15} | {pst(stats_30m['stdev']):^15} | {pst(stats_30m['sum']):^15})\n"
|
||||
if stats_60m != None:
|
||||
results_str += f" {ind} 30-60m : ({pst(stats_60m["mean"]):^15} | {pst(stats_60m["median"]):^15} | {pst(stats_60m["min"]):^15} | {pst(stats_60m["max"]):^15} | {pst(stats_60m["stdev"]):^15} | {pst(stats_60m["sum"]):^15})\n"
|
||||
results_str += f" {ind} 30-60m : ({pst(stats_60m['mean']):^15} | {pst(stats_60m['median']):^15} | {pst(stats_60m['min']):^15} | {pst(stats_60m['max']):^15} | {pst(stats_60m['stdev']):^15} | {pst(stats_60m['sum']):^15})\n"
|
||||
return results_str
|
||||
|
||||
results_str = ""
|
||||
|
|
|
|||
|
|
@ -608,7 +608,7 @@ def _fmt_pps(value):
|
|||
|
||||
|
||||
def print_environment_header():
|
||||
tree_fastpath = "present" if hasattr(RNS.Transport, "_fastpath") else "absent"
|
||||
tree_fastpath = "present" if hasattr(RNS.Transport, "USE_FP_CACHE") else "absent"
|
||||
print("=" * 40)
|
||||
print("Reticulum Transport Throughput Benchmark")
|
||||
print("=" * 40)
|
||||
|
|
@ -616,7 +616,7 @@ def print_environment_header():
|
|||
print(f" Mode : {'compiled' if RNS.compiled else 'interpreted'}")
|
||||
print(f" crypto : {RNS.Cryptography.backend()}")
|
||||
print(f" transport : enabled")
|
||||
print(f" fast path : {tree_fastpath} (informational)")
|
||||
print(f" fast path : {tree_fastpath}")
|
||||
print(f" python : {platform.python_version()}")
|
||||
print(f" platform : {platform.platform()}")
|
||||
print(f" machine : {platform.machine()}, cpus: {os.cpu_count()}")
|
||||
|
|
@ -651,6 +651,7 @@ def print_scenario_table(scenario, results):
|
|||
|
||||
r = results[mode]
|
||||
tp = r['pps']*scenario.frame_size*8
|
||||
if mode == "inline": mode = "direct"
|
||||
print(f"{mode:<8} : {RNS.prettyspeed(tp)}")
|
||||
|
||||
print()
|
||||
|
|
@ -661,7 +662,7 @@ def print_pps_matrix(rows):
|
|||
if not rows:
|
||||
return
|
||||
print("-" * 72)
|
||||
print("Transport Core Throughput - PPS matrix (median of runs)")
|
||||
print("Transport Throughput - PPS matrix (median of runs)")
|
||||
print(f" {'scenario':<22}{'direct':>14}{'drainer':>14}")
|
||||
print(" " + "-" * 70)
|
||||
for name, inline_pps, drainer_pps, fsize in rows:
|
||||
|
|
@ -839,7 +840,7 @@ def _usage():
|
|||
"\nUsage: python3 tests/transport_throughput.py [options]\n"
|
||||
"\n"
|
||||
"Options:\n"
|
||||
" -s, --scenario NAME Run only the named scenario (repeatable)\n"
|
||||
" -s, --scenario NAME Run only the named scenario\n"
|
||||
" --mode MODE Measurement mode: inline, drainer or both\n"
|
||||
" (default: both)\n"
|
||||
" --runs N Measurement runs per scenario/mode, median\n"
|
||||
|
|
@ -881,3 +882,61 @@ if __name__ == "__main__":
|
|||
|
||||
unittest.main(argv=[sys.argv[0]] + rest, verbosity=2)
|
||||
|
||||
# Pre:
|
||||
#
|
||||
# Transport Throughput - PPS matrix (median of runs)
|
||||
# scenario direct drainer
|
||||
# ----------------------------------------------------------------------
|
||||
# transit_single_135 208,550 184,075 225.23 Mbps / 198.80 Mbps
|
||||
# transit_single_475 195,652 130,808 743.48 Mbps / 497.07 Mbps
|
||||
# transit_single_1024 169,828 111,446 1.39 Gbps / 912.97 Mbps
|
||||
# transit_single_16384 49,618 74,101 6.50 Gbps / 9.71 Gbps
|
||||
# transit_single_final 204,604 112,925 220.97 Mbps / 121.96 Mbps
|
||||
# transit_link_135 272,813 234,430 294.64 Mbps / 253.18 Mbps
|
||||
# transit_link_475 260,003 227,895 988.01 Mbps / 866.00 Mbps
|
||||
# transit_link_1024 232,763 145,872 1.91 Gbps / 1.19 Gbps
|
||||
# transit_link_16384 84,028 73,313 11.01 Gbps / 9.61 Gbps
|
||||
#
|
||||
# terminus_single 29,813 25,663 32.20 Mbps / 27.72 Mbps
|
||||
# announce_ingress 7,561 7,242 10.10 Mbps / 9.68 Mbps
|
||||
# outbound_path 696,106 - 751.79 Mbps / -
|
||||
#
|
||||
# No Fastpath:
|
||||
#
|
||||
# Transport Throughput - PPS matrix (median of runs)
|
||||
# scenario direct drainer
|
||||
# ----------------------------------------------------------------------
|
||||
# transit_single_135 247,667 162,090 267.48 Mbps / 175.06 Mbps
|
||||
# transit_single_475 233,514 159,717 887.35 Mbps / 606.92 Mbps
|
||||
# transit_single_1024 211,443 175,994 1.73 Gbps / 1.44 Gbps
|
||||
# transit_single_16384 78,963 72,532 10.35 Gbps / 9.51 Gbps
|
||||
# transit_single_final 240,855 112,702 260.12 Mbps / 121.72 Mbps
|
||||
# transit_link_135 266,614 220,571 287.94 Mbps / 238.22 Mbps
|
||||
# transit_link_475 256,347 152,410 974.12 Mbps / 579.16 Mbps
|
||||
# transit_link_1024 228,080 194,444 1.87 Gbps / 1.59 Gbps
|
||||
# transit_link_16384 82,149 73,720 10.77 Gbps / 9.66 Gbps
|
||||
#
|
||||
# terminus_single 29,764 28,308 32.15 Mbps / 30.57 Mbps
|
||||
# announce_ingress 7,394 7,150 9.88 Mbps / 9.55 Mbps
|
||||
# outbound_path 872,747 - 942.57 Mbps / -
|
||||
# ----------------------------------------------------------------------
|
||||
#
|
||||
#
|
||||
# Fastpath:
|
||||
#
|
||||
# Transport Throughput - PPS matrix (median of runs)
|
||||
# scenario direct drainer
|
||||
# ----------------------------------------------------------------------
|
||||
# transit_single_135 407,561 411,426 440.17 Mbps / 444.34 Mbps
|
||||
# transit_single_475 378,867 377,964 1.44 Gbps / 1.44 Gbps
|
||||
# transit_single_1024 320,878 325,910 2.63 Gbps / 2.67 Gbps
|
||||
# transit_single_16384 94,265 94,357 12.36 Gbps / 12.37 Gbps
|
||||
# transit_single_final 395,245 399,247 426.86 Mbps / 431.19 Mbps
|
||||
# transit_link_135 453,216 451,863 489.47 Mbps / 488.01 Mbps
|
||||
# transit_link_475 417,013 417,294 1.58 Gbps / 1.59 Gbps
|
||||
# transit_link_1024 347,548 353,783 2.85 Gbps / 2.90 Gbps
|
||||
# transit_link_16384 96,682 96,871 12.67 Gbps / 12.70 Gbps
|
||||
#
|
||||
# terminus_single 29,451 25,862 31.81 Mbps / 27.93 Mbps
|
||||
# announce_ingress 7,495 6,996 10.01 Mbps / 9.35 Mbps
|
||||
# outbound_path 840,738 - 908.00 Mbps / -
|
||||
|
|
|
|||
Loading…
Reference in New Issue