mirror of
https://github.com/markqvist/Reticulum.git
synced 2025-04-18 06:36:20 -04:00
Added transport table index specifiers
This commit is contained in:
parent
a4468da9b1
commit
ae92432878
341
RNS/Transport.py
341
RNS/Transport.py
@ -291,10 +291,8 @@ class Transport:
|
||||
tunnel = [tunnel_id, None, tunnel_paths, expires]
|
||||
Transport.tunnels[tunnel_id] = tunnel
|
||||
|
||||
if len(Transport.path_table) == 1:
|
||||
specifier = "entry"
|
||||
else:
|
||||
specifier = "entries"
|
||||
if len(Transport.path_table) == 1: specifier = "entry"
|
||||
else: specifier = "entries"
|
||||
|
||||
RNS.log("Loaded "+str(len(Transport.tunnels))+" tunnel table "+specifier+" from storage", RNS.LOG_VERBOSE)
|
||||
|
||||
@ -433,19 +431,18 @@ class Transport:
|
||||
completed_announces = []
|
||||
for destination_hash in Transport.announce_table:
|
||||
announce_entry = Transport.announce_table[destination_hash]
|
||||
if announce_entry[2] > Transport.PATHFINDER_R:
|
||||
if announce_entry[IDX_AT_RETRIES] > Transport.PATHFINDER_R:
|
||||
RNS.log("Completed announce processing for "+RNS.prettyhexrep(destination_hash)+", retry limit reached", RNS.LOG_EXTREME)
|
||||
completed_announces.append(destination_hash)
|
||||
else:
|
||||
if time.time() > announce_entry[1]:
|
||||
announce_entry[1] = time.time() + Transport.PATHFINDER_G + Transport.PATHFINDER_RW
|
||||
announce_entry[2] += 1
|
||||
packet = announce_entry[5]
|
||||
block_rebroadcasts = announce_entry[7]
|
||||
attached_interface = announce_entry[8]
|
||||
if time.time() > announce_entry[IDX_AT_RTRNS_TMO]:
|
||||
announce_entry[IDX_AT_RTRNS_TMO] = time.time() + Transport.PATHFINDER_G + Transport.PATHFINDER_RW
|
||||
announce_entry[IDX_AT_RETRIES] += 1
|
||||
packet = announce_entry[IDX_AT_PACKET]
|
||||
block_rebroadcasts = announce_entry[IDX_AT_BLCK_RBRD]
|
||||
attached_interface = announce_entry[IDX_AT_ATTCHD_IF]
|
||||
announce_context = RNS.Packet.NONE
|
||||
if block_rebroadcasts:
|
||||
announce_context = RNS.Packet.PATH_RESPONSE
|
||||
if block_rebroadcasts: announce_context = RNS.Packet.PATH_RESPONSE
|
||||
announce_data = packet.data
|
||||
announce_identity = RNS.Identity.recall(packet.destination_hash)
|
||||
announce_destination = RNS.Destination(announce_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, "unknown", "unknown");
|
||||
@ -510,7 +507,7 @@ class Transport:
|
||||
stale_reverse_entries = []
|
||||
for truncated_packet_hash in Transport.reverse_table:
|
||||
reverse_entry = Transport.reverse_table[truncated_packet_hash]
|
||||
if time.time() > reverse_entry[2] + Transport.REVERSE_TIMEOUT:
|
||||
if time.time() > reverse_entry[IDX_RT_TIMESTAMP] + Transport.REVERSE_TIMEOUT:
|
||||
stale_reverse_entries.append(truncated_packet_hash)
|
||||
|
||||
# Cull the link table according to timeout
|
||||
@ -518,33 +515,33 @@ class Transport:
|
||||
for link_id in Transport.link_table:
|
||||
link_entry = Transport.link_table[link_id]
|
||||
|
||||
if link_entry[7] == True:
|
||||
if time.time() > link_entry[0] + Transport.LINK_TIMEOUT:
|
||||
if link_entry[IDX_LT_VALIDATED] == True:
|
||||
if time.time() > link_entry[IDX_LT_TIMESTAMP] + Transport.LINK_TIMEOUT:
|
||||
stale_links.append(link_id)
|
||||
else:
|
||||
if time.time() > link_entry[8]:
|
||||
if time.time() > link_entry[IDX_LT_PROOF_TMO]:
|
||||
stale_links.append(link_id)
|
||||
|
||||
last_path_request = 0
|
||||
if link_entry[6] in Transport.path_requests:
|
||||
last_path_request = Transport.path_requests[link_entry[6]]
|
||||
if link_entry[IDX_LT_DSTHASH] in Transport.path_requests:
|
||||
last_path_request = Transport.path_requests[link_entry[IDX_LT_DSTHASH]]
|
||||
|
||||
lr_taken_hops = link_entry[5]
|
||||
lr_taken_hops = link_entry[IDX_LT_HOPS]
|
||||
|
||||
path_request_throttle = time.time() - last_path_request < Transport.PATH_REQUEST_MI
|
||||
path_request_conditions = False
|
||||
|
||||
# If the path has been invalidated between the time of
|
||||
# making the link request and now, try to rediscover it
|
||||
if not Transport.has_path(link_entry[6]):
|
||||
RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link_entry[6])+" since an attempted link was never established, and path is now missing", RNS.LOG_DEBUG)
|
||||
if not Transport.has_path(link_entry[IDX_LT_DSTHASH]):
|
||||
RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link_entry[IDX_LT_DSTHASH])+" since an attempted link was never established, and path is now missing", RNS.LOG_DEBUG)
|
||||
path_request_conditions =True
|
||||
|
||||
# If this link request was originated from a local client
|
||||
# attempt to rediscover a path to the destination, if this
|
||||
# has not already happened recently.
|
||||
elif not path_request_throttle and lr_taken_hops == 0:
|
||||
RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link_entry[6])+" since an attempted local client link was never established", RNS.LOG_DEBUG)
|
||||
RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link_entry[IDX_LT_DSTHASH])+" since an attempted local client link was never established", RNS.LOG_DEBUG)
|
||||
path_request_conditions = True
|
||||
|
||||
# If the link destination was previously only 1 hop
|
||||
@ -552,10 +549,10 @@ class Transport:
|
||||
# of our interfaces, and that it roamed somewhere else.
|
||||
# In that case, try to discover a new path, and mark
|
||||
# the old one as unresponsive.
|
||||
elif not path_request_throttle and Transport.hops_to(link_entry[6]) == 1:
|
||||
RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link_entry[6])+" since an attempted link was never established, and destination was previously local to an interface on this instance", RNS.LOG_DEBUG)
|
||||
elif not path_request_throttle and Transport.hops_to(link_entry[IDX_LT_DSTHASH]) == 1:
|
||||
RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link_entry[IDX_LT_DSTHASH])+" since an attempted link was never established, and destination was previously local to an interface on this instance", RNS.LOG_DEBUG)
|
||||
path_request_conditions = True
|
||||
blocked_if = link_entry[4]
|
||||
blocked_if = link_entry[IDX_LT_RCVD_IF]
|
||||
|
||||
# TODO: This might result in the path re-resolution
|
||||
# only being able to happen once, since new path found
|
||||
@ -567,44 +564,44 @@ class Transport:
|
||||
# and score them according to number of unsuccessful tries or
|
||||
# similar.
|
||||
if RNS.Reticulum.transport_enabled():
|
||||
if hasattr(link_entry[4], "mode") and link_entry[4].mode != RNS.Interfaces.Interface.Interface.MODE_BOUNDARY:
|
||||
Transport.mark_path_unresponsive(link_entry[6])
|
||||
if hasattr(link_entry[IDX_LT_RCVD_IF], "mode") and link_entry[IDX_LT_RCVD_IF].mode != RNS.Interfaces.Interface.Interface.MODE_BOUNDARY:
|
||||
Transport.mark_path_unresponsive(link_entry[IDX_LT_DSTHASH])
|
||||
|
||||
# If the link initiator is only 1 hop away,
|
||||
# this likely means that network topology has
|
||||
# changed. In that case, we try to discover a new path,
|
||||
# and mark the old one as potentially unresponsive.
|
||||
elif not path_request_throttle and lr_taken_hops == 1:
|
||||
RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link_entry[6])+" since an attempted link was never established, and link initiator is local to an interface on this instance", RNS.LOG_DEBUG)
|
||||
RNS.log("Trying to rediscover path for "+RNS.prettyhexrep(link_entry[IDX_LT_DSTHASH])+" since an attempted link was never established, and link initiator is local to an interface on this instance", RNS.LOG_DEBUG)
|
||||
path_request_conditions = True
|
||||
blocked_if = link_entry[4]
|
||||
blocked_if = link_entry[IDX_LT_RCVD_IF]
|
||||
|
||||
if RNS.Reticulum.transport_enabled():
|
||||
if hasattr(link_entry[4], "mode") and link_entry[4].mode != RNS.Interfaces.Interface.Interface.MODE_BOUNDARY:
|
||||
Transport.mark_path_unresponsive(link_entry[6])
|
||||
if hasattr(link_entry[IDX_LT_RCVD_IF], "mode") and link_entry[IDX_LT_RCVD_IF].mode != RNS.Interfaces.Interface.Interface.MODE_BOUNDARY:
|
||||
Transport.mark_path_unresponsive(link_entry[IDX_LT_DSTHASH])
|
||||
|
||||
if path_request_conditions:
|
||||
if not link_entry[6] in path_requests:
|
||||
path_requests[link_entry[6]] = blocked_if
|
||||
if not link_entry[IDX_LT_DSTHASH] in path_requests:
|
||||
path_requests[link_entry[IDX_LT_DSTHASH]] = blocked_if
|
||||
|
||||
if not RNS.Reticulum.transport_enabled():
|
||||
# Drop current path if we are not a transport instance, to
|
||||
# allow using higher-hop count paths or reused announces
|
||||
# from newly adjacent transport instances.
|
||||
Transport.expire_path(link_entry[6])
|
||||
Transport.expire_path(link_entry[IDX_LT_DSTHASH])
|
||||
|
||||
# Cull the path table
|
||||
stale_paths = []
|
||||
for destination_hash in Transport.path_table:
|
||||
destination_entry = Transport.path_table[destination_hash]
|
||||
attached_interface = destination_entry[5]
|
||||
attached_interface = destination_entry[IDX_PT_RVCD_IF]
|
||||
|
||||
if attached_interface != None and hasattr(attached_interface, "mode") and attached_interface.mode == RNS.Interfaces.Interface.Interface.MODE_ACCESS_POINT:
|
||||
destination_expiry = destination_entry[0] + Transport.AP_PATH_TIME
|
||||
destination_expiry = destination_entry[IDX_PT_TIMESTAMP] + Transport.AP_PATH_TIME
|
||||
elif attached_interface != None and hasattr(attached_interface, "mode") and attached_interface.mode == RNS.Interfaces.Interface.Interface.MODE_ROAMING:
|
||||
destination_expiry = destination_entry[0] + Transport.ROAMING_PATH_TIME
|
||||
destination_expiry = destination_entry[IDX_PT_TIMESTAMP] + Transport.ROAMING_PATH_TIME
|
||||
else:
|
||||
destination_expiry = destination_entry[0] + Transport.DESTINATION_TIMEOUT
|
||||
destination_expiry = destination_entry[IDX_PT_TIMESTAMP] + Transport.DESTINATION_TIMEOUT
|
||||
|
||||
if time.time() > destination_expiry:
|
||||
stale_paths.append(destination_hash)
|
||||
@ -834,24 +831,24 @@ class Transport:
|
||||
|
||||
# Check if we have a known path for the destination in the path table
|
||||
if packet.packet_type != RNS.Packet.ANNOUNCE and packet.destination.type != RNS.Destination.PLAIN and packet.destination.type != RNS.Destination.GROUP and packet.destination_hash in Transport.path_table:
|
||||
outbound_interface = Transport.path_table[packet.destination_hash][5]
|
||||
outbound_interface = Transport.path_table[packet.destination_hash][IDX_PT_RVCD_IF]
|
||||
|
||||
# If there's more than one hop to the destination, and we know
|
||||
# a path, we insert the packet into transport by adding the next
|
||||
# transport nodes address to the header, and modifying the flags.
|
||||
# This rule applies both for "normal" transport, and when connected
|
||||
# to a local shared Reticulum instance.
|
||||
if Transport.path_table[packet.destination_hash][2] > 1:
|
||||
if Transport.path_table[packet.destination_hash][IDX_PT_HOPS] > 1:
|
||||
if packet.header_type == RNS.Packet.HEADER_1:
|
||||
# Insert packet into transport
|
||||
new_flags = (RNS.Packet.HEADER_2) << 6 | (Transport.TRANSPORT) << 4 | (packet.flags & 0b00001111)
|
||||
new_raw = struct.pack("!B", new_flags)
|
||||
new_raw += packet.raw[1:2]
|
||||
new_raw += Transport.path_table[packet.destination_hash][1]
|
||||
new_raw += Transport.path_table[packet.destination_hash][IDX_PT_NEXT_HOP]
|
||||
new_raw += packet.raw[2:]
|
||||
packet_sent(packet)
|
||||
Transport.transmit(outbound_interface, new_raw)
|
||||
Transport.path_table[packet.destination_hash][0] = time.time()
|
||||
Transport.path_table[packet.destination_hash][IDX_PT_TIMESTAMP] = time.time()
|
||||
sent = True
|
||||
|
||||
# In the special case where we are connected to a local shared
|
||||
@ -861,17 +858,17 @@ class Transport:
|
||||
# one hop away would just be broadcast directly, but since we
|
||||
# are "behind" a shared instance, we need to get that instance
|
||||
# to transport it onto the network.
|
||||
elif Transport.path_table[packet.destination_hash][2] == 1 and Transport.owner.is_connected_to_shared_instance:
|
||||
elif Transport.path_table[packet.destination_hash][IDX_PT_HOPS] == 1 and Transport.owner.is_connected_to_shared_instance:
|
||||
if packet.header_type == RNS.Packet.HEADER_1:
|
||||
# Insert packet into transport
|
||||
new_flags = (RNS.Packet.HEADER_2) << 6 | (Transport.TRANSPORT) << 4 | (packet.flags & 0b00001111)
|
||||
new_raw = struct.pack("!B", new_flags)
|
||||
new_raw += packet.raw[1:2]
|
||||
new_raw += Transport.path_table[packet.destination_hash][1]
|
||||
new_raw += Transport.path_table[packet.destination_hash][IDX_PT_NEXT_HOP]
|
||||
new_raw += packet.raw[2:]
|
||||
packet_sent(packet)
|
||||
Transport.transmit(outbound_interface, new_raw)
|
||||
Transport.path_table[packet.destination_hash][0] = time.time()
|
||||
Transport.path_table[packet.destination_hash][IDX_PT_TIMESTAMP] = time.time()
|
||||
sent = True
|
||||
|
||||
# If none of the above applies, we know the destination is
|
||||
@ -1250,10 +1247,10 @@ class Transport:
|
||||
# Check special conditions for local clients connected
|
||||
# through a shared Reticulum instance
|
||||
from_local_client = (packet.receiving_interface in Transport.local_client_interfaces)
|
||||
for_local_client = (packet.packet_type != RNS.Packet.ANNOUNCE) and (packet.destination_hash in Transport.path_table and Transport.path_table[packet.destination_hash][2] == 0)
|
||||
for_local_client_link = (packet.packet_type != RNS.Packet.ANNOUNCE) and (packet.destination_hash in Transport.link_table and Transport.link_table[packet.destination_hash][4] in Transport.local_client_interfaces)
|
||||
for_local_client_link |= (packet.packet_type != RNS.Packet.ANNOUNCE) and (packet.destination_hash in Transport.link_table and Transport.link_table[packet.destination_hash][2] in Transport.local_client_interfaces)
|
||||
proof_for_local_client = (packet.destination_hash in Transport.reverse_table) and (Transport.reverse_table[packet.destination_hash][0] in Transport.local_client_interfaces)
|
||||
for_local_client = (packet.packet_type != RNS.Packet.ANNOUNCE) and (packet.destination_hash in Transport.path_table and Transport.path_table[packet.destination_hash][IDX_PT_HOPS] == 0)
|
||||
for_local_client_link = (packet.packet_type != RNS.Packet.ANNOUNCE) and (packet.destination_hash in Transport.link_table and Transport.link_table[packet.destination_hash][IDX_LT_RCVD_IF] in Transport.local_client_interfaces)
|
||||
for_local_client_link |= (packet.packet_type != RNS.Packet.ANNOUNCE) and (packet.destination_hash in Transport.link_table and Transport.link_table[packet.destination_hash][IDX_LT_NH_IF] in Transport.local_client_interfaces)
|
||||
proof_for_local_client = (packet.destination_hash in Transport.reverse_table) and (Transport.reverse_table[packet.destination_hash][IDX_RT_RCVD_IF] in Transport.local_client_interfaces)
|
||||
|
||||
# Plain broadcast packets from local clients are sent
|
||||
# directly on all attached interfaces, since they are
|
||||
@ -1301,8 +1298,8 @@ class Transport:
|
||||
if packet.transport_id != None and packet.packet_type != RNS.Packet.ANNOUNCE:
|
||||
if packet.transport_id == Transport.identity.hash:
|
||||
if packet.destination_hash in Transport.path_table:
|
||||
next_hop = Transport.path_table[packet.destination_hash][1]
|
||||
remaining_hops = Transport.path_table[packet.destination_hash][2]
|
||||
next_hop = Transport.path_table[packet.destination_hash][IDX_PT_NEXT_HOP]
|
||||
remaining_hops = Transport.path_table[packet.destination_hash][IDX_PT_HOPS]
|
||||
|
||||
if remaining_hops > 1:
|
||||
# Just increase hop count and transmit
|
||||
@ -1322,7 +1319,7 @@ class Transport:
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[2:]
|
||||
|
||||
outbound_interface = Transport.path_table[packet.destination_hash][5]
|
||||
outbound_interface = Transport.path_table[packet.destination_hash][IDX_PT_RVCD_IF]
|
||||
|
||||
if packet.packet_type == RNS.Packet.LINKREQUEST:
|
||||
now = time.time()
|
||||
@ -1369,7 +1366,7 @@ class Transport:
|
||||
Transport.reverse_table[packet.getTruncatedHash()] = reverse_entry
|
||||
|
||||
Transport.transmit(outbound_interface, new_raw)
|
||||
Transport.path_table[packet.destination_hash][0] = time.time()
|
||||
Transport.path_table[packet.destination_hash][IDX_PT_TIMESTAMP] = time.time()
|
||||
|
||||
else:
|
||||
# TODO: There should probably be some kind of REJECT
|
||||
@ -1386,23 +1383,23 @@ class Transport:
|
||||
# the same for this link, direction doesn't
|
||||
# matter, and we simply repeat the packet.
|
||||
outbound_interface = None
|
||||
if link_entry[2] == link_entry[4]:
|
||||
if link_entry[IDX_LT_NH_IF] == link_entry[IDX_LT_RCVD_IF]:
|
||||
# But check that taken hops matches one
|
||||
# of the expectede values.
|
||||
if packet.hops == link_entry[3] or packet.hops == link_entry[5]:
|
||||
outbound_interface = link_entry[2]
|
||||
if packet.hops == link_entry[IDX_LT_REM_HOPS] or packet.hops == link_entry[IDX_LT_HOPS]:
|
||||
outbound_interface = link_entry[IDX_LT_NH_IF]
|
||||
else:
|
||||
# If interfaces differ, we transmit on
|
||||
# the opposite interface of what the
|
||||
# packet was received on.
|
||||
if packet.receiving_interface == link_entry[2]:
|
||||
if packet.receiving_interface == link_entry[IDX_LT_NH_IF]:
|
||||
# Also check that expected hop count matches
|
||||
if packet.hops == link_entry[3]:
|
||||
outbound_interface = link_entry[4]
|
||||
elif packet.receiving_interface == link_entry[4]:
|
||||
if packet.hops == link_entry[IDX_LT_REM_HOPS]:
|
||||
outbound_interface = link_entry[IDX_LT_RCVD_IF]
|
||||
elif packet.receiving_interface == link_entry[IDX_LT_RCVD_IF]:
|
||||
# Also check that expected hop count matches
|
||||
if packet.hops == link_entry[5]:
|
||||
outbound_interface = link_entry[2]
|
||||
if packet.hops == link_entry[IDX_LT_HOPS]:
|
||||
outbound_interface = link_entry[IDX_LT_NH_IF]
|
||||
|
||||
if outbound_interface != None:
|
||||
# Add this packet to the filter hashlist if we
|
||||
@ -1414,7 +1411,7 @@ class Transport:
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[2:]
|
||||
Transport.transmit(outbound_interface, new_raw)
|
||||
Transport.link_table[packet.destination_hash][0] = time.time()
|
||||
Transport.link_table[packet.destination_hash][IDX_LT_TIMESTAMP] = time.time()
|
||||
|
||||
# TODO: Test and possibly enable this at some point
|
||||
# Transport.jobs_locked = False
|
||||
@ -1449,17 +1446,17 @@ class Transport:
|
||||
if RNS.Reticulum.transport_enabled() and packet.destination_hash in Transport.announce_table:
|
||||
announce_entry = Transport.announce_table[packet.destination_hash]
|
||||
|
||||
if packet.hops-1 == announce_entry[4]:
|
||||
if packet.hops-1 == announce_entry[IDX_AT_HOPS]:
|
||||
RNS.log("Heard a local rebroadcast of announce for "+RNS.prettyhexrep(packet.destination_hash), RNS.LOG_DEBUG)
|
||||
announce_entry[6] += 1
|
||||
if announce_entry[6] >= Transport.LOCAL_REBROADCASTS_MAX:
|
||||
announce_entry[IDX_AT_LCL_RBRD] += 1
|
||||
if announce_entry[IDX_AT_LCL_RBRD] >= Transport.LOCAL_REBROADCASTS_MAX:
|
||||
RNS.log("Max local rebroadcasts of announce for "+RNS.prettyhexrep(packet.destination_hash)+" reached, dropping announce from our table", RNS.LOG_DEBUG)
|
||||
if packet.destination_hash in Transport.announce_table:
|
||||
Transport.announce_table.pop(packet.destination_hash)
|
||||
|
||||
if packet.hops-1 == announce_entry[4]+1 and announce_entry[2] > 0:
|
||||
if packet.hops-1 == announce_entry[IDX_AT_HOPS]+1 and announce_entry[IDX_AT_RETRIES] > 0:
|
||||
now = time.time()
|
||||
if now < announce_entry[1]:
|
||||
if now < announce_entry[IDX_AT_RTRNS_TMO]:
|
||||
RNS.log("Rebroadcasted announce for "+RNS.prettyhexrep(packet.destination_hash)+" has been passed on to another node, no further tries needed", RNS.LOG_DEBUG)
|
||||
if packet.destination_hash in Transport.announce_table:
|
||||
Transport.announce_table.pop(packet.destination_hash)
|
||||
@ -1479,12 +1476,12 @@ class Transport:
|
||||
random_blob = packet.data[RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8:RNS.Identity.KEYSIZE//8+RNS.Identity.NAME_HASH_LENGTH//8+10]
|
||||
random_blobs = []
|
||||
if packet.destination_hash in Transport.path_table:
|
||||
random_blobs = Transport.path_table[packet.destination_hash][4]
|
||||
random_blobs = Transport.path_table[packet.destination_hash][IDX_PT_RANDBLOBS]
|
||||
|
||||
# If we already have a path to the announced
|
||||
# destination, but the hop count is equal or
|
||||
# less, we'll update our tables.
|
||||
if packet.hops <= Transport.path_table[packet.destination_hash][2]:
|
||||
if packet.hops <= Transport.path_table[packet.destination_hash][IDX_PT_HOPS]:
|
||||
# Make sure we haven't heard the random
|
||||
# blob before, so announces can't be
|
||||
# replayed to forge paths.
|
||||
@ -1502,7 +1499,7 @@ class Transport:
|
||||
# ignore it, unless the path is expired, or
|
||||
# the emission timestamp is more recent.
|
||||
now = time.time()
|
||||
path_expires = Transport.path_table[packet.destination_hash][3]
|
||||
path_expires = Transport.path_table[packet.destination_hash][IDX_PT_EXPIRES]
|
||||
|
||||
path_announce_emitted = 0
|
||||
for path_random_blob in random_blobs:
|
||||
@ -1622,15 +1619,15 @@ class Transport:
|
||||
retries = Transport.PATHFINDER_R
|
||||
|
||||
Transport.announce_table[packet.destination_hash] = [
|
||||
now,
|
||||
retransmit_timeout,
|
||||
retries,
|
||||
received_from,
|
||||
announce_hops,
|
||||
packet,
|
||||
local_rebroadcasts,
|
||||
block_rebroadcasts,
|
||||
attached_interface
|
||||
now, # 0: IDX_AT_TIMESTAMP
|
||||
retransmit_timeout, # 1: IDX_AT_RTRNS_TMO
|
||||
retries, # 2: IDX_AT_RETRIES
|
||||
received_from, # 3: IDX_AT_RCVD_IF
|
||||
announce_hops, # 4: IDX_AT_HOPS
|
||||
packet, # 5: IDX_AT_PACKET
|
||||
local_rebroadcasts, # 6: IDX_AT_LCL_RBRD
|
||||
block_rebroadcasts, # 7: IDX_AT_BLCK_RBRD
|
||||
attached_interface, # 8: IDX_AT_ATTCHD_IF
|
||||
]
|
||||
|
||||
# TODO: Check from_local_client once and store result
|
||||
@ -1870,8 +1867,8 @@ class Transport:
|
||||
# needs to be transported
|
||||
if (RNS.Reticulum.transport_enabled() or for_local_client_link or from_local_client) and packet.destination_hash in Transport.link_table:
|
||||
link_entry = Transport.link_table[packet.destination_hash]
|
||||
if packet.hops == link_entry[3]:
|
||||
if packet.receiving_interface == link_entry[2]:
|
||||
if packet.hops == link_entry[IDX_LT_REM_HOPS]:
|
||||
if packet.receiving_interface == link_entry[IDX_LT_NH_IF]:
|
||||
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:
|
||||
mtu_bytes = b""
|
||||
@ -1879,19 +1876,19 @@ class Transport:
|
||||
mtu_bytes = RNS.Link.mtu_bytes(RNS.Link.mtu_from_lp_packet(packet))
|
||||
|
||||
peer_pub_bytes = packet.data[RNS.Identity.SIGLENGTH//8:RNS.Identity.SIGLENGTH//8+RNS.Link.ECPUBSIZE//2]
|
||||
peer_identity = RNS.Identity.recall(link_entry[6])
|
||||
peer_identity = RNS.Identity.recall(link_entry[IDX_LT_DSTHASH])
|
||||
peer_sig_pub_bytes = peer_identity.get_public_key()[RNS.Link.ECPUBSIZE//2:RNS.Link.ECPUBSIZE]
|
||||
|
||||
signed_data = packet.destination_hash+peer_pub_bytes+peer_sig_pub_bytes+mtu_bytes
|
||||
signature = packet.data[:RNS.Identity.SIGLENGTH//8]
|
||||
|
||||
if peer_identity.validate(signature, signed_data):
|
||||
RNS.log("Link request proof validated for transport via "+str(link_entry[4]), RNS.LOG_EXTREME)
|
||||
RNS.log("Link request proof validated for transport via "+str(link_entry[IDX_LT_RCVD_IF]), RNS.LOG_EXTREME)
|
||||
new_raw = packet.raw[0:1]
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[2:]
|
||||
Transport.link_table[packet.destination_hash][7] = True
|
||||
Transport.transmit(link_entry[4], new_raw)
|
||||
Transport.link_table[packet.destination_hash][IDX_LT_VALIDATED] = True
|
||||
Transport.transmit(link_entry[IDX_LT_RCVD_IF], new_raw)
|
||||
|
||||
else:
|
||||
RNS.log("Invalid link request proof in transport for link "+RNS.prettyhexrep(packet.destination_hash)+", dropping proof.", RNS.LOG_DEBUG)
|
||||
@ -1945,12 +1942,12 @@ class Transport:
|
||||
# Check if this proof needs to be transported
|
||||
if (RNS.Reticulum.transport_enabled() or from_local_client or proof_for_local_client) and packet.destination_hash in Transport.reverse_table:
|
||||
reverse_entry = Transport.reverse_table.pop(packet.destination_hash)
|
||||
if packet.receiving_interface == reverse_entry[1]:
|
||||
RNS.log("Proof received on correct interface, transporting it via "+str(reverse_entry[0]), RNS.LOG_EXTREME)
|
||||
if packet.receiving_interface == reverse_entry[IDX_RT_OUTB_IF]:
|
||||
RNS.log("Proof received on correct interface, transporting it via "+str(reverse_entry[IDX_RT_RCVD_IF]), RNS.LOG_EXTREME)
|
||||
new_raw = packet.raw[0:1]
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[2:]
|
||||
Transport.transmit(reverse_entry[0], new_raw)
|
||||
Transport.transmit(reverse_entry[IDX_RT_RCVD_IF], new_raw)
|
||||
else:
|
||||
RNS.log("Proof received on wrong interface, not transporting it.", RNS.LOG_DEBUG)
|
||||
|
||||
@ -2046,8 +2043,8 @@ class Transport:
|
||||
should_add = False
|
||||
if destination_hash in Transport.path_table:
|
||||
old_entry = Transport.path_table[destination_hash]
|
||||
old_hops = old_entry[2]
|
||||
old_expires = old_entry[3]
|
||||
old_hops = old_entry[IDX_PT_HOPS]
|
||||
old_expires = old_entry[IDX_PT_EXPIRES]
|
||||
if announce_hops <= old_hops or time.time() > old_expires:
|
||||
should_add = True
|
||||
else:
|
||||
@ -2230,10 +2227,8 @@ class Transport:
|
||||
:param destination_hash: A destination hash as *bytes*.
|
||||
:returns: *True* if a path to the destination is known, otherwise *False*.
|
||||
"""
|
||||
if destination_hash in Transport.path_table:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
if destination_hash in Transport.path_table: return True
|
||||
else: return False
|
||||
|
||||
@staticmethod
|
||||
def hops_to(destination_hash):
|
||||
@ -2241,10 +2236,8 @@ class Transport:
|
||||
:param destination_hash: A destination hash as *bytes*.
|
||||
:returns: The number of hops to the specified destination, or ``RNS.Transport.PATHFINDER_M`` if the number of hops is unknown.
|
||||
"""
|
||||
if destination_hash in Transport.path_table:
|
||||
return Transport.path_table[destination_hash][2]
|
||||
else:
|
||||
return Transport.PATHFINDER_M
|
||||
if destination_hash in Transport.path_table: return Transport.path_table[destination_hash][IDX_PT_HOPS]
|
||||
else: return Transport.PATHFINDER_M
|
||||
|
||||
@staticmethod
|
||||
def next_hop(destination_hash):
|
||||
@ -2252,10 +2245,8 @@ class Transport:
|
||||
:param destination_hash: A destination hash as *bytes*.
|
||||
:returns: The destination hash as *bytes* for the next hop to the specified destination, or *None* if the next hop is unknown.
|
||||
"""
|
||||
if destination_hash in Transport.path_table:
|
||||
return Transport.path_table[destination_hash][1]
|
||||
else:
|
||||
return None
|
||||
if destination_hash in Transport.path_table: return Transport.path_table[destination_hash][IDX_PT_NEXT_HOP]
|
||||
else: return None
|
||||
|
||||
@staticmethod
|
||||
def next_hop_interface(destination_hash):
|
||||
@ -2263,65 +2254,51 @@ class Transport:
|
||||
:param destination_hash: A destination hash as *bytes*.
|
||||
:returns: The interface for the next hop to the specified destination, or *None* if the interface is unknown.
|
||||
"""
|
||||
if destination_hash in Transport.path_table:
|
||||
return Transport.path_table[destination_hash][5]
|
||||
else:
|
||||
return None
|
||||
if destination_hash in Transport.path_table: return Transport.path_table[destination_hash][IDX_PT_RVCD_IF]
|
||||
else: return None
|
||||
|
||||
@staticmethod
|
||||
def next_hop_interface_bitrate(destination_hash):
|
||||
next_hop_interface = Transport.next_hop_interface(destination_hash)
|
||||
if next_hop_interface != None:
|
||||
return next_hop_interface.bitrate
|
||||
else:
|
||||
return None
|
||||
if next_hop_interface != None: return next_hop_interface.bitrate
|
||||
else: return None
|
||||
|
||||
@staticmethod
|
||||
def next_hop_interface_hw_mtu(destination_hash):
|
||||
next_hop_interface = Transport.next_hop_interface(destination_hash)
|
||||
if next_hop_interface != None:
|
||||
if next_hop_interface.AUTOCONFIGURE_MTU or next_hop_interface.FIXED_MTU:
|
||||
return next_hop_interface.HW_MTU
|
||||
else:
|
||||
return None
|
||||
if next_hop_interface.AUTOCONFIGURE_MTU or next_hop_interface.FIXED_MTU: return next_hop_interface.HW_MTU
|
||||
else: return None
|
||||
else:
|
||||
return None
|
||||
|
||||
@staticmethod
|
||||
def next_hop_per_bit_latency(destination_hash):
|
||||
next_hop_interface_bitrate = Transport.next_hop_interface_bitrate(destination_hash)
|
||||
if next_hop_interface_bitrate != None:
|
||||
return (1/next_hop_interface_bitrate)
|
||||
else:
|
||||
return None
|
||||
if next_hop_interface_bitrate != None: return (1/next_hop_interface_bitrate)
|
||||
else: return None
|
||||
|
||||
@staticmethod
|
||||
def next_hop_per_byte_latency(destination_hash):
|
||||
per_bit_latency = Transport.next_hop_per_bit_latency(destination_hash)
|
||||
if per_bit_latency != None:
|
||||
return per_bit_latency*8
|
||||
else:
|
||||
return None
|
||||
if per_bit_latency != None: return per_bit_latency*8
|
||||
else: return None
|
||||
|
||||
@staticmethod
|
||||
def first_hop_timeout(destination_hash):
|
||||
latency = Transport.next_hop_per_byte_latency(destination_hash)
|
||||
if latency != None:
|
||||
return RNS.Reticulum.MTU * latency + RNS.Reticulum.DEFAULT_PER_HOP_TIMEOUT
|
||||
else:
|
||||
return RNS.Reticulum.DEFAULT_PER_HOP_TIMEOUT
|
||||
if latency != None: return RNS.Reticulum.MTU * latency + RNS.Reticulum.DEFAULT_PER_HOP_TIMEOUT
|
||||
else: return RNS.Reticulum.DEFAULT_PER_HOP_TIMEOUT
|
||||
|
||||
@staticmethod
|
||||
def extra_link_proof_timeout(interface):
|
||||
if interface != None:
|
||||
return ((1/interface.bitrate)*8)*RNS.Reticulum.MTU
|
||||
else:
|
||||
return 0
|
||||
if interface != None: return ((1/interface.bitrate)*8)*RNS.Reticulum.MTU
|
||||
else: return 0
|
||||
|
||||
@staticmethod
|
||||
def expire_path(destination_hash):
|
||||
if destination_hash in Transport.path_table:
|
||||
Transport.path_table[destination_hash][0] = 0
|
||||
Transport.path_table[destination_hash][IDX_PT_TIMESTAMP] = 0
|
||||
Transport.tables_last_culled = 0
|
||||
return True
|
||||
else:
|
||||
@ -2531,7 +2508,7 @@ class Transport:
|
||||
destination_exists_on_local_client = False
|
||||
if len(Transport.local_client_interfaces) > 0:
|
||||
if destination_hash in Transport.path_table:
|
||||
destination_interface = Transport.path_table[destination_hash][5]
|
||||
destination_interface = Transport.path_table[destination_hash][IDX_PT_RVCD_IF]
|
||||
|
||||
if Transport.is_local_client_interface(destination_interface):
|
||||
destination_exists_on_local_client = True
|
||||
@ -2543,9 +2520,9 @@ class Transport:
|
||||
RNS.log("Answering path request for "+RNS.prettyhexrep(destination_hash)+interface_str+", destination is local to this system", RNS.LOG_DEBUG)
|
||||
|
||||
elif (RNS.Reticulum.transport_enabled() or is_from_local_client) and (destination_hash in Transport.path_table):
|
||||
packet = Transport.path_table[destination_hash][6]
|
||||
next_hop = Transport.path_table[destination_hash][1]
|
||||
received_from = Transport.path_table[destination_hash][5]
|
||||
packet = Transport.path_table[destination_hash][IDX_PT_PACKET]
|
||||
next_hop = Transport.path_table[destination_hash][IDX_PT_NEXT_HOP]
|
||||
received_from = Transport.path_table[destination_hash][IDX_PT_RVCD_IF]
|
||||
|
||||
if attached_interface.mode == RNS.Interfaces.Interface.Interface.MODE_ROAMING and attached_interface == received_from:
|
||||
RNS.log("Not answering path request on roaming-mode interface, since next hop is on same roaming-mode interface", RNS.LOG_DEBUG)
|
||||
@ -2720,14 +2697,13 @@ class Transport:
|
||||
link.teardown()
|
||||
|
||||
Transport.announce_table = {}
|
||||
Transport.path_table = {}
|
||||
Transport.path_table = {}
|
||||
Transport.reverse_table = {}
|
||||
Transport.link_table = {}
|
||||
Transport.held_announces = {}
|
||||
Transport.announce_handlers = []
|
||||
Transport.tunnels = {}
|
||||
|
||||
|
||||
@staticmethod
|
||||
def shared_connection_reappeared():
|
||||
if Transport.owner.is_connected_to_shared_instance:
|
||||
@ -2742,11 +2718,8 @@ class Transport:
|
||||
if hasattr(interface, "announce_queue") and interface.announce_queue != None:
|
||||
na = len(interface.announce_queue)
|
||||
if na > 0:
|
||||
if na == 1:
|
||||
na_str = "1 announce"
|
||||
else:
|
||||
na_str = str(na)+" announces"
|
||||
|
||||
if na == 1: na_str = "1 announce"
|
||||
else: na_str = str(na)+" announces"
|
||||
interface.announce_queue = []
|
||||
RNS.log("Dropped "+na_str+" on "+str(interface), RNS.LOG_VERBOSE)
|
||||
|
||||
@ -2787,10 +2760,8 @@ class Transport:
|
||||
Transport.saving_packet_hashlist = True
|
||||
save_start = time.time()
|
||||
|
||||
if not RNS.Reticulum.transport_enabled():
|
||||
Transport.packet_hashlist = set()
|
||||
else:
|
||||
RNS.log("Saving packet hashlist to storage...", RNS.LOG_DEBUG)
|
||||
if not RNS.Reticulum.transport_enabled(): Transport.packet_hashlist = set()
|
||||
else: RNS.log("Saving packet hashlist to storage...", RNS.LOG_DEBUG)
|
||||
|
||||
packet_hashlist_path = RNS.Reticulum.storagepath+"/packet_hashlist"
|
||||
file = open(packet_hashlist_path, "wb")
|
||||
@ -2798,10 +2769,8 @@ class Transport:
|
||||
file.close()
|
||||
|
||||
save_time = time.time() - save_start
|
||||
if save_time < 1:
|
||||
time_str = str(round(save_time*1000,2))+"ms"
|
||||
else:
|
||||
time_str = str(round(save_time,2))+"s"
|
||||
if save_time < 1: time_str = str(round(save_time*1000,2))+"ms"
|
||||
else: time_str = str(round(save_time,2))+"s"
|
||||
RNS.log("Saved packet hashlist in "+time_str, RNS.LOG_DEBUG)
|
||||
|
||||
except Exception as e:
|
||||
@ -2832,7 +2801,7 @@ class Transport:
|
||||
for destination_hash in Transport.path_table.copy():
|
||||
# Get the destination entry from the destination table
|
||||
de = Transport.path_table[destination_hash]
|
||||
interface_hash = de[5].get_hash()
|
||||
interface_hash = de[IDX_PT_RVCD_IF].get_hash()
|
||||
|
||||
# Only store destination table entry if the associated
|
||||
# interface is still active
|
||||
@ -2840,12 +2809,12 @@ class Transport:
|
||||
if interface != None:
|
||||
# Get the destination entry from the destination table
|
||||
de = Transport.path_table[destination_hash]
|
||||
timestamp = de[0]
|
||||
received_from = de[1]
|
||||
hops = de[2]
|
||||
expires = de[3]
|
||||
random_blobs = de[4]
|
||||
packet_hash = de[6].get_hash()
|
||||
timestamp = de[IDX_PT_TIMESTAMP]
|
||||
received_from = de[IDX_PT_NEXT_HOP]
|
||||
hops = de[IDX_PT_HOPS]
|
||||
expires = de[IDX_PT_EXPIRES]
|
||||
random_blobs = list(set(de[IDX_PT_RANDBLOBS]))
|
||||
packet_hash = de[IDX_PT_PACKET].get_hash()
|
||||
|
||||
serialised_entry = [
|
||||
destination_hash,
|
||||
@ -2860,7 +2829,7 @@ class Transport:
|
||||
|
||||
serialised_destinations.append(serialised_entry)
|
||||
|
||||
Transport.cache(de[6], force_cache=True)
|
||||
Transport.cache(de[IDX_PT_PACKET], force_cache=True)
|
||||
|
||||
path_table_path = RNS.Reticulum.storagepath+"/destination_table"
|
||||
file = open(path_table_path, "wb")
|
||||
@ -2868,10 +2837,8 @@ class Transport:
|
||||
file.close()
|
||||
|
||||
save_time = time.time() - save_start
|
||||
if save_time < 1:
|
||||
time_str = str(round(save_time*1000,2))+"ms"
|
||||
else:
|
||||
time_str = str(round(save_time,2))+"s"
|
||||
if save_time < 1: time_str = str(round(save_time*1000,2))+"ms"
|
||||
else: time_str = str(round(save_time,2))+"s"
|
||||
RNS.log("Saved "+str(len(serialised_destinations))+" path table entries in "+time_str, RNS.LOG_DEBUG)
|
||||
|
||||
except Exception as e:
|
||||
@ -2946,11 +2913,10 @@ class Transport:
|
||||
file.close()
|
||||
|
||||
save_time = time.time() - save_start
|
||||
if save_time < 1:
|
||||
time_str = str(round(save_time*1000,2))+"ms"
|
||||
else:
|
||||
time_str = str(round(save_time,2))+"s"
|
||||
if save_time < 1: time_str = str(round(save_time*1000,2))+"ms"
|
||||
else: time_str = str(round(save_time,2))+"s"
|
||||
RNS.log("Saved "+str(len(serialised_tunnels))+" tunnel table entries in "+time_str, RNS.LOG_DEBUG)
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Could not save tunnel table to storage, the contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
@ -2966,3 +2932,42 @@ class Transport:
|
||||
def exit_handler():
|
||||
if not Transport.owner.is_connected_to_shared_instance:
|
||||
Transport.persist_data()
|
||||
|
||||
|
||||
# Table entry indices
|
||||
|
||||
# Transport.path_table entry indices
|
||||
IDX_PT_TIMESTAMP = 0
|
||||
IDX_PT_NEXT_HOP = 1
|
||||
IDX_PT_HOPS = 2
|
||||
IDX_PT_EXPIRES = 3
|
||||
IDX_PT_RANDBLOBS = 4
|
||||
IDX_PT_RVCD_IF = 5
|
||||
IDX_PT_PACKET = 6
|
||||
|
||||
# Transport.reverse_table entry indices
|
||||
IDX_RT_RCVD_IF = 0
|
||||
IDX_RT_OUTB_IF = 1
|
||||
IDX_RT_TIMESTAMP = 2
|
||||
|
||||
# Transport.announce_table entry indices
|
||||
IDX_AT_TIMESTAMP = 0
|
||||
IDX_AT_RTRNS_TMO = 1
|
||||
IDX_AT_RETRIES = 2
|
||||
IDX_AT_RCVD_IF = 3
|
||||
IDX_AT_HOPS = 4
|
||||
IDX_AT_PACKET = 5
|
||||
IDX_AT_LCL_RBRD = 6
|
||||
IDX_AT_BLCK_RBRD = 7
|
||||
IDX_AT_ATTCHD_IF = 8
|
||||
|
||||
# Transport.link_table entry indices
|
||||
IDX_LT_TIMESTAMP = 0
|
||||
IDX_LT_NH_TRID = 1
|
||||
IDX_LT_NH_IF = 2
|
||||
IDX_LT_REM_HOPS = 3
|
||||
IDX_LT_RCVD_IF = 4
|
||||
IDX_LT_HOPS = 5
|
||||
IDX_LT_DSTHASH = 6
|
||||
IDX_LT_VALIDATED = 7
|
||||
IDX_LT_PROOF_TMO = 8
|
Loading…
x
Reference in New Issue
Block a user