Ejemplo n.º 1
0
def client(destination_hexhash, configpath):
    # We need a binary representation of the destination
    # hash that was entered on the command line
    try:
        if len(destination_hexhash) != 20:
            raise ValueError(
                "Destination length is invalid, must be 20 hexadecimal characters (10 bytes)"
            )
        destination_hash = bytes.fromhex(destination_hexhash)
    except:
        RNS.log("Invalid destination entered. Check your input!\n")
        exit()

    # We must first initialise Reticulum
    reticulum = RNS.Reticulum(configpath)

    # Check if we know a path to the destination
    if not RNS.Transport.has_path(destination_hash):
        RNS.log(
            "Destination is not yet known. Requesting path and waiting for announce to arrive..."
        )
        RNS.Transport.request_path(destination_hash)
        while not RNS.Transport.has_path(destination_hash):
            time.sleep(0.1)

    # Recall the server identity
    server_identity = RNS.Identity.recall(destination_hash)

    # Inform the user that we'll begin connecting
    RNS.log("Establishing link with server...")

    # When the server identity is known, we set
    # up a destination
    server_destination = RNS.Destination(server_identity, RNS.Destination.OUT,
                                         RNS.Destination.SINGLE, APP_NAME,
                                         "filetransfer", "server")

    # We also want to automatically prove incoming packets
    server_destination.set_proof_strategy(RNS.Destination.PROVE_ALL)

    # And create a link
    link = RNS.Link(server_destination)

    # We expect any normal data packets on the link
    # to contain a list of served files, so we set
    # a callback accordingly
    link.set_packet_callback(filelist_received)

    # We'll also set up functions to inform the
    # user when the link is established or closed
    link.set_link_established_callback(link_established)
    link.set_link_closed_callback(link_closed)

    # And set the link to automatically begin
    # downloading advertised resources
    link.set_resource_strategy(RNS.Link.ACCEPT_ALL)
    link.set_resource_started_callback(download_began)
    link.set_resource_concluded_callback(download_concluded)

    menu()
Ejemplo n.º 2
0
def client(destination_hexhash, configpath):
    # We need a binary representation of the destination
    # hash that was entered on the command line
    try:
        if len(destination_hexhash) != 20:
            raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
        destination_hash = bytes.fromhex(destination_hexhash)
    except:
        RNS.log("Invalid destination entered. Check your input!\n")
        exit()

    # We must first initialise Reticulum
    reticulum = RNS.Reticulum(configpath)

    # Check if we know a path to the destination
    if not RNS.Transport.has_path(destination_hash):
        RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...")
        RNS.Transport.request_path(destination_hash)
        while not RNS.Transport.has_path(destination_hash):
            time.sleep(0.1)

    # Recall the server identity
    server_identity = RNS.Identity.recall(destination_hash)

    # Inform the user that we'll begin connecting
    RNS.log("Establishing link with server...")

    # When the server identity is known, we set
    # up a destination
    server_destination = RNS.Destination(
        server_identity,
        RNS.Destination.OUT,
        RNS.Destination.SINGLE,
        APP_NAME,
        "linkexample"
    )

    # And create a link
    link = RNS.Link(server_destination)

    # We set a callback that will get executed
    # every time a packet is received over the
    # link
    link.set_packet_callback(client_packet_received)

    # We'll also set up functions to inform the
    # user when the link is established or closed
    link.set_link_established_callback(link_established)
    link.set_link_closed_callback(link_closed)

    # Everything is set up, so let's enter a loop
    # for the user to interact with the example
    client_loop()
