From 6521f839cdf9a10e4a21d98cb5963dcf0ad584b8 Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Thu, 10 Oct 2024 17:06:43 +0200 Subject: [PATCH] Fixed resource transfers hanging for a long time over slow links if proof packet is lost --- RNS/Resource.py | 7 +++++++ RNS/Transport.py | 11 ++++++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/RNS/Resource.py b/RNS/Resource.py index eb95114..d61dbf2 100644 --- a/RNS/Resource.py +++ b/RNS/Resource.py @@ -118,6 +118,7 @@ class Resource: PART_TIMEOUT_FACTOR = 4 PART_TIMEOUT_FACTOR_AFTER_RTT = 2 + PROOF_TIMEOUT_FACTOR = 3 MAX_RETRIES = 16 MAX_ADV_RETRIES = 4 SENDER_GRACE_TIME = 10.0 @@ -532,6 +533,10 @@ class Resource: sleep_time = 0.001 elif self.status == Resource.AWAITING_PROOF: + # Decrease timeout factor since proof packets are + # significantly smaller than full req/resp roundtrip + self.timeout_factor = Resource.PROOF_TIMEOUT_FACTOR + sleep_time = self.last_part_sent + (self.rtt*self.timeout_factor+self.sender_grace_time) - time.time() if sleep_time < 0: if self.retries_left <= 0: @@ -623,6 +628,7 @@ class Resource: proof_data = self.hash+proof proof_packet = RNS.Packet(self.link, proof_data, packet_type=RNS.Packet.PROOF, context=RNS.Packet.RESOURCE_PRF) proof_packet.send() + RNS.Transport.cache(proof_packet, force_cache=True) except Exception as e: RNS.log("Could not send proof packet, cancelling resource", RNS.LOG_DEBUG) RNS.log("The contained exception was: "+str(e), RNS.LOG_DEBUG) @@ -919,6 +925,7 @@ class Resource: if self.sent_parts == len(self.parts): self.status = Resource.AWAITING_PROOF + self.retries_left = 3 if self.__progress_callback != None: try: diff --git a/RNS/Transport.py b/RNS/Transport.py index 51c7b36..2338383 100755 --- a/RNS/Transport.py +++ b/RNS/Transport.py @@ -1738,7 +1738,16 @@ class Transport: if link.link_id == packet.destination_hash: if link.attached_interface == packet.receiving_interface: packet.link = link - link.receive(packet) + if packet.context == RNS.Packet.CACHE_REQUEST: + cached_packet = Transport.get_cached_packet(packet.data) + if cached_packet != None: + cached_packet.unpack() + RNS.Packet(destination=link, data=cached_packet.data, + packet_type=cached_packet.packet_type, context=cached_packet.context).send() + + Transport.jobs_locked = False + else: + link.receive(packet) else: # In the strange and rare case that an interface # is partly malfunctioning, and a link-associated