mirror of
https://github.com/markqvist/Reticulum.git
synced 2026-07-11 02:58:12 -07:00
Cleanup
This commit is contained in:
+5
-8
@@ -602,21 +602,18 @@ class Identity:
|
||||
signal_str = " ["
|
||||
if packet.rssi != None:
|
||||
signal_str += "RSSI "+str(packet.rssi)+"dBm"
|
||||
if packet.snr != None:
|
||||
signal_str += ", "
|
||||
if packet.snr != None:
|
||||
signal_str += "SNR "+str(packet.snr)+"dB"
|
||||
if packet.snr != None: signal_str += ", "
|
||||
if packet.snr != None: signal_str += "SNR "+str(packet.snr)+"dB"
|
||||
signal_str += "]"
|
||||
else:
|
||||
signal_str = ""
|
||||
|
||||
else: signal_str = ""
|
||||
|
||||
if hasattr(packet, "transport_id") and packet.transport_id != None:
|
||||
RNS.log("Valid announce for "+RNS.prettyhexrep(destination_hash)+" "+str(packet.hops)+" hops away, received via "+RNS.prettyhexrep(packet.transport_id)+" on "+str(packet.receiving_interface)+signal_str, RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
|
||||
else:
|
||||
RNS.log("Valid announce for "+RNS.prettyhexrep(destination_hash)+" "+str(packet.hops)+" hops away, received on "+str(packet.receiving_interface)+signal_str, RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
|
||||
|
||||
if ratchet:
|
||||
Identity._remember_ratchet(destination_hash, ratchet)
|
||||
if ratchet: Identity._remember_ratchet(destination_hash, ratchet)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
+72
-152
@@ -191,8 +191,7 @@ class Link:
|
||||
|
||||
if len(data) == Link.ECPUBSIZE+Link.LINK_MTU_SIZE:
|
||||
RNS.log("Link request includes MTU signalling", RNS.LOG_DEBUG) # TODO: Remove debug
|
||||
try:
|
||||
link.mtu = Link.mtu_from_lr_packet(packet) or Reticulum.MTU
|
||||
try: link.mtu = Link.mtu_from_lr_packet(packet) or Reticulum.MTU
|
||||
except Exception as e:
|
||||
RNS.trace_exception(e)
|
||||
link.mtu = RNS.Reticulum.MTU
|
||||
@@ -277,6 +276,7 @@ class Link:
|
||||
self.initiator = False
|
||||
self.prv = X25519PrivateKey.generate()
|
||||
self.sig_prv = self.owner.identity.sig_prv
|
||||
|
||||
else:
|
||||
self.initiator = True
|
||||
self.expected_hops = RNS.Transport.hops_to(self.destination.hash)
|
||||
@@ -296,14 +296,11 @@ class Link:
|
||||
if peer_pub_bytes == None:
|
||||
self.peer_pub = None
|
||||
self.peer_pub_bytes = None
|
||||
else:
|
||||
self.load_peer(peer_pub_bytes, peer_sig_pub_bytes)
|
||||
|
||||
if established_callback != None:
|
||||
self.set_link_established_callback(established_callback)
|
||||
else: self.load_peer(peer_pub_bytes, peer_sig_pub_bytes)
|
||||
|
||||
if closed_callback != None:
|
||||
self.set_link_closed_callback(closed_callback)
|
||||
if established_callback != None: self.set_link_established_callback(established_callback)
|
||||
if closed_callback != None: self.set_link_closed_callback(closed_callback)
|
||||
|
||||
if self.initiator:
|
||||
signalling_bytes = b""
|
||||
@@ -334,8 +331,7 @@ class Link:
|
||||
self.peer_sig_pub_bytes = peer_sig_pub_bytes
|
||||
self.peer_sig_pub = Ed25519PublicKey.from_public_bytes(self.peer_sig_pub_bytes)
|
||||
|
||||
if not hasattr(self.peer_pub, "curve"):
|
||||
self.peer_pub.curve = Link.CURVE
|
||||
if not hasattr(self.peer_pub, "curve"): self.peer_pub.curve = Link.CURVE
|
||||
|
||||
@staticmethod
|
||||
def link_id_from_lr_packet(packet):
|
||||
@@ -447,8 +443,8 @@ class Link:
|
||||
thread = threading.Thread(target=self.callbacks.link_established, args=(self,))
|
||||
thread.daemon = True
|
||||
thread.start()
|
||||
else:
|
||||
RNS.log("Invalid link proof signature received by "+str(self)+". Ignoring.", RNS.LOG_DEBUG)
|
||||
|
||||
else: RNS.log("Invalid link proof signature received by "+str(self)+". Ignoring.", RNS.LOG_DEBUG)
|
||||
|
||||
except Exception as e:
|
||||
self.status = Link.CLOSED
|
||||
@@ -497,35 +493,21 @@ class Link:
|
||||
request_packet = RNS.Packet(self, packed_request, RNS.Packet.DATA, context = RNS.Packet.REQUEST)
|
||||
packet_receipt = request_packet.send()
|
||||
|
||||
if packet_receipt == False:
|
||||
return False
|
||||
if packet_receipt == False: return False
|
||||
else:
|
||||
packet_receipt.set_timeout(timeout)
|
||||
return RequestReceipt(
|
||||
self,
|
||||
packet_receipt = packet_receipt,
|
||||
response_callback = response_callback,
|
||||
failed_callback = failed_callback,
|
||||
progress_callback = progress_callback,
|
||||
timeout = timeout,
|
||||
request_size = len(packed_request),
|
||||
)
|
||||
return RequestReceipt(self, packet_receipt = packet_receipt, response_callback = response_callback,
|
||||
failed_callback = failed_callback, progress_callback = progress_callback,
|
||||
timeout = timeout, request_size = len(packed_request))
|
||||
|
||||
else:
|
||||
request_id = RNS.Identity.truncated_hash(packed_request)
|
||||
RNS.log("Sending request "+RNS.prettyhexrep(request_id)+" as resource.", RNS.LOG_DEBUG)
|
||||
request_resource = RNS.Resource(packed_request, self, request_id = request_id, is_response = False, timeout = timeout)
|
||||
|
||||
return RequestReceipt(
|
||||
self,
|
||||
resource = request_resource,
|
||||
response_callback = response_callback,
|
||||
failed_callback = failed_callback,
|
||||
progress_callback = progress_callback,
|
||||
timeout = timeout,
|
||||
request_size = len(packed_request),
|
||||
)
|
||||
|
||||
return RequestReceipt(self, resource = request_resource, response_callback = response_callback,
|
||||
failed_callback = failed_callback, progress_callback = progress_callback,
|
||||
timeout = timeout, request_size = len(packed_request))
|
||||
|
||||
def update_mdu(self):
|
||||
self.mdu = self.mtu - RNS.Reticulum.HEADER_MAXSIZE - RNS.Reticulum.IFAC_MIN_SIZE
|
||||
@@ -547,10 +529,8 @@ class Link:
|
||||
self.__update_keepalive()
|
||||
|
||||
try:
|
||||
if self.owner.callbacks.link_established != None:
|
||||
self.owner.callbacks.link_established(self)
|
||||
except Exception as e:
|
||||
RNS.log("Error occurred in external link establishment callback. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
if self.owner.callbacks.link_established != None: self.owner.callbacks.link_established(self)
|
||||
except Exception as e: RNS.log("Error occurred in external link establishment callback. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Error occurred while processing RTT packet, tearing down link. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
@@ -565,73 +545,57 @@ class Link:
|
||||
|
||||
:param track: Whether or not to keep track of physical layer statistics. Value must be ``True`` or ``False``.
|
||||
"""
|
||||
if track:
|
||||
self.__track_phy_stats = True
|
||||
else:
|
||||
self.__track_phy_stats = False
|
||||
if track: self.__track_phy_stats = True
|
||||
else: self.__track_phy_stats = False
|
||||
|
||||
def get_rssi(self):
|
||||
"""
|
||||
:returns: The physical layer *Received Signal Strength Indication* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value.
|
||||
"""
|
||||
if self.__track_phy_stats:
|
||||
return self.rssi
|
||||
else:
|
||||
return None
|
||||
if self.__track_phy_stats: return self.rssi
|
||||
else: return None
|
||||
|
||||
def get_snr(self):
|
||||
"""
|
||||
:returns: The physical layer *Signal-to-Noise Ratio* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value.
|
||||
"""
|
||||
if self.__track_phy_stats:
|
||||
return self.snr
|
||||
else:
|
||||
return None
|
||||
if self.__track_phy_stats: return self.snr
|
||||
else: return None
|
||||
|
||||
def get_q(self):
|
||||
"""
|
||||
:returns: The physical layer *Link Quality* if available, otherwise ``None``. Physical layer statistics must be enabled on the link for this method to return a value.
|
||||
"""
|
||||
if self.__track_phy_stats:
|
||||
return self.q
|
||||
else:
|
||||
return None
|
||||
if self.__track_phy_stats: return self.q
|
||||
else: return None
|
||||
|
||||
def get_establishment_rate(self):
|
||||
"""
|
||||
:returns: The data transfer rate at which the link establishment procedure ocurred, in bits per second.
|
||||
"""
|
||||
if self.establishment_rate != None:
|
||||
return self.establishment_rate*8
|
||||
else:
|
||||
return None
|
||||
if self.establishment_rate != None: return self.establishment_rate*8
|
||||
else: return None
|
||||
|
||||
def get_mtu(self):
|
||||
"""
|
||||
:returns: The MTU of an established link.
|
||||
"""
|
||||
if self.status == Link.ACTIVE:
|
||||
return self.mtu
|
||||
else:
|
||||
return None
|
||||
if self.status == Link.ACTIVE: return self.mtu
|
||||
else: return None
|
||||
|
||||
def get_mdu(self):
|
||||
"""
|
||||
:returns: The packet MDU of an established link.
|
||||
"""
|
||||
if self.status == Link.ACTIVE:
|
||||
return self.mdu
|
||||
else:
|
||||
return None
|
||||
if self.status == Link.ACTIVE: return self.mdu
|
||||
else: return None
|
||||
|
||||
def get_expected_rate(self):
|
||||
"""
|
||||
:returns: The packet expected in-flight data rate of an established link.
|
||||
"""
|
||||
if self.status == Link.ACTIVE:
|
||||
return self.expected_rate
|
||||
else:
|
||||
return None
|
||||
if self.status == Link.ACTIVE: return self.expected_rate
|
||||
else: return None
|
||||
|
||||
def get_mode(self):
|
||||
"""
|
||||
@@ -649,10 +613,8 @@ class Link:
|
||||
"""
|
||||
:returns: The time in seconds since this link was established.
|
||||
"""
|
||||
if self.activated_at:
|
||||
return time.time() - self.activated_at
|
||||
else:
|
||||
return None
|
||||
if self.activated_at: return time.time() - self.activated_at
|
||||
else: return None
|
||||
|
||||
def no_inbound_for(self):
|
||||
"""
|
||||
@@ -712,14 +674,11 @@ class Link:
|
||||
plaintext = self.decrypt(packet.data)
|
||||
if plaintext == self.link_id:
|
||||
self.status = Link.CLOSED
|
||||
if self.initiator:
|
||||
self.teardown_reason = Link.DESTINATION_CLOSED
|
||||
else:
|
||||
self.teardown_reason = Link.INITIATOR_CLOSED
|
||||
if self.initiator: self.teardown_reason = Link.DESTINATION_CLOSED
|
||||
else: self.teardown_reason = Link.INITIATOR_CLOSED
|
||||
self.__update_phy_stats(packet)
|
||||
self.link_closed()
|
||||
except Exception as e:
|
||||
pass
|
||||
except Exception as e: pass
|
||||
|
||||
def link_closed(self):
|
||||
for resource in self.incoming_resources: resource.cancel()
|
||||
@@ -752,9 +711,7 @@ class Link:
|
||||
while not self.status == Link.CLOSED:
|
||||
while (self.watchdog_lock):
|
||||
rtt_wait = 0.025
|
||||
if hasattr(self, "rtt") and self.rtt:
|
||||
rtt_wait = self.rtt
|
||||
|
||||
if hasattr(self, "rtt") and self.rtt: rtt_wait = self.rtt
|
||||
sleep(max(rtt_wait, 0.025))
|
||||
|
||||
if not self.status == Link.CLOSED:
|
||||
@@ -779,10 +736,8 @@ class Link:
|
||||
self.link_closed()
|
||||
sleep_time = 0.001
|
||||
|
||||
if self.initiator:
|
||||
RNS.log("Timeout waiting for link request proof", RNS.LOG_DEBUG)
|
||||
else:
|
||||
RNS.log("Timeout waiting for RTT packet from link initiator", RNS.LOG_DEBUG)
|
||||
if self.initiator: RNS.log("Timeout waiting for link request proof", RNS.LOG_DEBUG)
|
||||
else: RNS.log("Timeout waiting for RTT packet from link initiator", RNS.LOG_DEBUG)
|
||||
|
||||
elif self.status == Link.ACTIVE:
|
||||
activated_at = self.activated_at if self.activated_at != None else 0
|
||||
@@ -796,11 +751,10 @@ class Link:
|
||||
if time.time() >= last_inbound + self.stale_time:
|
||||
sleep_time = self.rtt * self.keepalive_timeout_factor + Link.STALE_GRACE
|
||||
self.status = Link.STALE
|
||||
else:
|
||||
sleep_time = self.keepalive
|
||||
|
||||
else: sleep_time = self.keepalive
|
||||
|
||||
else:
|
||||
sleep_time = (last_inbound + self.keepalive) - time.time()
|
||||
else: sleep_time = (last_inbound + self.keepalive) - time.time()
|
||||
|
||||
elif self.status == Link.STALE:
|
||||
sleep_time = 0.001
|
||||
@@ -810,8 +764,7 @@ class Link:
|
||||
self.link_closed()
|
||||
|
||||
|
||||
if sleep_time == 0:
|
||||
RNS.log("Warning! Link watchdog sleep time of 0!", RNS.LOG_ERROR)
|
||||
if sleep_time == 0: RNS.log("Warning! Link watchdog sleep time of 0!", RNS.LOG_ERROR)
|
||||
if sleep_time == None or sleep_time < 0:
|
||||
RNS.log("Timing error! Tearing down link "+str(self)+" now.", RNS.LOG_ERROR)
|
||||
self.teardown()
|
||||
@@ -825,7 +778,6 @@ class Link:
|
||||
self.snr = None
|
||||
self.q = None
|
||||
|
||||
|
||||
def __update_phy_stats(self, packet, query_shared = True, force_update = False):
|
||||
if self.__track_phy_stats or force_update:
|
||||
if query_shared:
|
||||
@@ -834,12 +786,9 @@ class Link:
|
||||
if packet.snr == None: packet.snr = reticulum.get_packet_snr(packet.packet_hash)
|
||||
if packet.q == None: packet.q = reticulum.get_packet_q(packet.packet_hash)
|
||||
|
||||
if packet.rssi != None:
|
||||
self.rssi = packet.rssi
|
||||
if packet.snr != None:
|
||||
self.snr = packet.snr
|
||||
if packet.q != None:
|
||||
self.q = packet.q
|
||||
if packet.rssi != None: self.rssi = packet.rssi
|
||||
if packet.snr != None: self.snr = packet.snr
|
||||
if packet.q != None: self.q = packet.q
|
||||
|
||||
def __update_keepalive(self):
|
||||
self.keepalive = max(min(self.rtt*(Link.KEEPALIVE_MAX/Link.KEEPALIVE_MAX_RTT), Link.KEEPALIVE_MAX), Link.KEEPALIVE_MIN)
|
||||
@@ -933,8 +882,8 @@ class Link:
|
||||
|
||||
def job(): self.handle_request(request_id, request_data)
|
||||
threading.Thread(target=job, daemon=True).start()
|
||||
else:
|
||||
RNS.log("Incoming request resource failed with status: "+RNS.hexrep([resource.status]), RNS.LOG_DEBUG)
|
||||
|
||||
else: RNS.log("Incoming request resource failed with status: "+RNS.hexrep([resource.status]), RNS.LOG_DEBUG)
|
||||
|
||||
def response_resource_concluded(self, resource):
|
||||
if resource.status == RNS.Resource.COMPLETE:
|
||||
@@ -965,8 +914,7 @@ class Link:
|
||||
|
||||
:return: ``Channel`` object
|
||||
"""
|
||||
if self._channel is None:
|
||||
self._channel = Channel(LinkChannelOutlet(self))
|
||||
if self._channel is None: self._channel = Channel(LinkChannelOutlet(self))
|
||||
return self._channel
|
||||
|
||||
def receive(self, packet):
|
||||
@@ -976,12 +924,10 @@ class Link:
|
||||
RNS.log(f"Link-associated packet received on unexpected interface {packet.receiving_interface} instead of {self.attached_interface}! Someone might be trying to manipulate your communication!", RNS.LOG_ERROR)
|
||||
else:
|
||||
self.last_inbound = time.time()
|
||||
if packet.context != RNS.Packet.KEEPALIVE:
|
||||
self.last_data = self.last_inbound
|
||||
if packet.context != RNS.Packet.KEEPALIVE: self.last_data = self.last_inbound
|
||||
self.rx += 1
|
||||
self.rxbytes += len(packet.data)
|
||||
if self.status == Link.STALE:
|
||||
self.status = Link.ACTIVE
|
||||
if self.status == Link.STALE: self.status = Link.ACTIVE
|
||||
|
||||
if packet.packet_type == RNS.Packet.DATA:
|
||||
should_query = False
|
||||
@@ -1002,10 +948,8 @@ class Link:
|
||||
elif self.destination.proof_strategy == RNS.Destination.PROVE_APP:
|
||||
if self.destination.callbacks.proof_requested:
|
||||
try:
|
||||
if self.destination.callbacks.proof_requested(packet):
|
||||
packet.prove()
|
||||
except Exception as e:
|
||||
RNS.log("Error while executing proof request callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
if self.destination.callbacks.proof_requested(packet): packet.prove()
|
||||
except Exception as e: RNS.log("Error while executing proof request callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
elif packet.context == RNS.Packet.LINKIDENTIFY:
|
||||
plaintext = self.decrypt(packet.data)
|
||||
@@ -1039,8 +983,7 @@ class Link:
|
||||
def job(): self.handle_request(request_id, unpacked_request)
|
||||
threading.Thread(target=job, daemon=True).start()
|
||||
self.__update_phy_stats(packet, query_shared=True)
|
||||
except Exception as e:
|
||||
RNS.log("Error occurred while handling request. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
except Exception as e: RNS.log("Error occurred while handling request. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
elif packet.context == RNS.Packet.RESPONSE:
|
||||
try:
|
||||
@@ -1053,8 +996,7 @@ class Link:
|
||||
def job(): self.handle_response(request_id, response_data, transfer_size, transfer_size, update_sizes=True)
|
||||
threading.Thread(target=job, daemon=True).start()
|
||||
self.__update_phy_stats(packet, query_shared=True)
|
||||
except Exception as e:
|
||||
RNS.log("Error occurred while handling response. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
except Exception as e: RNS.log("Error occurred while handling response. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
elif packet.context == RNS.Packet.LRRTT:
|
||||
if not self.initiator:
|
||||
@@ -1186,7 +1128,6 @@ class Link:
|
||||
|
||||
self.watchdog_lock = False
|
||||
|
||||
|
||||
def encrypt(self, plaintext):
|
||||
try:
|
||||
if not self.token:
|
||||
@@ -1201,7 +1142,6 @@ class Link:
|
||||
RNS.log("Encryption on link "+str(self)+" failed. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
raise e
|
||||
|
||||
|
||||
def decrypt(self, ciphertext):
|
||||
try:
|
||||
if not self.token: self.token = Token(self.derived_key)
|
||||
@@ -1211,7 +1151,6 @@ class Link:
|
||||
RNS.log("Decryption failed on link "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
return None
|
||||
|
||||
|
||||
def sign(self, message):
|
||||
return self.sig_prv.sign(message)
|
||||
|
||||
@@ -1219,8 +1158,7 @@ class Link:
|
||||
try:
|
||||
self.peer_sig_pub.verify(signature, message)
|
||||
return True
|
||||
except Exception as e:
|
||||
return False
|
||||
except Exception as e: return False
|
||||
|
||||
def set_link_established_callback(self, callback):
|
||||
self.callbacks.link_established = callback
|
||||
@@ -1388,7 +1326,6 @@ class RequestReceipt():
|
||||
|
||||
self.link.pending_requests.append(self)
|
||||
|
||||
|
||||
def request_resource_concluded(self, resource):
|
||||
if resource.status == RNS.Resource.COMPLETE:
|
||||
RNS.log("Request "+RNS.prettyhexrep(self.request_id)+" successfully sent as resource.", RNS.LOG_DEBUG)
|
||||
@@ -1411,7 +1348,6 @@ class RequestReceipt():
|
||||
except Exception as e:
|
||||
RNS.log("Error while executing request failed callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
|
||||
def __response_timeout_job(self):
|
||||
while self.status == RequestReceipt.DELIVERED:
|
||||
now = time.time()
|
||||
@@ -1421,7 +1357,6 @@ class RequestReceipt():
|
||||
|
||||
time.sleep(0.1)
|
||||
|
||||
|
||||
def request_timed_out(self, packet_receipt):
|
||||
if self in self.link.pending_requests and self.status == RequestReceipt.DELIVERED:
|
||||
self.status = RequestReceipt.FAILED
|
||||
@@ -1430,9 +1365,7 @@ class RequestReceipt():
|
||||
|
||||
if self.callbacks.failed != None:
|
||||
try: self.callbacks.failed(self)
|
||||
except Exception as e:
|
||||
RNS.log("Error while executing request timed out callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
except Exception as e: RNS.log("Error while executing request timed out callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
def response_resource_progress(self, resource):
|
||||
if resource != None:
|
||||
@@ -1449,13 +1382,10 @@ class RequestReceipt():
|
||||
self.progress = resource.get_progress()
|
||||
|
||||
if self.callbacks.progress != None:
|
||||
try:
|
||||
self.callbacks.progress(self)
|
||||
except Exception as e:
|
||||
RNS.log("Error while executing response progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
else:
|
||||
resource.cancel()
|
||||
|
||||
try: self.callbacks.progress(self)
|
||||
except Exception as e: RNS.log("Error while executing response progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
else: resource.cancel()
|
||||
|
||||
def response_received(self, response, metadata=None):
|
||||
if not self.status == RequestReceipt.FAILED:
|
||||
@@ -1474,13 +1404,11 @@ class RequestReceipt():
|
||||
|
||||
if self.callbacks.progress != None:
|
||||
try: self.callbacks.progress(self)
|
||||
except Exception as e:
|
||||
RNS.log("Error while executing response progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
except Exception as e: RNS.log("Error while executing response progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
if self.callbacks.response != None:
|
||||
try: self.callbacks.response(self)
|
||||
except Exception as e:
|
||||
RNS.log("Error while executing response received callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
except Exception as e: RNS.log("Error while executing response received callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
def get_request_id(self):
|
||||
"""
|
||||
@@ -1504,31 +1432,23 @@ class RequestReceipt():
|
||||
"""
|
||||
:returns: The response as *bytes* if it is ready, otherwise *None*.
|
||||
"""
|
||||
if self.status == RequestReceipt.READY:
|
||||
return self.response
|
||||
else:
|
||||
return None
|
||||
if self.status == RequestReceipt.READY: return self.response
|
||||
else: return None
|
||||
|
||||
def get_response_time(self):
|
||||
"""
|
||||
:returns: The response time of the request in seconds.
|
||||
"""
|
||||
if self.status == RequestReceipt.READY:
|
||||
return self.response_concluded_at - self.started_at
|
||||
else:
|
||||
return None
|
||||
if self.status == RequestReceipt.READY: return self.response_concluded_at - self.started_at
|
||||
else: return None
|
||||
|
||||
def concluded(self):
|
||||
"""
|
||||
:returns: True if the associated request has concluded (successfully or with a failure), otherwise False.
|
||||
"""
|
||||
if self.status == RequestReceipt.READY:
|
||||
return True
|
||||
elif self.status == RequestReceipt.FAILED:
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
|
||||
if self.status == RequestReceipt.READY: return True
|
||||
elif self.status == RequestReceipt.FAILED: return True
|
||||
else: return False
|
||||
|
||||
|
||||
class RequestReceiptCallbacks:
|
||||
|
||||
+40
-69
@@ -313,51 +313,40 @@ class Packet:
|
||||
# encrypted destinations
|
||||
self.pack()
|
||||
|
||||
if RNS.Transport.outbound(self):
|
||||
return self.receipt
|
||||
if RNS.Transport.outbound(self): return self.receipt
|
||||
else:
|
||||
RNS.log("Re-send failed. No interfaces could process the outbound packet", RNS.LOG_WARNING)
|
||||
self.sent = False
|
||||
self.receipt = None
|
||||
return False
|
||||
else:
|
||||
raise IOError("Packet was not sent yet")
|
||||
|
||||
else: raise IOError("Packet was not sent yet")
|
||||
|
||||
def prove(self, destination=None):
|
||||
if self.fromPacked and hasattr(self, "destination") and self.destination:
|
||||
if self.destination.identity and self.destination.identity.prv:
|
||||
self.destination.identity.prove(self, destination)
|
||||
elif self.fromPacked and hasattr(self, "link") and self.link:
|
||||
self.link.prove_packet(self)
|
||||
else:
|
||||
RNS.log("Could not prove packet associated with neither a destination nor a link", RNS.LOG_ERROR)
|
||||
elif self.fromPacked and hasattr(self, "link") and self.link: self.link.prove_packet(self)
|
||||
else: RNS.log("Could not prove packet associated with neither a destination nor a link", RNS.LOG_ERROR)
|
||||
|
||||
# Generates a special destination that allows Reticulum
|
||||
# to direct the proof back to the proved packet's sender
|
||||
def generate_proof_destination(self):
|
||||
return ProofDestination(self)
|
||||
def generate_proof_destination(self): return ProofDestination(self)
|
||||
|
||||
def validate_proof_packet(self, proof_packet):
|
||||
return self.receipt.validate_proof_packet(proof_packet)
|
||||
def validate_proof_packet(self, proof_packet): return self.receipt.validate_proof_packet(proof_packet)
|
||||
|
||||
def validate_proof(self, proof):
|
||||
return self.receipt.validate_proof(proof)
|
||||
def validate_proof(self, proof): return self.receipt.validate_proof(proof)
|
||||
|
||||
def update_hash(self):
|
||||
self.packet_hash = self.get_hash()
|
||||
def update_hash(self): self.packet_hash = self.get_hash()
|
||||
|
||||
def get_hash(self):
|
||||
return RNS.Identity.full_hash(self.get_hashable_part())
|
||||
def get_hash(self): return RNS.Identity.full_hash(self.get_hashable_part())
|
||||
|
||||
def getTruncatedHash(self):
|
||||
return RNS.Identity.truncated_hash(self.get_hashable_part())
|
||||
def getTruncatedHash(self): return RNS.Identity.truncated_hash(self.get_hashable_part())
|
||||
|
||||
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:]
|
||||
else:
|
||||
hashable_part += self.raw[2:]
|
||||
if self.header_type == Packet.HEADER_2: hashable_part += self.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
|
||||
else: hashable_part += self.raw[2:]
|
||||
|
||||
return hashable_part
|
||||
|
||||
@@ -365,36 +354,29 @@ class Packet:
|
||||
"""
|
||||
:returns: The physical layer *Received Signal Strength Indication* if available, otherwise ``None``.
|
||||
"""
|
||||
if self.rssi != None:
|
||||
return self.rssi
|
||||
else:
|
||||
return reticulum.get_packet_rssi(self.packet_hash)
|
||||
if self.rssi != None: return self.rssi
|
||||
else: return reticulum.get_packet_rssi(self.packet_hash)
|
||||
|
||||
def get_snr(self):
|
||||
"""
|
||||
:returns: The physical layer *Signal-to-Noise Ratio* if available, otherwise ``None``.
|
||||
"""
|
||||
if self.snr != None:
|
||||
return self.snr
|
||||
else:
|
||||
return reticulum.get_packet_snr(self.packet_hash)
|
||||
if self.snr != None: return self.snr
|
||||
else: return reticulum.get_packet_snr(self.packet_hash)
|
||||
|
||||
def get_q(self):
|
||||
"""
|
||||
:returns: The physical layer *Link Quality* if available, otherwise ``None``.
|
||||
"""
|
||||
if self.q != None:
|
||||
return self.q
|
||||
else:
|
||||
return reticulum.get_packet_q(self.packet_hash)
|
||||
if self.q != None: return self.q
|
||||
else: return reticulum.get_packet_q(self.packet_hash)
|
||||
|
||||
class ProofDestination:
|
||||
def __init__(self, packet):
|
||||
self.hash = packet.get_hash()[:RNS.Reticulum.TRUNCATED_HASHLENGTH//8];
|
||||
self.type = RNS.Destination.SINGLE
|
||||
|
||||
def encrypt(self, plaintext):
|
||||
return plaintext
|
||||
def encrypt(self, plaintext): return plaintext
|
||||
|
||||
|
||||
class PacketReceipt:
|
||||
@@ -463,18 +445,17 @@ class PacketReceipt:
|
||||
link.last_proof = self.concluded_at
|
||||
|
||||
if self.callbacks.delivery != None:
|
||||
try:
|
||||
self.callbacks.delivery(self)
|
||||
try: self.callbacks.delivery(self)
|
||||
except Exception as e:
|
||||
RNS.log("An error occurred while evaluating external delivery callback for "+str(link), RNS.LOG_ERROR)
|
||||
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
RNS.trace_exception(e)
|
||||
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
else: return False
|
||||
else: return False
|
||||
|
||||
elif len(proof) == PacketReceipt.IMPL_LENGTH:
|
||||
pass
|
||||
# TODO: Why is this disabled?
|
||||
@@ -491,8 +472,7 @@ class PacketReceipt:
|
||||
# else:
|
||||
# RNS.log("invalid")
|
||||
# return False
|
||||
else:
|
||||
return False
|
||||
else: return False
|
||||
|
||||
# Validate a raw proof
|
||||
def validate_proof(self, proof, proof_packet=None):
|
||||
@@ -509,24 +489,20 @@ class PacketReceipt:
|
||||
self.proof_packet = proof_packet
|
||||
|
||||
if self.callbacks.delivery != None:
|
||||
try:
|
||||
self.callbacks.delivery(self)
|
||||
try: self.callbacks.delivery(self)
|
||||
except Exception as e:
|
||||
RNS.log("Error while executing proof validated callback. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
else: return False
|
||||
else: return False
|
||||
|
||||
elif len(proof) == PacketReceipt.IMPL_LENGTH:
|
||||
# This is an implicit proof
|
||||
|
||||
if not hasattr(self.destination, "identity"):
|
||||
return False
|
||||
|
||||
if self.destination.identity == None:
|
||||
return False
|
||||
if not hasattr(self.destination, "identity"): return False
|
||||
if self.destination.identity == None: return False
|
||||
|
||||
signature = proof[:RNS.Identity.SIGLENGTH//8]
|
||||
proof_valid = self.destination.identity.validate(signature, self.hash)
|
||||
@@ -537,16 +513,13 @@ class PacketReceipt:
|
||||
self.proof_packet = proof_packet
|
||||
|
||||
if self.callbacks.delivery != None:
|
||||
try:
|
||||
self.callbacks.delivery(self)
|
||||
except Exception as e:
|
||||
RNS.log("Error while executing proof validated callback. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
try: self.callbacks.delivery(self)
|
||||
except Exception as e: RNS.log("Error while executing proof validated callback. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
|
||||
return True
|
||||
else:
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
else: return False
|
||||
else: return False
|
||||
|
||||
def get_rtt(self):
|
||||
"""
|
||||
@@ -559,10 +532,8 @@ class PacketReceipt:
|
||||
|
||||
def check_timeout(self):
|
||||
if self.status == PacketReceipt.SENT and self.is_timed_out():
|
||||
if self.timeout == -1:
|
||||
self.status = PacketReceipt.CULLED
|
||||
else:
|
||||
self.status = PacketReceipt.FAILED
|
||||
if self.timeout == -1: self.status = PacketReceipt.CULLED
|
||||
else: self.status = PacketReceipt.FAILED
|
||||
|
||||
self.concluded_at = time.time()
|
||||
|
||||
|
||||
+1
-2
@@ -31,5 +31,4 @@
|
||||
class Resolver:
|
||||
|
||||
@staticmethod
|
||||
def resolve_identity(full_name):
|
||||
pass
|
||||
def resolve_identity(full_name): pass
|
||||
+129
-186
@@ -253,6 +253,7 @@ class Reticulum:
|
||||
Reticulum.__network_identity = None
|
||||
Reticulum.__transport_enabled = False
|
||||
Reticulum.__static_transport_identity = False
|
||||
Reticulum.__local_hops_delta = False
|
||||
Reticulum.__link_mtu_discovery = Reticulum.LINK_MTU_DISCOVERY
|
||||
Reticulum.__remote_management_enabled = False
|
||||
Reticulum.__use_implicit_proof = True
|
||||
@@ -387,11 +388,7 @@ class Reticulum:
|
||||
def __start_local_interface(self):
|
||||
if self.share_instance:
|
||||
try:
|
||||
interface = LocalInterface.LocalServerInterface(
|
||||
RNS.Transport,
|
||||
self.local_interface_port,
|
||||
socket_path=self.local_socket_path
|
||||
)
|
||||
interface = LocalInterface.LocalServerInterface(RNS.Transport, self.local_interface_port, socket_path=self.local_socket_path)
|
||||
interface.OUT = True
|
||||
if hasattr(Reticulum, "_force_shared_instance_bitrate"):
|
||||
interface.bitrate = Reticulum._force_shared_instance_bitrate
|
||||
@@ -433,6 +430,7 @@ class Reticulum:
|
||||
Reticulum.__remote_management_enabled = False
|
||||
Reticulum.__allow_probes = False
|
||||
RNS.log("Connected to locally available Reticulum instance via: "+str(interface), RNS.LOG_DEBUG)
|
||||
|
||||
except Exception as e:
|
||||
RNS.log("Local shared instance appears to be running, but it could not be connected", RNS.LOG_ERROR)
|
||||
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||
@@ -505,6 +503,10 @@ class Reticulum:
|
||||
v = self.config["reticulum"].as_bool(option)
|
||||
if v == True: Reticulum.__static_transport_identity = True
|
||||
|
||||
if option == "local_hops_delta":
|
||||
v = self.config["reticulum"].as_bool(option)
|
||||
if v == True: Reticulum.__local_hops_delta = True
|
||||
|
||||
if option == "network_identity":
|
||||
if Reticulum.__network_identity == None:
|
||||
path = self.config["reticulum"][option]
|
||||
@@ -737,24 +739,19 @@ class Reticulum:
|
||||
|
||||
ifac_size = None
|
||||
if "ifac_size" in c:
|
||||
if c.as_int("ifac_size") >= Reticulum.IFAC_MIN_SIZE*8:
|
||||
ifac_size = c.as_int("ifac_size")//8
|
||||
if c.as_int("ifac_size") >= Reticulum.IFAC_MIN_SIZE*8: ifac_size = c.as_int("ifac_size")//8
|
||||
|
||||
ifac_netname = None
|
||||
if "networkname" in c:
|
||||
if c["networkname"] != "":
|
||||
ifac_netname = c["networkname"]
|
||||
if c["networkname"] != "": ifac_netname = c["networkname"]
|
||||
if "network_name" in c:
|
||||
if c["network_name"] != "":
|
||||
ifac_netname = c["network_name"]
|
||||
if c["network_name"] != "": ifac_netname = c["network_name"]
|
||||
|
||||
ifac_netkey = None
|
||||
if "passphrase" in c:
|
||||
if c["passphrase"] != "":
|
||||
ifac_netkey = c["passphrase"]
|
||||
if c["passphrase"] != "": ifac_netkey = c["passphrase"]
|
||||
if "pass_phrase" in c:
|
||||
if c["pass_phrase"] != "":
|
||||
ifac_netkey = c["pass_phrase"]
|
||||
if c["pass_phrase"] != "": ifac_netkey = c["pass_phrase"]
|
||||
|
||||
ingress_control = True
|
||||
if "ingress_control" in c: ingress_control = c.as_bool("ingress_control")
|
||||
@@ -783,29 +780,22 @@ class Reticulum:
|
||||
|
||||
configured_bitrate = None
|
||||
if "bitrate" in c:
|
||||
if c.as_int("bitrate") >= Reticulum.MINIMUM_BITRATE:
|
||||
configured_bitrate = c.as_int("bitrate")
|
||||
if c.as_int("bitrate") >= Reticulum.MINIMUM_BITRATE: configured_bitrate = c.as_int("bitrate")
|
||||
|
||||
announce_rate_target = None
|
||||
if "announce_rate_target" in c:
|
||||
if c.as_int("announce_rate_target") > 0:
|
||||
announce_rate_target = c.as_int("announce_rate_target")
|
||||
if c.as_int("announce_rate_target") > 0: announce_rate_target = c.as_int("announce_rate_target")
|
||||
|
||||
announce_rate_grace = None
|
||||
if "announce_rate_grace" in c:
|
||||
if c.as_int("announce_rate_grace") >= 0:
|
||||
announce_rate_grace = c.as_int("announce_rate_grace")
|
||||
if c.as_int("announce_rate_grace") >= 0: announce_rate_grace = c.as_int("announce_rate_grace")
|
||||
|
||||
announce_rate_penalty = None
|
||||
if "announce_rate_penalty" in c:
|
||||
if c.as_int("announce_rate_penalty") >= 0:
|
||||
announce_rate_penalty = c.as_int("announce_rate_penalty")
|
||||
if c.as_int("announce_rate_penalty") >= 0: announce_rate_penalty = c.as_int("announce_rate_penalty")
|
||||
|
||||
if announce_rate_target != None and announce_rate_grace == None:
|
||||
announce_rate_grace = 0
|
||||
|
||||
if announce_rate_target != None and announce_rate_penalty == None:
|
||||
announce_rate_penalty = 0
|
||||
if announce_rate_target != None and announce_rate_grace == None: announce_rate_grace = 0
|
||||
if announce_rate_target != None and announce_rate_penalty == None: announce_rate_penalty = 0
|
||||
|
||||
announce_cap = Reticulum.ANNOUNCE_CAP/100.0
|
||||
if "announce_cap" in c:
|
||||
@@ -887,40 +877,41 @@ class Reticulum:
|
||||
if ifac_size != None: interface.ifac_size = ifac_size
|
||||
else: interface.ifac_size = interface.DEFAULT_IFAC_SIZE
|
||||
|
||||
interface.discoverable = discoverable
|
||||
interface.discovery_announce_interval = discovery_announce_interval
|
||||
interface.discovery_publish_ifac = publish_ifac
|
||||
interface.reachable_on = reachable_on
|
||||
interface.discovery_name = discovery_name
|
||||
interface.discovery_encrypt = discovery_encrypt
|
||||
interface.discovery_stamp_value = discovery_stamp_value
|
||||
interface.discovery_latitude = latitude
|
||||
interface.discovery_longitude = longitude
|
||||
interface.discovery_height = height
|
||||
interface.discovery_frequency = discovery_frequency
|
||||
interface.discovery_bandwidth = discovery_bandwidth
|
||||
interface.discovery_modulation = discovery_modulation
|
||||
interface.discoverable = discoverable
|
||||
interface.discovery_announce_interval = discovery_announce_interval
|
||||
interface.discovery_publish_ifac = publish_ifac
|
||||
interface.reachable_on = reachable_on
|
||||
interface.discovery_name = discovery_name
|
||||
interface.discovery_encrypt = discovery_encrypt
|
||||
interface.discovery_stamp_value = discovery_stamp_value
|
||||
interface.discovery_latitude = latitude
|
||||
interface.discovery_longitude = longitude
|
||||
interface.discovery_height = height
|
||||
interface.discovery_frequency = discovery_frequency
|
||||
interface.discovery_bandwidth = discovery_bandwidth
|
||||
interface.discovery_modulation = discovery_modulation
|
||||
|
||||
interface.recursive_prs = recursive_prs
|
||||
interface.announces_from_internal = announces_from_internal
|
||||
interface.announce_rate_target = announce_rate_target
|
||||
interface.announce_rate_grace = announce_rate_grace
|
||||
interface.announce_rate_penalty = announce_rate_penalty
|
||||
interface.ingress_control = ingress_control
|
||||
if egress_control != None: interface.egress_control = egress_control
|
||||
if ic_max_held_announces != None: interface.ic_max_held_announces = ic_max_held_announces
|
||||
if ic_burst_hold != None: interface.ic_burst_hold = ic_burst_hold
|
||||
if ic_burst_freq_new != None: interface.ic_burst_freq_new = ic_burst_freq_new
|
||||
if ic_burst_freq != None: interface.ic_burst_freq = ic_burst_freq
|
||||
if ic_pr_burst_freq_new != None: interface.ic_pr_burst_freq_new = ic_pr_burst_freq_new
|
||||
if ic_pr_burst_freq != None: interface.ic_pr_burst_freq = ic_pr_burst_freq
|
||||
if ec_pr_freq != None: interface.ec_pr_freq = ec_pr_freq
|
||||
if ic_new_time != None: interface.ic_new_time = ic_new_time
|
||||
if ic_burst_penalty != None: interface.ic_burst_penalty = ic_burst_penalty
|
||||
interface.recursive_prs = recursive_prs
|
||||
interface.announces_from_internal = announces_from_internal
|
||||
interface.announce_rate_target = announce_rate_target
|
||||
interface.announce_rate_grace = announce_rate_grace
|
||||
interface.announce_rate_penalty = announce_rate_penalty
|
||||
interface.ingress_control = ingress_control
|
||||
|
||||
if egress_control != None: interface.egress_control = egress_control
|
||||
if ic_max_held_announces != None: interface.ic_max_held_announces = ic_max_held_announces
|
||||
if ic_burst_hold != None: interface.ic_burst_hold = ic_burst_hold
|
||||
if ic_burst_freq_new != None: interface.ic_burst_freq_new = ic_burst_freq_new
|
||||
if ic_burst_freq != None: interface.ic_burst_freq = ic_burst_freq
|
||||
if ic_pr_burst_freq_new != None: interface.ic_pr_burst_freq_new = ic_pr_burst_freq_new
|
||||
if ic_pr_burst_freq != None: interface.ic_pr_burst_freq = ic_pr_burst_freq
|
||||
if ec_pr_freq != None: interface.ec_pr_freq = ec_pr_freq
|
||||
if ic_new_time != None: interface.ic_new_time = ic_new_time
|
||||
if ic_burst_penalty != None: interface.ic_burst_penalty = ic_burst_penalty
|
||||
if ic_held_release_interval != None: interface.ic_held_release_interval = ic_held_release_interval
|
||||
|
||||
interface.ifac_netname = ifac_netname
|
||||
interface.ifac_netkey = ifac_netkey
|
||||
interface.ifac_netkey = ifac_netkey
|
||||
|
||||
if interface.ifac_netname != None or interface.ifac_netkey != None:
|
||||
ifac_origin = b""
|
||||
@@ -932,12 +923,8 @@ class Reticulum:
|
||||
ifac_origin += RNS.Identity.full_hash(interface.ifac_netkey.encode("utf-8"))
|
||||
|
||||
ifac_origin_hash = RNS.Identity.full_hash(ifac_origin)
|
||||
interface.ifac_key = RNS.Cryptography.hkdf(
|
||||
length=64,
|
||||
derive_from=ifac_origin_hash,
|
||||
salt=self.ifac_salt,
|
||||
context=None
|
||||
)
|
||||
interface.ifac_key = RNS.Cryptography.hkdf(length=64, derive_from=ifac_origin_hash,
|
||||
salt=self.ifac_salt, context=None)
|
||||
|
||||
interface.ifac_identity = RNS.Identity.from_bytes(interface.ifac_key)
|
||||
interface.ifac_signature = interface.ifac_identity.sign(RNS.Identity.full_hash(interface.ifac_key))
|
||||
@@ -1063,6 +1050,7 @@ class Reticulum:
|
||||
def _add_interface(self, interface, mode = None, configured_bitrate=None, ifac_size=None, ifac_netname=None, ifac_netkey=None,
|
||||
announce_cap=None, announce_rate_target=None, announce_rate_grace=None, announce_rate_penalty=None,
|
||||
bootstrap_only=False, recursive_prs=False, announces_from_internal=True):
|
||||
|
||||
if not self.is_connected_to_shared_instance:
|
||||
if interface != None and issubclass(type(interface), RNS.Interfaces.Interface.Interface):
|
||||
|
||||
@@ -1077,15 +1065,15 @@ class Reticulum:
|
||||
if ifac_size != None: interface.ifac_size = ifac_size
|
||||
else: interface.ifac_size = interface.DEFAULT_IFAC_SIZE
|
||||
|
||||
interface.recursive_prs = recursive_prs
|
||||
interface.recursive_prs = recursive_prs
|
||||
interface.announces_from_internal = announces_from_internal
|
||||
interface.announce_cap = announce_cap if announce_cap != None else Reticulum.ANNOUNCE_CAP/100.0
|
||||
interface.announce_rate_target = announce_rate_target
|
||||
interface.announce_rate_grace = announce_rate_grace
|
||||
interface.announce_rate_penalty = announce_rate_penalty
|
||||
interface.announce_cap = announce_cap if announce_cap != None else Reticulum.ANNOUNCE_CAP/100.0
|
||||
interface.announce_rate_target = announce_rate_target
|
||||
interface.announce_rate_grace = announce_rate_grace
|
||||
interface.announce_rate_penalty = announce_rate_penalty
|
||||
|
||||
interface.ifac_netname = ifac_netname
|
||||
interface.ifac_netkey = ifac_netkey
|
||||
interface.ifac_netkey = ifac_netkey
|
||||
|
||||
if interface.ifac_netname != None or interface.ifac_netkey != None:
|
||||
ifac_origin = b""
|
||||
@@ -1097,12 +1085,8 @@ class Reticulum:
|
||||
ifac_origin += RNS.Identity.full_hash(interface.ifac_netkey.encode("utf-8"))
|
||||
|
||||
ifac_origin_hash = RNS.Identity.full_hash(ifac_origin)
|
||||
interface.ifac_key = RNS.Cryptography.hkdf(
|
||||
length=64,
|
||||
derive_from=ifac_origin_hash,
|
||||
salt=self.ifac_salt,
|
||||
context=None
|
||||
)
|
||||
interface.ifac_key = RNS.Cryptography.hkdf(length=64, derive_from=ifac_origin_hash,
|
||||
salt=self.ifac_salt, context=None)
|
||||
|
||||
interface.ifac_identity = RNS.Identity.from_bytes(interface.ifac_key)
|
||||
interface.ifac_signature = interface.ifac_identity.sign(RNS.Identity.full_hash(interface.ifac_key))
|
||||
@@ -1199,8 +1183,7 @@ class Reticulum:
|
||||
self.config = ConfigObj(__default_rns_config__)
|
||||
self.config.filename = Reticulum.configpath
|
||||
|
||||
if not os.path.isdir(Reticulum.configdir):
|
||||
os.makedirs(Reticulum.configdir)
|
||||
if not os.path.isdir(Reticulum.configdir): os.makedirs(Reticulum.configdir)
|
||||
self.config.write()
|
||||
|
||||
def rpc_return(self, connection, response):
|
||||
@@ -1331,31 +1314,26 @@ class Reticulum:
|
||||
rpc_connection.send_bytes(mp.packb({"get": "interface_stats"}))
|
||||
response = mp.unpackb(rpc_connection.recv_bytes())
|
||||
return response
|
||||
|
||||
else:
|
||||
interfaces = []
|
||||
for interface in RNS.Transport.interfaces:
|
||||
ifstats = {}
|
||||
|
||||
if hasattr(interface, "clients"):
|
||||
ifstats["clients"] = interface.clients
|
||||
else:
|
||||
ifstats["clients"] = None
|
||||
if hasattr(interface, "clients"): ifstats["clients"] = interface.clients
|
||||
else: ifstats["clients"] = None
|
||||
|
||||
if hasattr(interface, "parent_interface") and interface.parent_interface != None:
|
||||
ifstats["parent_interface_name"] = str(interface.parent_interface)
|
||||
ifstats["parent_interface_hash"] = interface.parent_interface.get_hash()
|
||||
|
||||
if hasattr(interface, "i2p") and hasattr(interface, "connectable"):
|
||||
if interface.connectable:
|
||||
ifstats["i2p_connectable"] = True
|
||||
else:
|
||||
ifstats["i2p_connectable"] = False
|
||||
if interface.connectable: ifstats["i2p_connectable"] = True
|
||||
else: ifstats["i2p_connectable"] = False
|
||||
|
||||
if hasattr(interface, "b32"):
|
||||
if interface.b32 != None:
|
||||
ifstats["i2p_b32"] = interface.b32+".b32.i2p"
|
||||
else:
|
||||
ifstats["i2p_b32"] = None
|
||||
if interface.b32 != None: ifstats["i2p_b32"] = interface.b32+".b32.i2p"
|
||||
else: ifstats["i2p_b32"] = None
|
||||
|
||||
if hasattr(interface, "i2p_tunnel_state"):
|
||||
if interface.i2p_tunnel_state != None:
|
||||
@@ -1370,37 +1348,20 @@ class Reticulum:
|
||||
else:
|
||||
ifstats["tunnelstate"] = None
|
||||
|
||||
if hasattr(interface, "r_airtime_short"):
|
||||
ifstats["airtime_short"] = interface.r_airtime_short
|
||||
|
||||
if hasattr(interface, "r_airtime_long"):
|
||||
ifstats["airtime_long"] = interface.r_airtime_long
|
||||
|
||||
if hasattr(interface, "r_channel_load_short"):
|
||||
ifstats["channel_load_short"] = interface.r_channel_load_short
|
||||
|
||||
if hasattr(interface, "r_channel_load_long"):
|
||||
ifstats["channel_load_long"] = interface.r_channel_load_long
|
||||
|
||||
if hasattr(interface, "r_noise_floor"):
|
||||
ifstats["noise_floor"] = interface.r_noise_floor
|
||||
|
||||
if hasattr(interface, "r_interference"):
|
||||
ifstats["interference"] = interface.r_interference
|
||||
if hasattr(interface, "r_airtime_short"): ifstats["airtime_short"] = interface.r_airtime_short
|
||||
if hasattr(interface, "r_airtime_long"): ifstats["airtime_long"] = interface.r_airtime_long
|
||||
if hasattr(interface, "r_channel_load_short"): ifstats["channel_load_short"] = interface.r_channel_load_short
|
||||
if hasattr(interface, "r_channel_load_long"): ifstats["channel_load_long"] = interface.r_channel_load_long
|
||||
if hasattr(interface, "r_noise_floor"): ifstats["noise_floor"] = interface.r_noise_floor
|
||||
if hasattr(interface, "r_interference"): ifstats["interference"] = interface.r_interference
|
||||
if hasattr(interface, "cpu_temp"): ifstats["cpu_temp"] = interface.cpu_temp
|
||||
if hasattr(interface, "cpu_load"): ifstats["cpu_load"] = interface.cpu_load
|
||||
if hasattr(interface, "mem_load"): ifstats["mem_load"] = interface.mem_load
|
||||
|
||||
if hasattr(interface, "r_interference_l") and type(interface.r_interference_l) == list:
|
||||
ifstats["interference_last_ts"] = interface.r_interference_l[0]
|
||||
ifstats["interference_last_dbm"] = interface.r_interference_l[1]
|
||||
|
||||
if hasattr(interface, "cpu_temp"):
|
||||
ifstats["cpu_temp"] = interface.cpu_temp
|
||||
|
||||
if hasattr(interface, "cpu_load"):
|
||||
ifstats["cpu_load"] = interface.cpu_load
|
||||
|
||||
if hasattr(interface, "mem_load"):
|
||||
ifstats["mem_load"] = interface.mem_load
|
||||
|
||||
if hasattr(interface, "switch_id"):
|
||||
if interface.switch_id != None: ifstats["switch_id"] = RNS.hexrep(interface.switch_id)
|
||||
else: ifstats["switch_id"] = None
|
||||
@@ -1414,39 +1375,26 @@ class Reticulum:
|
||||
else: ifstats["endpoint_id"] = None
|
||||
|
||||
if hasattr(interface, "r_battery_state"):
|
||||
if interface.r_battery_state != 0x00:
|
||||
ifstats["battery_state"] = interface.get_battery_state_string()
|
||||
|
||||
if hasattr(interface, "r_battery_percent"):
|
||||
ifstats["battery_percent"] = interface.r_battery_percent
|
||||
if interface.r_battery_state != 0x00: ifstats["battery_state"] = interface.get_battery_state_string()
|
||||
if hasattr(interface, "r_battery_percent"): ifstats["battery_percent"] = interface.r_battery_percent
|
||||
|
||||
if hasattr(interface, "bitrate"):
|
||||
if interface.bitrate != None:
|
||||
ifstats["bitrate"] = interface.bitrate
|
||||
else:
|
||||
ifstats["bitrate"] = None
|
||||
if interface.bitrate != None: ifstats["bitrate"] = interface.bitrate
|
||||
else: ifstats["bitrate"] = None
|
||||
|
||||
if hasattr(interface, "current_rx_speed"):
|
||||
if interface.current_rx_speed != None:
|
||||
ifstats["rxs"] = interface.current_rx_speed
|
||||
else:
|
||||
ifstats["rxs"] = 0
|
||||
else:
|
||||
ifstats["rxs"] = 0
|
||||
if interface.current_rx_speed != None: ifstats["rxs"] = interface.current_rx_speed
|
||||
else: ifstats["rxs"] = 0
|
||||
else: ifstats["rxs"] = 0
|
||||
|
||||
if hasattr(interface, "current_tx_speed"):
|
||||
if interface.current_tx_speed != None:
|
||||
ifstats["txs"] = interface.current_tx_speed
|
||||
else:
|
||||
ifstats["txs"] = 0
|
||||
else:
|
||||
ifstats["txs"] = 0
|
||||
if interface.current_tx_speed != None: ifstats["txs"] = interface.current_tx_speed
|
||||
else: ifstats["txs"] = 0
|
||||
else: ifstats["txs"] = 0
|
||||
|
||||
if hasattr(interface, "peers"):
|
||||
if interface.peers != None:
|
||||
ifstats["peers"] = len(interface.peers)
|
||||
else:
|
||||
ifstats["peers"] = None
|
||||
if interface.peers != None: ifstats["peers"] = len(interface.peers)
|
||||
else: ifstats["peers"] = None
|
||||
|
||||
if hasattr(interface, "ifac_signature"):
|
||||
ifstats["ifac_signature"] = interface.ifac_signature
|
||||
@@ -1454,57 +1402,52 @@ class Reticulum:
|
||||
ifstats["ifac_netname"] = interface.ifac_netname
|
||||
else:
|
||||
ifstats["ifac_signature"] = None
|
||||
ifstats["ifac_size"] = None
|
||||
ifstats["ifac_netname"] = None
|
||||
ifstats["ifac_size"] = None
|
||||
ifstats["ifac_netname"] = None
|
||||
|
||||
if hasattr(interface, "autoconnect_source"):
|
||||
ifstats["autoconnect_source"] = interface.autoconnect_source
|
||||
else:
|
||||
ifstats["autoconnect_source"] = None
|
||||
if hasattr(interface, "autoconnect_source"): ifstats["autoconnect_source"] = interface.autoconnect_source
|
||||
else: ifstats["autoconnect_source"] = None
|
||||
|
||||
if hasattr(interface, "announce_queue"):
|
||||
if interface.announce_queue != None:
|
||||
ifstats["announce_queue"] = len(interface.announce_queue)
|
||||
else:
|
||||
ifstats["announce_queue"] = None
|
||||
if interface.announce_queue != None: ifstats["announce_queue"] = len(interface.announce_queue)
|
||||
else: ifstats["announce_queue"] = None
|
||||
|
||||
ifstats["name"] = str(interface)
|
||||
ifstats["short_name"] = str(interface.name)
|
||||
ifstats["hash"] = interface.get_hash()
|
||||
ifstats["type"] = str(type(interface).__name__)
|
||||
ifstats["rxb"] = interface.rxb
|
||||
ifstats["txb"] = interface.txb
|
||||
ifstats["name"] = str(interface)
|
||||
ifstats["short_name"] = str(interface.name)
|
||||
ifstats["hash"] = interface.get_hash()
|
||||
ifstats["type"] = str(type(interface).__name__)
|
||||
ifstats["rxb"] = interface.rxb
|
||||
ifstats["txb"] = interface.txb
|
||||
ifstats["incoming_announce_frequency"] = interface.incoming_announce_frequency()
|
||||
ifstats["outgoing_announce_frequency"] = interface.outgoing_announce_frequency()
|
||||
ifstats["incoming_pr_frequency"] = interface.incoming_pr_frequency()
|
||||
ifstats["outgoing_pr_frequency"] = interface.outgoing_pr_frequency()
|
||||
ifstats["announce_rate_target"] = interface.announce_rate_target
|
||||
ifstats["announce_rate_penalty"] = interface.announce_rate_penalty
|
||||
ifstats["announce_rate_grace"] = interface.announce_rate_grace
|
||||
ifstats["held_announces"] = len(interface.held_announces)
|
||||
ifstats["burst_active"] = interface.ic_burst_active
|
||||
ifstats["burst_activated"] = interface.ic_burst_activated
|
||||
ifstats["pr_burst_active"] = interface.ic_pr_burst_active
|
||||
ifstats["pr_burst_activated"] = interface.ic_pr_burst_activated
|
||||
ifstats["status"] = interface.online
|
||||
ifstats["mode"] = interface.mode
|
||||
ifstats["incoming_pr_frequency"] = interface.incoming_pr_frequency()
|
||||
ifstats["outgoing_pr_frequency"] = interface.outgoing_pr_frequency()
|
||||
ifstats["announce_rate_target"] = interface.announce_rate_target
|
||||
ifstats["announce_rate_penalty"] = interface.announce_rate_penalty
|
||||
ifstats["announce_rate_grace"] = interface.announce_rate_grace
|
||||
ifstats["held_announces"] = len(interface.held_announces)
|
||||
ifstats["burst_active"] = interface.ic_burst_active
|
||||
ifstats["burst_activated"] = interface.ic_burst_activated
|
||||
ifstats["pr_burst_active"] = interface.ic_pr_burst_active
|
||||
ifstats["pr_burst_activated"] = interface.ic_pr_burst_activated
|
||||
ifstats["status"] = interface.online
|
||||
ifstats["mode"] = interface.mode
|
||||
|
||||
interfaces.append(ifstats)
|
||||
|
||||
stats = {}
|
||||
stats = {}
|
||||
stats["interfaces"] = interfaces
|
||||
stats["rxb"] = RNS.Transport.traffic_rxb
|
||||
stats["txb"] = RNS.Transport.traffic_txb
|
||||
stats["rxs"] = RNS.Transport.speed_rx
|
||||
stats["txs"] = RNS.Transport.speed_tx
|
||||
stats["rxb"] = RNS.Transport.traffic_rxb
|
||||
stats["txb"] = RNS.Transport.traffic_txb
|
||||
stats["rxs"] = RNS.Transport.speed_rx
|
||||
stats["txs"] = RNS.Transport.speed_tx
|
||||
|
||||
if Reticulum.transport_enabled():
|
||||
stats["transport_id"] = RNS.Transport.identity.hash
|
||||
stats["network_id"] = RNS.Transport.network_identity.hash if RNS.Transport.network_identity else None
|
||||
stats["transport_uptime"] = time.time()-RNS.Transport.start_time
|
||||
if Reticulum.probe_destination_enabled():
|
||||
stats["probe_responder"] = RNS.Transport.probe_destination.hash
|
||||
else:
|
||||
stats["probe_responder"] = None
|
||||
if Reticulum.probe_destination_enabled(): stats["probe_responder"] = RNS.Transport.probe_destination.hash
|
||||
else: stats["probe_responder"] = None
|
||||
|
||||
if importlib.util.find_spec('psutil') != None:
|
||||
import psutil
|
||||
@@ -1527,14 +1470,10 @@ class Reticulum:
|
||||
for dst_hash in RNS.Transport.path_table:
|
||||
path_hops = RNS.Transport.path_table[dst_hash][2]
|
||||
if max_hops == None or path_hops <= max_hops:
|
||||
entry = {
|
||||
"hash": dst_hash,
|
||||
"timestamp": RNS.Transport.path_table[dst_hash][0],
|
||||
"via": RNS.Transport.path_table[dst_hash][1],
|
||||
"hops": path_hops,
|
||||
"expires": RNS.Transport.path_table[dst_hash][3],
|
||||
"interface": str(RNS.Transport.path_table[dst_hash][5]),
|
||||
}
|
||||
entry = { "hash": dst_hash, "timestamp": RNS.Transport.path_table[dst_hash][0],
|
||||
"via": RNS.Transport.path_table[dst_hash][1], "hops": path_hops,
|
||||
"expires": RNS.Transport.path_table[dst_hash][3],
|
||||
"interface": str(RNS.Transport.path_table[dst_hash][5]) }
|
||||
path_table.append(entry)
|
||||
|
||||
return path_table
|
||||
@@ -1862,6 +1801,10 @@ class Reticulum:
|
||||
def static_transport_identity():
|
||||
return Reticulum.__static_transport_identity
|
||||
|
||||
@staticmethod
|
||||
def local_hops_delta():
|
||||
return Reticulum.__local_hops_delta
|
||||
|
||||
# Default configuration file:
|
||||
__default_rns_config__ = '''# This is the default Reticulum config file.
|
||||
# You should probably edit it to include any additional,
|
||||
|
||||
+62
-18
@@ -166,6 +166,7 @@ class Transport:
|
||||
local_client_rssi_cache = []
|
||||
local_client_snr_cache = []
|
||||
local_client_q_cache = []
|
||||
local_hops_delta = 0
|
||||
LOCAL_CLIENT_CACHE_MAXSIZE = 512
|
||||
|
||||
pending_local_path_requests = {}
|
||||
@@ -236,6 +237,8 @@ class Transport:
|
||||
Transport.identity = RNS.Identity()
|
||||
RNS.log(f"Initialized ephemeral transport identity {RNS.prettyhexrep(Transport.identity.hash)}", RNS.LOG_VERBOSE) if RNS.sl(RNS.LOG_VERBOSE) else None
|
||||
|
||||
if RNS.Reticulum.local_hops_delta(): Transport.local_hops_delta = (ord(os.urandom(1))%6)+2
|
||||
|
||||
packet_hashlist_path = RNS.Reticulum.storagepath+"/packet_hashlist"
|
||||
if not Transport.owner.is_connected_to_shared_instance:
|
||||
if os.path.isfile(packet_hashlist_path):
|
||||
@@ -1147,7 +1150,7 @@ class Transport:
|
||||
# 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 += packet.raw[1:2] if not Transport.should_apply_delta(packet, outbound_interface) else struct.pack("!B", Transport.local_hops_delta)
|
||||
new_raw += path_entry[IDX_PT_NEXT_HOP]
|
||||
new_raw += packet.raw[2:]
|
||||
packet_sent(packet)
|
||||
@@ -1167,7 +1170,7 @@ class Transport:
|
||||
# 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 += packet.raw[1:2] if not Transport.should_apply_delta(packet, outbound_interface) else struct.pack("!B", Transport.local_hops_delta)
|
||||
new_raw += path_entry[IDX_PT_NEXT_HOP]
|
||||
new_raw += packet.raw[2:]
|
||||
packet_sent(packet)
|
||||
@@ -1180,7 +1183,9 @@ class Transport:
|
||||
# simply transmit the packet directly on that one.
|
||||
else:
|
||||
packet_sent(packet)
|
||||
Transport.transmit(outbound_interface, packet.raw)
|
||||
if not Transport.should_apply_delta(packet, outbound_interface): raw = packet.raw
|
||||
else: raw = Transport.mangle_hops(packet.raw, Transport.local_hops_delta)
|
||||
Transport.transmit(outbound_interface, raw)
|
||||
sent = True
|
||||
|
||||
# If we don't have a known path for the destination, we'll
|
||||
@@ -1194,11 +1199,10 @@ class Transport:
|
||||
should_transmit = True
|
||||
|
||||
if packet.destination.type == RNS.Destination.LINK:
|
||||
if packet.destination.status == RNS.Link.CLOSED: should_transmit = False
|
||||
if interface != packet.destination.attached_interface: should_transmit = False
|
||||
if packet.destination.status == RNS.Link.CLOSED: continue
|
||||
if interface != packet.destination.attached_interface: continue
|
||||
|
||||
if packet.attached_interface != None and interface != packet.attached_interface:
|
||||
should_transmit = False
|
||||
if packet.attached_interface != None and interface != packet.attached_interface: continue
|
||||
|
||||
if packet.packet_type == RNS.Packet.ANNOUNCE:
|
||||
if packet.attached_interface == None:
|
||||
@@ -1335,7 +1339,12 @@ class Transport:
|
||||
Transport.add_packet_hash(packet.packet_hash)
|
||||
stored_hash = True
|
||||
|
||||
Transport.transmit(interface, packet.raw)
|
||||
if not Transport.should_apply_delta(packet, interface): raw = packet.raw
|
||||
else:
|
||||
if packet.packet_type != RNS.Packet.ANNOUNCE: raw = Transport.mangle_hops(packet.raw, Transport.local_hops_delta)
|
||||
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()
|
||||
packet_sent(packet)
|
||||
@@ -1343,6 +1352,17 @@ class Transport:
|
||||
|
||||
return sent
|
||||
|
||||
@staticmethod
|
||||
def should_apply_delta(packet, interface):
|
||||
return not Transport.owner.is_connected_to_shared_instance and packet.hops == 0 and Transport.local_hops_delta != 0 \
|
||||
and not packet.destination.type == RNS.Destination.PLAIN and not packet.destination.type == RNS.Destination.GROUP \
|
||||
and not interface in Transport.local_client_interfaces and not Transport.is_shared_instance(interface)
|
||||
|
||||
@staticmethod
|
||||
def mangle_hops(raw, hops, transport_insert=False):
|
||||
if not transport_insert: return raw[0:1]+struct.pack("!B", hops)+raw[2:]
|
||||
else: return struct.pack("!B", ord(raw[0:1]) | (RNS.Packet.HEADER_2<<6) | (Transport.TRANSPORT<<4))+struct.pack("!B", hops)+Transport.identity.hash+raw[2:]
|
||||
|
||||
@staticmethod
|
||||
def add_packet_hash(packet_hash):
|
||||
if not Transport.owner.is_connected_to_shared_instance:
|
||||
@@ -1530,6 +1550,8 @@ class Transport:
|
||||
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)
|
||||
to_local_client = for_local_client or for_local_client_link or proof_for_local_client
|
||||
link_request_handled = False
|
||||
|
||||
# Plain broadcast packets from local clients are sent
|
||||
# directly on all attached interfaces, since they are
|
||||
@@ -1591,10 +1613,23 @@ class Transport:
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
|
||||
elif remaining_hops == 0:
|
||||
# Just increase hop count and transmit
|
||||
new_raw = packet.raw[0:1]
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[2:]
|
||||
if to_local_client and RNS.Transport.local_hops_delta != 0:
|
||||
if packet.header_type == RNS.Packet.HEADER_2:
|
||||
# Strip transport headers and transmit
|
||||
new_flags = (RNS.Packet.HEADER_1) << 6 | (Transport.BROADCAST) << 4 | (packet.flags & 0b00001111)
|
||||
new_raw = struct.pack("!B", new_flags)
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
|
||||
else:
|
||||
# Just increase hop count and transmit
|
||||
new_raw = packet.raw[0:1]
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[2:]
|
||||
else:
|
||||
# Just increase hop count and transmit
|
||||
new_raw = packet.raw[0:1]
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += packet.raw[2:]
|
||||
|
||||
outbound_interface = Transport.path_table[packet.destination_hash][IDX_PT_RVCD_IF]
|
||||
|
||||
@@ -1639,6 +1674,7 @@ class Transport:
|
||||
proof_timeout ] # 8: Proof timeout timestamp
|
||||
|
||||
with Transport.link_table_lock: Transport.link_table[RNS.Link.link_id_from_lr_packet(packet)] = link_entry
|
||||
link_request_handled = True
|
||||
|
||||
else:
|
||||
# Entry format is
|
||||
@@ -1648,6 +1684,7 @@ class Transport:
|
||||
|
||||
with Transport.reverse_table_lock: Transport.reverse_table[packet.getTruncatedHash()] = 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()
|
||||
|
||||
@@ -1691,7 +1728,7 @@ class Transport:
|
||||
Transport.add_packet_hash(packet.packet_hash)
|
||||
|
||||
new_raw = packet.raw[0:1]
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += struct.pack("!B", packet.hops if not from_local_client or Transport.local_hops_delta == 0 else Transport.local_hops_delta)
|
||||
new_raw += packet.raw[2:]
|
||||
Transport.transmit(outbound_interface, new_raw)
|
||||
Transport.link_table[packet.destination_hash][IDX_LT_TIMESTAMP] = time.time()
|
||||
@@ -2104,7 +2141,7 @@ class Transport:
|
||||
RNS.trace_exception(e)
|
||||
|
||||
# Handling for link requests to local destinations
|
||||
elif packet.packet_type == RNS.Packet.LINKREQUEST:
|
||||
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:
|
||||
@@ -2207,7 +2244,7 @@ class Transport:
|
||||
if peer_identity.validate(signature, signed_data):
|
||||
RNS.log("Link request proof validated for transport via "+str(link_entry[IDX_LT_RCVD_IF]), RNS.LOG_EXTREME) if RNS.sl(RNS.LOG_EXTREME) else None
|
||||
new_raw = packet.raw[0:1]
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += struct.pack("!B", packet.hops if not from_local_client or Transport.local_hops_delta == 0 else Transport.local_hops_delta)
|
||||
new_raw += packet.raw[2:]
|
||||
Transport.link_table[packet.destination_hash][IDX_LT_VALIDATED] = True
|
||||
Transport.transmit(link_entry[IDX_LT_RCVD_IF], new_raw)
|
||||
@@ -2274,7 +2311,7 @@ class Transport:
|
||||
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) if RNS.sl(RNS.LOG_EXTREME) else None
|
||||
new_raw = packet.raw[0:1]
|
||||
new_raw += struct.pack("!B", packet.hops)
|
||||
new_raw += struct.pack("!B", packet.hops if not from_local_client or Transport.local_hops_delta == 0 else Transport.local_hops_delta)
|
||||
new_raw += packet.raw[2:]
|
||||
Transport.transmit(reverse_entry[IDX_RT_RCVD_IF], new_raw)
|
||||
else:
|
||||
@@ -2672,7 +2709,8 @@ class Transport:
|
||||
:returns: The destination hash as *bytes* for the next hop to the specified destination, or *None* if the next hop is unknown.
|
||||
"""
|
||||
with Transport.path_table_lock:
|
||||
if destination_hash in Transport.path_table: return Transport.path_table[destination_hash][IDX_PT_NEXT_HOP]
|
||||
if destination_hash in Transport.path_table: return Transport.path_table[destination_hash][IDX_PT_NEXT_HOP]
|
||||
elif destination_hash in Transport.destinations_map: return Transport.identity.hash
|
||||
else: return None
|
||||
|
||||
@staticmethod
|
||||
@@ -2682,7 +2720,8 @@ class Transport:
|
||||
:returns: The interface for the next hop to the specified destination, or *None* if the interface is unknown.
|
||||
"""
|
||||
with Transport.path_table_lock:
|
||||
if destination_hash in Transport.path_table: return Transport.path_table[destination_hash][IDX_PT_RVCD_IF]
|
||||
if destination_hash in Transport.path_table: return Transport.path_table[destination_hash][IDX_PT_RVCD_IF]
|
||||
elif destination_hash in Transport.destinations_map: return RNS.Reticulum.get_instance().shared_instance_interface
|
||||
else: return None
|
||||
|
||||
@staticmethod
|
||||
@@ -3080,6 +3119,11 @@ class Transport:
|
||||
else: return False
|
||||
else: return False
|
||||
|
||||
@staticmethod
|
||||
def is_shared_instance(interface):
|
||||
if hasattr(interface, "is_local_shared_instance"): return True
|
||||
else: return False
|
||||
|
||||
@staticmethod
|
||||
def interface_to_shared_instance(interface):
|
||||
if hasattr(interface, "is_connected_to_shared_instance"): return True
|
||||
|
||||
Reference in New Issue
Block a user