Ejemplo n.º 3
0
    def process_outbound(self, sender=None):
        if self.processing_outbound:
            return

        for lxmessage in self.pending_outbound:
            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:
                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:
                    if lxmessage.delivery_attempts <= LXMRouter.MAX_DELIVERY_ATTEMPTS:
                        if not hasattr(
                                lxmessage, "next_delivery_attempt"
                        ) or time.time() > lxmessage.next_delivery_attempt:
                            lxmessage.delivery_attempts += 1
                            lxmessage.next_delivery_attempt = time.time(
                            ) + LXMRouter.DELIVERY_RETRY_WAIT
                            RNS.log(
                                "Opportunistic delivery attempt " +
                                str(lxmessage.delivery_attempts) + " for " +
                                str(lxmessage) + " to " + RNS.prettyhexrep(
                                    lxmessage.get_destination().hash),
                                RNS.LOG_DEBUG)
                            lxmessage.send()
                    else:
                        RNS.log(
                            "Max delivery attempts reached for oppertunistic "
                            + str(lxmessage) + " to " +
                            RNS.prettyhexrep(lxmessage.get_destination().hash),
                            RNS.LOG_DEBUG)
                        self.fail_message(lxmessage)

                # Outbound handling for messages transferred
                # over a direct link to the final recipient
                elif lxmessage.method == LXMessage.DIRECT:
                    if lxmessage.delivery_attempts <= LXMRouter.MAX_DELIVERY_ATTEMPTS:
                        delivery_destination_hash = lxmessage.get_destination(
                        ).hash

                        if delivery_destination_hash in self.direct_links:
                            # A link already exists, so we'll try to use it
                            # to deliver the message
                            direct_link = self.direct_links[
                                delivery_destination_hash]
                            if direct_link.status == RNS.Link.ACTIVE:
                                if lxmessage.state != LXMessage.SENDING:
                                    RNS.log(
                                        "Starting transfer of " +
                                        str(lxmessage) + " to " +
                                        RNS.prettyhexrep(
                                            lxmessage.get_destination().hash),
                                        RNS.LOG_DEBUG)
                                    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)
                            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)
                                self.direct_links.pop(
                                    delivery_destination_hash)
                                lxmessage.next_delivery_attempt = time.time(
                                ) + LXMRouter.DELIVERY_RETRY_WAIT
                            else:
                                # Simply wait for the link to become
                                # active or close
                                RNS.log(
                                    "The link to " + RNS.prettyhexrep(
                                        lxmessage.get_destination().hash) +
                                    " is pending, waiting for link to become active",
                                    RNS.LOG_DEBUG)
                        else:
                            # No link exists, so we'll try to establish one, but
                            # only if we've never tried before, or the retry wait
                            # period has elapsed.
                            if not hasattr(
                                    lxmessage, "next_delivery_attempt"
                            ) or time.time() > lxmessage.next_delivery_attempt:
                                lxmessage.delivery_attempts += 1
                                lxmessage.next_delivery_attempt = time.time(
                                ) + LXMRouter.DELIVERY_RETRY_WAIT
                                if lxmessage.delivery_attempts < LXMRouter.MAX_DELIVERY_ATTEMPTS:
                                    if RNS.Transport.has_path(
                                            lxmessage.get_destination().hash):
                                        RNS.log(
                                            "Establishing link to " +
                                            RNS.prettyhexrep(
                                                lxmessage.get_destination(
                                                ).hash) +
                                            " for delivery attempt " +
                                            str(lxmessage.delivery_attempts) +
                                            " to " + RNS.prettyhexrep(
                                                lxmessage.get_destination(
                                                ).hash), RNS.LOG_DEBUG)
                                        delivery_link = RNS.Link(
                                            lxmessage.get_destination())
                                        delivery_link.set_link_established_callback(
                                            self.process_outbound)
                                        self.direct_links[
                                            delivery_destination_hash] = delivery_link
                                    else:
                                        RNS.log(
                                            "No path known for delivery attempt "
                                            +
                                            str(lxmessage.delivery_attempts) +
                                            " to " + RNS.prettyhexrep(
                                                lxmessage.get_destination().
                                                hash) + ". Requesting path...",
                                            RNS.LOG_DEBUG)
                                        RNS.Transport.request_path(
                                            lxmessage.get_destination().hash)
                    else:
                        RNS.log(
                            "Max delivery attempts reached for direct " +
                            str(lxmessage) + " to " +
                            RNS.prettyhexrep(lxmessage.get_destination().hash),
                            RNS.LOG_DEBUG)
                        self.fail_message(lxmessage)

                # Outbound handling for messages transported via
                # propagation to a LXMF router network.
                elif lxmessage.method == LXMessage.PROPAGATED:
                    RNS.log(
                        "Attempting propagated delivery for " +
                        str(lxmessage) + " to " +
                        RNS.prettyhexrep(lxmessage.get_destination().hash),
                        RNS.LOG_DEBUG)
                    raise NotImplementedError(
                        "LXMF propagation is not implemented yet")
Ejemplo n.º 4
0
    def __load(self):
        # If an established link exists, but it doesn't match the target
        # destination, we close and clear it.
        if self.link != None and self.link.destination.hash != self.destination_hash:
            self.link.teardown()
            self.link = None

        # If no link to the destination exists, we create one.
        if self.link == None:
            if not RNS.Transport.has_path(self.destination_hash):
                self.status = Browser.NO_PATH
                self.update_display()

                RNS.Transport.request_path(self.destination_hash)
                self.status = Browser.PATH_REQUESTED
                self.update_display()

                pr_time = time.time()
                while not RNS.Transport.has_path(self.destination_hash):
                    now = time.time()
                    if now > pr_time + self.timeout:
                        self.request_timeout()
                        return

                    time.sleep(0.25)

            self.status = Browser.ESTABLISHING_LINK
            self.update_display()

            identity = RNS.Identity.recall(self.destination_hash)
            destination = RNS.Destination(identity, RNS.Destination.OUT,
                                          RNS.Destination.SINGLE,
                                          self.app_name, self.aspects)

            self.link = RNS.Link(destination,
                                 established_callback=self.link_established,
                                 closed_callback=self.link_closed)

            while self.status == Browser.ESTABLISHING_LINK:
                time.sleep(0.1)

            if self.status != Browser.LINK_ESTABLISHED:
                return

            self.update_display()

        # Send the request
        self.status = Browser.REQUESTING
        self.response_progress = 0
        self.response_size = None
        self.response_transfer_size = None
        self.saved_file_name = None

        self.update_display()
        receipt = self.link.request(self.path,
                                    data=None,
                                    response_callback=self.response_received,
                                    failed_callback=self.request_failed,
                                    progress_callback=self.response_progressed)

        if receipt:
            self.last_request_receipt = receipt
            self.last_request_id = receipt.request_id
            self.status = Browser.REQUEST_SENT
            self.update_display()
        else:
            self.link.teardown()