From bf49eb247568db5b7d181fb076a87a958dc2ff1b Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Tue, 12 May 2020 08:50:51 +0200 Subject: [PATCH] TCP performance improvements --- README.md | 2 +- RNS/Interfaces/TCPInterface.py | 48 +++++++++++++++++----------------- RNS/Resource.py | 28 +++++++++++++------- 3 files changed, 43 insertions(+), 35 deletions(-) diff --git a/README.md b/README.md index fe12ead..37148cf 100755 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Some countries still ban the use of encryption when operating under an amateur r - pyserial ## How do I get started? -Full documentation and video tutorials are coming with the stable alpha release. Until then, you are mostly on your own. If you really want to experiment already, you could take a look in the "Examples" folder, for some well-documented example programs. Be sure to also read the [Reticulum Overview Document](http://unsigned.io/wp-content/uploads/2018/04/Reticulum_Overview_v0.4.pdf). +Full documentation and video tutorials are coming with the stable alpha release. Until then, you are mostly on your own. If you really want to experiment already, you could take a look in the "Examples" folder, for some well-documented example programs. The default configuration file created by Reticulum on the first run is also worth reading. Be sure to also read the [Reticulum Overview Document](http://unsigned.io/wp-content/uploads/2018/04/Reticulum_Overview_v0.4.pdf). If you just need Reticulum as a dependency for another application, the easiest way is probably via pip: diff --git a/RNS/Interfaces/TCPInterface.py b/RNS/Interfaces/TCPInterface.py index 5c99034..875d1dc 100644 --- a/RNS/Interfaces/TCPInterface.py +++ b/RNS/Interfaces/TCPInterface.py @@ -78,27 +78,30 @@ class TCPClientInterface(Interface): data_buffer = b"" while True: - data_in = self.socket.recv(1) + data_in = self.socket.recv(1024) if len(data_in) > 0: - byte = ord(data_in) - if (in_frame and byte == HDLC.FLAG): - in_frame = False - self.processIncoming(data_buffer) - elif (byte == HDLC.FLAG): - in_frame = True - data_buffer = b"" - elif (in_frame and len(data_buffer) < RNS.Reticulum.MTU): - if (byte == HDLC.ESC): - escape = True - else: - if (escape): - if (byte == HDLC.FLAG ^ HDLC.ESC_MASK): - byte = HDLC.FLAG - if (byte == HDLC.ESC ^ HDLC.ESC_MASK): - byte = HDLC.ESC - escape = False - data_buffer = data_buffer+bytes([byte]) + pointer = 0 + while pointer < len(data_in): + byte = data_in[pointer] + pointer += 1 + if (in_frame and byte == HDLC.FLAG): + in_frame = False + self.processIncoming(data_buffer) + elif (byte == HDLC.FLAG): + in_frame = True + data_buffer = b"" + elif (in_frame and len(data_buffer) < RNS.Reticulum.MTU): + if (byte == HDLC.ESC): + escape = True + else: + if (escape): + if (byte == HDLC.FLAG ^ HDLC.ESC_MASK): + byte = HDLC.FLAG + if (byte == HDLC.ESC ^ HDLC.ESC_MASK): + byte = HDLC.ESC + escape = False + data_buffer = data_buffer+bytes([byte]) else: RNS.log("TCP socket for "+str(self)+" was closed, tearing down interface", RNS.LOG_VERBOSE) self.teardown() @@ -108,9 +111,8 @@ class TCPClientInterface(Interface): except Exception as e: self.online = False RNS.log("An interface error occurred, the contained exception was: "+str(e), RNS.LOG_ERROR) - RNS.log("The interface "+str(self.name)+" is now offline. Restart Reticulum to attempt reconnection.", RNS.LOG_ERROR) - raise e - + RNS.log("Tearing down "+str(self), RNS.LOG_ERROR) + self.teardown() def teardown(self): self.online = False @@ -128,8 +130,6 @@ class TCPServerInterface(Interface): def __init__(self, owner, name, bindip=None, bindport=None): self.IN = True self.OUT = False - self.transmit_delay = 0.001 - self.name = name if (bindip != None and bindport != None): diff --git a/RNS/Resource.py b/RNS/Resource.py index d873660..f829fd3 100644 --- a/RNS/Resource.py +++ b/RNS/Resource.py @@ -438,14 +438,19 @@ class Resource: pi = 0 for part in self.parts: if part.map_hash == requested_hash: - if not part.sent: - part.send() - self.sent_parts += 1 - else: - part.resend() - self.last_activity = time.time() - self.last_part_sent = self.last_activity - break + try: + if not part.sent: + part.send() + self.sent_parts += 1 + else: + part.resend() + self.last_activity = time.time() + self.last_part_sent = self.last_activity + break + except Exception as e: + RNS.log("Resource could not send parts, cancelling transfer!", RNS.LOG_ERROR) + RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR) + self.cancel() pi += 1 if wants_more_hashmap: @@ -488,8 +493,11 @@ class Resource: self.status = Resource.FAILED if self.initiator: if self.link.status == RNS.Link.ACTIVE: - cancel_packet = RNS.Packet(self.link, self.hash, context=RNS.Packet.RESOURCE_ICL) - cancel_packet.send() + try: + cancel_packet = RNS.Packet(self.link, self.hash, context=RNS.Packet.RESOURCE_ICL) + cancel_packet.send() + except Exception as e: + RNS.log("Could not send resource cancel packet, the contained exception was: "+str(e), RNS.LOG_ERROR) self.link.cancel_outgoing_resource(self) else: self.link.cancel_incoming_resource(self)