From cd8de6420155dc14f1b4743fc99d8c5bf68589cb Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Thu, 2 Sep 2021 18:00:03 +0200 Subject: [PATCH] Implemented ability to change MTU. --- RNS/Identity.py | 5 +++-- RNS/Link.py | 27 +++++++++++++++------------ RNS/Packet.py | 2 +- RNS/Resource.py | 5 ++++- RNS/Reticulum.py | 25 +++++++++++++++++-------- 5 files changed, 40 insertions(+), 24 deletions(-) diff --git a/RNS/Identity.py b/RNS/Identity.py index fba18b7..038bb96 100644 --- a/RNS/Identity.py +++ b/RNS/Identity.py @@ -34,12 +34,13 @@ class Identity: """ # Non-configurable constants - AES_HMAC_OVERHEAD = 58 # In bytes + FERNET_VERSION = 0x80 + FERNET_OVERHEAD = 57 # In bytes AES128_BLOCKSIZE = 16 # In bytes HASHLENGTH = 256 # In bits SIGLENGTH = KEYSIZE # In bits - TRUNCATED_HASHLENGTH = 80 # In bits + TRUNCATED_HASHLENGTH = RNS.Reticulum.TRUNCATED_HASHLENGTH """ Constant specifying the truncated hash length (in bits) used by Reticulum for addressable hashes and other purposes. Non-configurable. diff --git a/RNS/Link.py b/RNS/Link.py index 00dc638..2a6a4fc 100644 --- a/RNS/Link.py +++ b/RNS/Link.py @@ -44,7 +44,7 @@ class Link: ECPUBSIZE = 32+32 KEYSIZE = 32 - MDU = math.floor((RNS.Reticulum.MDU-RNS.Identity.AES_HMAC_OVERHEAD)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1 + MDU = math.floor((RNS.Reticulum.MTU-RNS.Reticulum.HEADER_MINSIZE-RNS.Identity.FERNET_OVERHEAD)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1 # This value is set at a reasonable # level for a 1 Kb/s channel. @@ -284,6 +284,7 @@ class Link: :param failed_callback: An optional function or method with the signature *failed_callback(request_receipt)* to be called when a request fails. See the :ref:`Request Example` for more info. :param progress_callback: An optional function or method with the signature *progress_callback(request_receipt)* to be called when progress is made receiving the response. Progress can be accessed as a float between 0.0 and 1.0 by the *request_receipt.progress* property. :param timeout: An optional timeout in seconds for the request. If *None* is supplied it will be calculated based on link RTT. + :returns: A :ref:`RNS.RequestReceipt` instance if the request was sent, or *False* if it was not. """ request_path_hash = RNS.Identity.truncated_hash(path.encode("utf-8")) unpacked_request = [time.time(), request_path_hash, data] @@ -296,17 +297,19 @@ class Link: request_packet = RNS.Packet(self, packed_request, RNS.Packet.DATA, context = RNS.Packet.REQUEST) packet_receipt = request_packet.send() - 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 - ) - + 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 + ) + else: request_id = RNS.Identity.truncated_hash(packed_request) RNS.log("Sending request "+RNS.prettyhexrep(request_id)+" as resource.", RNS.LOG_DEBUG) diff --git a/RNS/Packet.py b/RNS/Packet.py index 23ba622..3e351f8 100755 --- a/RNS/Packet.py +++ b/RNS/Packet.py @@ -71,7 +71,7 @@ class Packet: # With an MTU of 500, the maximum of data we can # send in a single encrypted packet is given by # the below calculation; 383 bytes. - ENCRYPTED_MDU = math.floor((RNS.Reticulum.MDU-RNS.Identity.AES_HMAC_OVERHEAD-RNS.Identity.KEYSIZE//16)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1 + ENCRYPTED_MDU = math.floor((RNS.Reticulum.MDU-RNS.Identity.FERNET_OVERHEAD-RNS.Identity.KEYSIZE//16)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1 """ The maximum size of the payload data in a single encrypted packet """ diff --git a/RNS/Resource.py b/RNS/Resource.py index 93aa82d..d389568 100644 --- a/RNS/Resource.py +++ b/RNS/Resource.py @@ -781,9 +781,12 @@ class Resource: class ResourceAdvertisement: - HASHMAP_MAX_LEN = 70 + OVERHEAD = 128 + HASHMAP_MAX_LEN = math.floor((RNS.Link.MDU-OVERHEAD)/Resource.MAPHASH_LEN) COLLISION_GUARD_SIZE = 2*Resource.WINDOW_MAX+HASHMAP_MAX_LEN + assert HASHMAP_MAX_LEN > 0, "The configured MTU is too small to include any map hashes in resource advertisments" + @staticmethod def is_request(advertisement_packet): adv = ResourceAdvertisement.unpack(advertisement_packet.plaintext) diff --git a/RNS/Reticulum.py b/RNS/Reticulum.py index 510358d..d10dd38 100755 --- a/RNS/Reticulum.py +++ b/RNS/Reticulum.py @@ -36,15 +36,24 @@ class Reticulum: other programs to use on demand. """ - # The default RNS MTU is 500 bytes. This number has been chosen as - # a balance between compatibility with existing hardware devices - # on one hand, and the ability to use sufficiently high cryptographic - # key sizes on the other. In custom RNS network implementations, it - # is possible to raise this value, but doing so will completely break - # compatibility with all other RNS networks. An identical MTU is a - # prerequisite for peers to communicate in the same network. MTU = 500 - HEADER_MAXSIZE = 23 + """ + The MTU that Reticulum adheres to, and will expect other peers to + adhere to. By default, the MTU is 500 bytes. In custom RNS network + implementations, it is possible to change this value, but doing so will + completely break compatibility with all other RNS networks. An identical + MTU is a prerequisite for peers to communicate in the same network. + + The absolute minimum MTU that Reticulum will function with is 215 bytes, + but bandwidth efficiency will be significantly impacted. + """ + + # Length of truncated hashes in bits. + TRUNCATED_HASHLENGTH = 80 + + HEADER_MINSIZE = 2+1+(TRUNCATED_HASHLENGTH//8)*1 + HEADER_MAXSIZE = 2+1+(TRUNCATED_HASHLENGTH//8)*2 + MDU = MTU - HEADER_MAXSIZE router = None