From 1e8ef437b950386e2d9a2f31fd2306979c64086a Mon Sep 17 00:00:00 2001 From: Mark Qvist Date: Sat, 28 Aug 2021 15:30:47 +0200 Subject: [PATCH] Implemented delivery as single packets over links. --- LXMF/LXMF.py | 28 ++++++++++++++++++++++------ README.md | 8 ++++---- 2 files changed, 26 insertions(+), 10 deletions(-) diff --git a/LXMF/LXMF.py b/LXMF/LXMF.py index b7a07dc..44e25af 100644 --- a/LXMF/LXMF.py +++ b/LXMF/LXMF.py @@ -228,7 +228,7 @@ class LXMessage: if self.desired_method == LXMessage.OPPORTUNISTIC: if self.__destination.type == RNS.Destination.SINGLE: - single_packet_content_limit = LXMessage.RSA_PACKET_MAX_CONTENT + single_packet_content_limit = LXMessage.ENCRYPTED_PACKET_MAX_CONTENT elif self.__destination.type == RNS.Destination.PLAIN: single_packet_content_limit = LXMessage.PLAIN_PACKET_MAX_CONTENT @@ -256,9 +256,18 @@ class LXMessage: if self.method == LXMessage.OPPORTUNISTIC: self.__as_packet().send().set_delivery_callback(self.__mark_delivered) self.state = LXMessage.SENT + elif self.method == LXMessage.DIRECT: self.state = LXMessage.SENDING - self.resource_representation = self.__as_resource() + + if self.representation == LXMessage.PACKET: + receipt = self.__as_packet().send() + receipt.set_delivery_callback(self.__mark_delivered) + receipt.set_timeout_callback(self.__link_packet_timed_out) + + elif self.representation == LXMessage.RESOURCE: + self.resource_representation = self.__as_resource() + elif self.method == LXMessage.PROPAGATED: # TODO: Implement propagation pass @@ -309,6 +318,10 @@ class LXMessage: resource.link.teardown() self.state = LXMessage.OUTBOUND + def __link_packet_timed_out(self, packet_receipt): + packet_receipt.destination.teardown() + self.state = LXMessage.OUTBOUND + def __update_transfer_progress(self, resource): self.progress = resource.progress() @@ -543,14 +556,14 @@ class LXMRouter: def delivery_packet(self, data, packet): try: - if packet.destination.type != RNS.Destination.LINK: + if packet.destination_type != RNS.Destination.LINK: lxmf_data = b"" lxmf_data += packet.destination.hash lxmf_data += data else: lxmf_data = data - if self.lxmf_delivery(lxmf_data, packet.destination.type): + if self.lxmf_delivery(lxmf_data, packet.destination_type): packet.prove() except Exception as e: @@ -617,7 +630,7 @@ class LXMRouter: if lxmessage.state == LXMessage.DELIVERED: RNS.log("Delivery has occurred for "+str(lxmessage)+", removing from outbound queue", RNS.LOG_DEBUG) self.pending_outbound.remove(lxmessage) - else: + else: RNS.log("Starting outbound processing for "+str(lxmessage)+" to "+RNS.prettyhexrep(lxmessage.get_destination().hash), RNS.LOG_DEBUG) # Outbound handling for opportunistic messages if lxmessage.method == LXMessage.OPPORTUNISTIC: @@ -647,7 +660,10 @@ class LXMRouter: lxmessage.set_delivery_destination(direct_link) lxmessage.send() else: - RNS.log("The transfer of "+str(lxmessage)+" is in progress ("+str(round(lxmessage.progress*100, 1))+"%)", RNS.LOG_DEBUG) + if lxmessage.representation == LXMessage.RESOURCE: + RNS.log("The transfer of "+str(lxmessage)+" is in progress ("+str(round(lxmessage.progress*100, 1))+"%)", RNS.LOG_DEBUG) + else: + RNS.log("Waiting for proof for "+str(lxmessage)+" sent as link packet", RNS.LOG_DEBUG) elif direct_link.status == RNS.Link.CLOSED: RNS.log("The link to "+RNS.prettyhexrep(lxmessage.get_destination().hash)+" was closed", RNS.LOG_DEBUG) lxmessage.set_delivery_destination(None) diff --git a/README.md b/README.md index 1f97785..c6fffca 100644 --- a/README.md +++ b/README.md @@ -20,14 +20,14 @@ LXMF messages are stored in a simple and efficient format, that's easy to parse ##### And these rules: -1. A LXMF message is identified by it's __message-id__, which is a SHA-256 hash of the __Destination__, __Source__ and __Payload__. The message-id is never included directly in the message, since it can always be inferred from the message itself. +1. A LXMF message is identified by its __message-id__, which is a SHA-256 hash of the __Destination__, __Source__ and __Payload__. The message-id is never included directly in the message, since it can always be inferred from the message itself. In some cases the actual message-id cannot be inferred, for example when a Propagation Node is storing an encrypted message for an offline user. In theses cases a _transient-id_ is used to identify the message while in storage or transit. 2. __Destination__, __Source__, __Signature__ and __Payload__ parts are mandatory, as is the __Timestamp__ part of the payload. - - The __Destination__ and __Source__ fields are Reticulum destination hashes - - The __Signature__ field is a Ed25519 signature of the __Destination__, __Source__, __Payload__ and __message-id__ - - The __Payload__ part is a list containing four items: + - The __Destination__ and __Source__ fields are 10-byte Reticulum destination hashes + - The __Signature__ field is a 64-byte Ed25519 signature of the __Destination__, __Source__, __Payload__ and __message-id__ + - The __Payload__ part is a [msgpacked](https://msgpack.org) list containing four items: 1. The __Timestamp__ is a double-precision floating point number representing the number of seconds since the UNIX epoch. 2. The __Content__ is the optional content or body of the message 3. The __Title__ is an optional title for the message