def client_connected(link): # Check if the served directory still exists if os.path.isdir(serve_path): RNS.log("Client connected, sending file list...") link.set_link_closed_callback(client_disconnected) # We pack a list of files for sending in a packet data = umsgpack.packb(list_files()) # Check the size of the packed data if len(data) <= RNS.Link.MDU: # If it fits in one packet, we will just # send it as a single packet over the link. list_packet = RNS.Packet(link, data) list_receipt = list_packet.send() list_receipt.set_timeout(APP_TIMEOUT) list_receipt.set_delivery_callback(list_delivered) list_receipt.set_timeout_callback(list_timeout) else: RNS.log("Too many files in served directory!", RNS.LOG_ERROR) RNS.log( "You should implement a function to split the filelist over multiple packets.", RNS.LOG_ERROR) RNS.log("Hint: The client already supports it :)", RNS.LOG_ERROR) # After this, we're just going to keep the link # open until the client requests a file. We'll # configure a function that get's called when # the client sends a packet with a file request. link.set_packet_callback(client_request) else: RNS.log("Client connected, but served path no longer exists!", RNS.LOG_ERROR) link.teardown()
def write_to_directory(self, directory_path): file_name = RNS.hexrep(self.hash, delimit=False) file_path = directory_path + "/" + file_name try: if not self.packed: self.pack() container = { "state": self.state, "lxmf_bytes": self.packed, "transport_encrypted": self.transport_encrypted, "transport_encryption": self.transport_encryption } packed_container = msgpack.packb(container) file = open(file_path, "wb") file.write(packed_container) file.close() return file_path except Exception as e: RNS.log( "Error while writing LXMF message to file \"" + str(file_path) + "\". The contained exception was: " + str(e), RNS.LOG_ERROR) return None
def save_to_disk(self): try: packed_list = [] for source_hash in self.directory_entries: e = self.directory_entries[source_hash] packed_list.append( (e.source_hash, e.display_name, e.trust_level, e.hosts_node, e.preferred_delivery, e.identify)) directory = { "entry_list": packed_list, "announce_stream": self.announce_stream } file = open(self.app.directorypath, "wb") file.write(msgpack.packb(directory)) file.close() except Exception as e: RNS.log( "Could not write directory to disk. Then contained exception was: " + str(e), RNS.LOG_ERROR)
def pack(self): if not self.packed: if self.timestamp == None: self.timestamp = time.time() self.payload = [ self.timestamp, self.title, self.content, self.fields ] hashed_part = b"" hashed_part += self.__destination.hash hashed_part += self.__source.hash hashed_part += msgpack.packb(self.payload) self.hash = RNS.Identity.full_hash(hashed_part) self.message_id = self.hash signed_part = b"" signed_part += hashed_part signed_part += self.hash self.signature = self.__source.sign(signed_part) self.signature_validated = True self.packed = b"" self.packed += self.__destination.hash self.packed += self.__source.hash self.packed += self.signature packed_payload = msgpack.packb(self.payload) self.packed += packed_payload self.packed_size = len(self.packed) content_size = len(packed_payload) # If no desired delivery method has been defined, # one will be chosen according to these rules: if self.desired_method == None: self.desired_method == LXMessage.DIRECT # TODO: Expand rules to something more intelligent if self.desired_method == LXMessage.OPPORTUNISTIC: if self.__destination.type == RNS.Destination.SINGLE: single_packet_content_limit = LXMessage.RSA_PACKET_MAX_CONTENT elif self.__destination.type == RNS.Destination.PLAIN: single_packet_content_limit = LXMessage.PLAIN_PACKET_MAX_CONTENT if content_size > single_packet_content_limit: raise TypeError( "LXMessage desired opportunistic delivery method, but content exceeds single-packet size." ) else: self.method = LXMessage.OPPORTUNISTIC self.representation = LXMessage.PACKET self.__delivery_destination = self.__destination elif self.desired_method == LXMessage.DIRECT or self.desired_method == LXMessage.PROPAGATED: single_packet_content_limit = LXMessage.LINK_PACKET_MAX_CONTENT if content_size <= single_packet_content_limit: self.method = self.desired_method self.representation = LXMessage.PACKET else: self.method = self.desired_method self.representation = LXMessage.RESOURCE else: raise ValueError("Attempt to re-pack LXMessage " + str(self) + " that was already packed")
def save_peer_settings(self): file = open(self.peersettingspath, "wb") file.write(msgpack.packb(self.peer_settings)) file.close()