Fixed race condition for link initiators on timed out link establishment

This commit is contained in:
Mark Qvist 2023-06-13 16:10:47 +02:00
parent 97f97eb063
commit bab779a34c
3 changed files with 49 additions and 38 deletions

View File

@ -264,6 +264,7 @@ class Link:
self.had_outbound()
def validate_proof(self, packet):
try:
if self.status == Link.PENDING:
if self.initiator and len(packet.data) == RNS.Identity.SIGLENGTH//8+Link.ECPUBSIZE//2:
peer_pub_bytes = packet.data[RNS.Identity.SIGLENGTH//8:RNS.Identity.SIGLENGTH//8+Link.ECPUBSIZE//2]
@ -276,6 +277,9 @@ class Link:
signature = packet.data[:RNS.Identity.SIGLENGTH//8]
if self.destination.identity.validate(signature, signed_data):
if self.status != Link.PENDING:
raise IOError("Invalid link state for proof validation")
self.rtt = time.time() - self.request_time
self.attached_interface = packet.receiving_interface
self.__remote_identity = self.destination.identity
@ -300,6 +304,11 @@ class Link:
else:
RNS.log("Invalid link proof signature received by "+str(self)+". Ignoring.", RNS.LOG_DEBUG)
except Exception as e:
self.status = Link.CLOSED
RNS.log("An error ocurred while validating link request proof on "+str(self)+".", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
def identify(self, identity):
"""
@ -520,16 +529,16 @@ class Link:
next_check = self.request_time + self.establishment_timeout
sleep_time = next_check - time.time()
if time.time() >= self.request_time + self.establishment_timeout:
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)
self.status = Link.CLOSED
self.teardown_reason = Link.TIMEOUT
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)
elif self.status == Link.ACTIVE:
activated_at = self.activated_at if self.activated_at != None else 0
last_inbound = max(max(self.last_inbound, self.last_proof), activated_at)
@ -847,7 +856,7 @@ class Link:
try:
self.fernet = Fernet(self.derived_key)
except Exception as e:
RNS.log("Could not "+str(self)+" instantiate Fernet while performin encryption on link. The contained exception was: "+str(e), RNS.LOG_ERROR)
RNS.log("Could not instantiate Fernet while performin encryption on link "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
raise e
return self.fernet.encrypt(plaintext)

View File

@ -1741,6 +1741,8 @@ class Transport:
def activate_link(link):
RNS.log("Activating link "+str(link), RNS.LOG_EXTREME)
if link in Transport.pending_links:
if link.status != Link.PENDING:
raise IOError("Invalid link state for link activation")
Transport.pending_links.remove(link)
Transport.active_links.append(link)
link.status = RNS.Link.ACTIVE

View File

@ -1 +1 @@
__version__ = "0.5.4"
__version__ = "0.5.5"