diff --git a/docs/Makefile b/docs/Makefile index 2ce9290..65c8e50 100644 --- a/docs/Makefile +++ b/docs/Makefile @@ -18,8 +18,15 @@ help: # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). %: Makefile @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - rm -rf html - rm -rf manual - cp -r build/html ./ - mv html manual - cp -r build/latex/reticulumnetworkstack.pdf ./Reticulum.pdf + @if [ $@ = "html" ]; then \ + rm -rf html; \ + rm -rf manual; \ + cp -r build/html ./; \ + mv html manual; \ + echo "HTML Manual Generated"; \ + fi + + @if [ $@ = "latexpdf" ]; then \ + cp -r build/latex/reticulumnetworkstack.pdf ./Reticulum\ Manual.pdf; \ + echo "PDF Manual Generated"; \ + fi diff --git a/docs/Reticulum.pdf b/docs/Reticulum Manual.pdf similarity index 52% rename from docs/Reticulum.pdf rename to docs/Reticulum Manual.pdf index 3445f74..6ed067b 100644 Binary files a/docs/Reticulum.pdf and b/docs/Reticulum Manual.pdf differ diff --git a/docs/index.html b/docs/index.html index e69de29..a0b2c7a 100644 --- a/docs/index.html +++ b/docs/index.html @@ -0,0 +1,9 @@ + + + + + + + + + \ No newline at end of file diff --git a/docs/manual/_sources/index.rst.txt b/docs/manual/_sources/index.rst.txt index b90073c..6fb6eb1 100644 --- a/docs/manual/_sources/index.rst.txt +++ b/docs/manual/_sources/index.rst.txt @@ -5,8 +5,6 @@ Welcome to the manual for Reticulum. This document aims to provide you with all the information you need to understand Reticulum, develop programs using it, or to participate in the development of Reticulum itself. -Table of Contents -================= .. toctree:: :maxdepth: 3 @@ -17,16 +15,6 @@ Table of Contents understanding -Current Status -============== -Reticulum should currently be considered beta software. All core protocol features are implemented and functioning, but additions will probably occur as real-world use is explored. There will be bugs. The API and wire-format can be considered relatively stable at the moment, but could change if warranted. - - -Caveat Emptor -============= -Reticulum is experimental software, and should be considered as such. While it has been built with cryptography best-practices very foremost in mind, it has not been externally security audited, and there could very well be privacy-breaking bugs. To be considered secure, Reticulum needs a very thourough security review by independt cryptographers and security researchers. If you want to help out, or help sponsor an audit, please do get in touch. - - Indices and Tables ================== diff --git a/docs/manual/_sources/whatis.rst.txt b/docs/manual/_sources/whatis.rst.txt index 31ba227..742e8bb 100644 --- a/docs/manual/_sources/whatis.rst.txt +++ b/docs/manual/_sources/whatis.rst.txt @@ -9,6 +9,16 @@ Reticulum is a complete networking stack, and does not use IP or higher layers, No kernel modules or drivers are required. Reticulum runs completely in userland, and can run on practically any system that runs Python 3. +Current Status +============== +Reticulum should currently be considered beta software. All core protocol features are implemented and functioning, but additions will probably occur as real-world use is explored. There will be bugs. The API and wire-format can be considered relatively stable at the moment, but could change if warranted. + + +Caveat Emptor +============== +Reticulum is experimental software, and should be considered as such. While it has been built with cryptography best-practices very foremost in mind, it has not been externally security audited, and there could very well be privacy-breaking bugs. To be considered secure, Reticulum needs a very thourough security review by independt cryptographers and security researchers. If you want to help out, or help sponsor an audit, please do get in touch. + + What does Reticulum Offer? ========================== * Coordination-less globally unique adressing and identification diff --git a/docs/manual/examples.html b/docs/manual/examples.html index 4f26335..d3357b9 100644 --- a/docs/manual/examples.html +++ b/docs/manual/examples.html @@ -80,7 +80,13 @@ program.

# existence, which will let the network know they are reachable # and autoomatically create paths to them, from anywhere else # in the network. - destination = RNS.Destination(identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "minimalsample") + destination = RNS.Destination( + identity, + RNS.Destination.IN, + RNS.Destination.SINGLE, + APP_NAME, + "minimalsample" + ) # We configure the destination to automatically prove all # packets adressed to it. By doing this, RNS will automatically @@ -97,7 +103,11 @@ program.

def announceLoop(destination): # Let the user know that everything is ready - RNS.log("Minimal example "+RNS.prettyhexrep(destination.hash)+" running, hit enter to manually send an announce (Ctrl-C to quit)") + RNS.log( + "Minimal example "+ + RNS.prettyhexrep(destination.hash)+ + " running, hit enter to manually send an announce (Ctrl-C to quit)" + ) # We enter a loop that runs until the users exits. # If the user hits enter, we will announce our server @@ -118,8 +128,18 @@ program.

# the desired program mode. if __name__ == "__main__": try: - parser = argparse.ArgumentParser(description="Bare minimum example to start Reticulum and create a destination") - parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str) + parser = argparse.ArgumentParser( + description="Minimal example to start Reticulum and create a destination" + ) + + parser.add_argument( + "--config", + action="store", + default=None, + help="path to alternative Reticulum config directory", + type=str + ) + args = parser.parse_args() if args.config: @@ -158,7 +178,7 @@ notifications about announces from relevant destinations.

APP_NAME = "example_utilities" # We initialise two lists of strings to use as app_data -fruits = ["Peach", "Quince", "Date palm", "Tangerine", "Pomelo", "Carambola", "Grape", "Passion fruit", "Prune", "Cranberry", "Strawberry", "Papaya", "Pomegranate", "Avocado", "Mango"] +fruits = ["Peach", "Quince", "Date palm", "Tangerine", "Pomelo", "Carambola", "Grape"] noble_gases = ["Helium", "Neon", "Argon", "Krypton", "Xenon", "Radon", "Oganesson"] # This initialisation is executed when the program is started @@ -177,8 +197,23 @@ notifications about announces from relevant destinations.

# existence, which will let the network know they are reachable # and autoomatically create paths to them, from anywhere else # in the network. - destination_1 = RNS.Destination(identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "announcesample", "fruits") - destination_2 = RNS.Destination(identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "announcesample", "noble_gases") + destination_1 = RNS.Destination( + identity, + RNS.Destination.IN, + RNS.Destination.SINGLE, + APP_NAME, + "announcesample", + "fruits" + ) + + destination_2 = RNS.Destination( + identity, + RNS.Destination.IN, + RNS.Destination.SINGLE, + APP_NAME, + "announcesample", + "noble_gases" + ) # We configure the destinations to automatically prove all # packets adressed to it. By doing this, RNS will automatically @@ -192,7 +227,9 @@ notifications about announces from relevant destinations.

# We create an announce handler and configure it to only ask for # announces from "example_utilities.announcesample.fruits". # Try changing the filter and see what happens. - announce_handler = ExampleAnnounceHandler(aspect_filter="example_utilities.announcesample.fruits") + announce_handler = ExampleAnnounceHandler( + aspect_filter="example_utilities.announcesample.fruits" + ) # We register the announce handler with Reticulum RNS.Transport.register_announce_handler(announce_handler) @@ -218,14 +255,22 @@ notifications about announces from relevant destinations.

# Send the announce including the app data destination_1.announce(app_data=fruit.encode("utf-8")) - RNS.log("Sent announce from "+RNS.prettyhexrep(destination_1.hash)+" ("+destination_1.name+")") + RNS.log( + "Sent announce from "+ + RNS.prettyhexrep(destination_1.hash)+ + " ("+destination_1.name+")" + ) # Randomly select a noble gas noble_gas = noble_gases[random.randint(0,len(noble_gases)-1)] # Send the announce including the app data destination_2.announce(app_data=noble_gas.encode("utf-8")) - RNS.log("Sent announce from "+RNS.prettyhexrep(destination_2.hash)+" ("+destination_2.name+")") + RNS.log( + "Sent announce from "+ + RNS.prettyhexrep(destination_2.hash)+ + " ("+destination_2.name+")" + ) # We will need to define an announce handler class that # Reticulum can message when an announce arrives. @@ -243,8 +288,15 @@ notifications about announces from relevant destinations.

# configured aspect filter. Filters must be specific, # and cannot use wildcards. def received_announce(self, destination_hash, announced_identity, app_data): - RNS.log("Received an announce from "+RNS.prettyhexrep(destination_hash)) - RNS.log("The announce contained the following app data: "+app_data.decode("utf-8")) + RNS.log( + "Received an announce from "+ + RNS.prettyhexrep(destination_hash) + ) + + RNS.log( + "The announce contained the following app data: "+ + app_data.decode("utf-8") + ) ########################################################## #### Program Startup ##################################### @@ -255,8 +307,18 @@ notifications about announces from relevant destinations.

# the desired program mode. if __name__ == "__main__": try: - parser = argparse.ArgumentParser(description="Reticulum example that demonstrates announces and announce handlers") - parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str) + parser = argparse.ArgumentParser( + description="Reticulum example that demonstrates announces and announce handlers" + ) + + parser.add_argument( + "--config", + action="store", + default=None, + help="path to alternative Reticulum config directory", + type=str + ) + args = parser.parse_args() if args.config: @@ -307,7 +369,14 @@ over the network.

# We create a PLAIN destination. This is an uncencrypted endpoint # that anyone can listen to and send information to. - broadcast_destination = RNS.Destination(None, RNS.Destination.IN, RNS.Destination.PLAIN, APP_NAME, "broadcast", channel) + broadcast_destination = RNS.Destination( + None, + RNS.Destination.IN, + RNS.Destination.PLAIN, + APP_NAME, + "broadcast", + channel + ) # We specify a callback that will get called every time # the destination receives data. @@ -325,7 +394,11 @@ over the network.

def broadcastLoop(destination): # Let the user know that everything is ready - RNS.log("Broadcast example "+RNS.prettyhexrep(destination.hash)+" running, enter text and hit enter to broadcast (Ctrl-C to quit)") + RNS.log( + "Broadcast example "+ + RNS.prettyhexrep(destination.hash)+ + " running, enter text and hit enter to broadcast (Ctrl-C to quit)" + ) # We enter a loop that runs until the users exits. # If the user hits enter, we will send the information @@ -350,9 +423,26 @@ over the network.

# the program. if __name__ == "__main__": try: - parser = argparse.ArgumentParser(description="Reticulum example that demonstrates sending and receiving unencrypted broadcasts") - parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str) - parser.add_argument("--channel", action="store", default=None, help="broadcast channel name", type=str) + parser = argparse.ArgumentParser( + description="Reticulum example demonstrating sending and receiving broadcasts" + ) + + parser.add_argument( + "--config", + action="store", + default=None, + help="path to alternative Reticulum config directory", + type=str + ) + + parser.add_argument( + "--channel", + action="store", + default=None, + help="broadcast channel name", + type=str + ) + args = parser.parse_args() if args.config: @@ -414,7 +504,14 @@ the Packet interface.

# messages. This way the client can send a request and be # certain that no-one else than this destination was able # to read it. - echo_destination = RNS.Destination(server_identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "echo", "request") + echo_destination = RNS.Destination( + server_identity, + RNS.Destination.IN, + RNS.Destination.SINGLE, + APP_NAME, + "echo", + "request" + ) # We configure the destination to automatically prove all # packets adressed to it. By doing this, RNS will automatically @@ -434,7 +531,11 @@ the Packet interface.

def announceLoop(destination): # Let the user know that everything is ready - RNS.log("Echo server "+RNS.prettyhexrep(destination.hash)+" running, hit enter to manually send an announce (Ctrl-C to quit)") + RNS.log( + "Echo server "+ + RNS.prettyhexrep(destination.hash)+ + " running, hit enter to manually send an announce (Ctrl-C to quit)" + ) # We enter a loop that runs until the users exits. # If the user hits enter, we will announce our server @@ -465,7 +566,10 @@ the Packet interface.

# 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)") + 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") @@ -480,7 +584,11 @@ the Packet interface.

RNS.loglevel = RNS.LOG_INFO # Tell the user that the client is ready! - RNS.log("Echo client ready, hit enter to send echo request to "+destination_hexhash+" (Ctrl-C to quit)") + RNS.log( + "Echo client ready, hit enter to send echo request to "+ + destination_hexhash+ + " (Ctrl-C to quit)" + ) # We enter a loop that runs until the user exits. # If the user hits enter, we will try to send an @@ -507,7 +615,14 @@ the Packet interface.

# example_utilities.echo.request # This matches the naming we specified in the # server part of the code. - request_destination = RNS.Destination(server_identity, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "echo", "request") + request_destination = RNS.Destination( + server_identity, + RNS.Destination.OUT, + RNS.Destination.SINGLE, + APP_NAME, + "echo", + "request" + ) # The destination is ready, so let's create a packet. # We set the destination to the request_destination @@ -552,7 +667,11 @@ the Packet interface.

rtt = round(rtt*1000, 3) rttstring = str(rtt)+" milliseconds" - RNS.log("Valid reply received from "+RNS.prettyhexrep(receipt.destination.hash)+", round-trip time is "+rttstring) + RNS.log( + "Valid reply received from "+ + RNS.prettyhexrep(receipt.destination.hash)+ + ", round-trip time is "+rttstring + ) # This function is called if a packet times out. def packet_timed_out(receipt): @@ -570,10 +689,39 @@ the Packet interface.

if __name__ == "__main__": try: parser = argparse.ArgumentParser(description="Simple echo server and client utility") - parser.add_argument("-s", "--server", action="store_true", help="wait for incoming packets from clients") - parser.add_argument("-t", "--timeout", action="store", metavar="s", default=None, help="set a reply timeout in seconds", type=float) - parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str) - parser.add_argument("destination", nargs="?", default=None, help="hexadecimal hash of the server destination", type=str) + + parser.add_argument( + "-s", + "--server", + action="store_true", + help="wait for incoming packets from clients" + ) + + parser.add_argument( + "-t", + "--timeout", + action="store", + metavar="s", + default=None, + help="set a reply timeout in seconds", + type=float + ) + + parser.add_argument("--config", + action="store", + default=None, + help="path to alternative Reticulum config directory", + type=str + ) + + parser.add_argument( + "destination", + nargs="?", + default=None, + help="hexadecimal hash of the server destination", + type=str + ) + args = parser.parse_args() if args.server: @@ -645,7 +793,13 @@ destination, and passing traffic back and forth over the link.

# We create a destination that clients can connect to. We # want clients to create links to this destination, so we # need to create a "single" destination type. - server_destination = RNS.Destination(server_identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "linkexample") + server_destination = RNS.Destination( + server_identity, + RNS.Destination.IN, + RNS.Destination.SINGLE, + APP_NAME, + "linkexample" + ) # We configure a function that will get called every time # a new client creates a link to this destination. @@ -657,7 +811,12 @@ destination, and passing traffic back and forth over the link.

def server_loop(destination): # Let the user know that everything is ready - RNS.log("Link example "+RNS.prettyhexrep(destination.hash)+" running, waiting for a connection.") + RNS.log( + "Link example "+ + RNS.prettyhexrep(destination.hash)+ + " running, waiting for a connection." + ) + RNS.log("Hit enter to manually send an announce (Ctrl-C to quit)") # We enter a loop that runs until the users exits. @@ -735,7 +894,13 @@ destination, and passing traffic back and forth over the link.

# 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") + server_destination = RNS.Destination( + server_identity, + RNS.Destination.OUT, + RNS.Destination.SINGLE, + APP_NAME, + "linkexample" + ) # And create a link link = RNS.Link(server_destination) @@ -825,9 +990,30 @@ destination, and passing traffic back and forth over the link.

if __name__ == "__main__": try: parser = argparse.ArgumentParser(description="Simple link example") - parser.add_argument("-s", "--server", action="store_true", help="wait for incoming link requests from clients") - parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str) - parser.add_argument("destination", nargs="?", default=None, help="hexadecimal hash of the server destination", type=str) + + parser.add_argument( + "-s", + "--server", + action="store_true", + help="wait for incoming link requests from clients" + ) + + parser.add_argument( + "--config", + action="store", + default=None, + help="path to alternative Reticulum config directory", + type=str + ) + + parser.add_argument( + "destination", + nargs="?", + default=None, + help="hexadecimal hash of the server destination", + type=str + ) + args = parser.parse_args() if args.config: @@ -913,7 +1099,14 @@ interface to efficiently pass files of any size over a Reticulum # We create a destination that clients can connect to. We # want clients to create links to this destination, so we # need to create a "single" destination type. - server_destination = RNS.Destination(server_identity, RNS.Destination.IN, RNS.Destination.SINGLE, APP_NAME, "filetransfer", "server") + server_destination = RNS.Destination( + server_identity, + RNS.Destination.IN, + RNS.Destination.SINGLE, + APP_NAME, + "filetransfer", + "server" + ) # We configure a function that will get called every time # a new client creates a link to this destination. @@ -994,7 +1187,13 @@ interface to efficiently pass files of any size over a Reticulum # read it and pack it as a resource RNS.log("Client requested \""+filename+"\"") file = open(os.path.join(serve_path, filename), "rb") - file_resource = RNS.Resource(file, packet.link, callback=resource_sending_concluded) + + file_resource = RNS.Resource( + file, + packet.link, + callback=resource_sending_concluded + ) + file_resource.filename = filename except Exception as e: # If somethign went wrong, we close @@ -1082,7 +1281,14 @@ interface to efficiently pass files of any size over a Reticulum # 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") + 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) @@ -1383,10 +1589,34 @@ interface to efficiently pass files of any size over a Reticulum # starts up the desired program mode. if __name__ == "__main__": try: - parser = argparse.ArgumentParser(description="Simple file transfer server and client utility") - parser.add_argument("-s", "--serve", action="store", metavar="dir", help="serve a directory of files to clients") - parser.add_argument("--config", action="store", default=None, help="path to alternative Reticulum config directory", type=str) - parser.add_argument("destination", nargs="?", default=None, help="hexadecimal hash of the server destination", type=str) + parser = argparse.ArgumentParser( + description="Simple file transfer server and client utility" + ) + + parser.add_argument( + "-s", + "--serve", + action="store", + metavar="dir", + help="serve a directory of files to clients" + ) + + parser.add_argument( + "--config", + action="store", + default=None, + help="path to alternative Reticulum config directory", + type=str + ) + + parser.add_argument( + "destination", + nargs="?", + default=None, + help="hexadecimal hash of the server destination", + type=str + ) + args = parser.parse_args() if args.config: diff --git a/docs/manual/index.html b/docs/manual/index.html index 1c8cb13..1ebb600 100644 --- a/docs/manual/index.html +++ b/docs/manual/index.html @@ -42,11 +42,11 @@

Welcome to the manual for Reticulum. This document aims to provide you with all the information you need to understand Reticulum, develop programs using it, or to participate in the development of Reticulum itself.

-
-

Table of Contents

-
-
-

Current Status

-

Reticulum should currently be considered beta software. All core protocol features are implemented and functioning, but additions will probably occur as real-world use is explored. There will be bugs. The API and wire-format can be considered relatively stable at the moment, but could change if warranted.

-
-
-

Caveat Emptor

-

Reticulum is experimental software, and should be considered as such. While it has been built with cryptography best-practices very foremost in mind, it has not been externally security audited, and there could very well be privacy-breaking bugs. To be considered secure, Reticulum needs a very thourough security review by independt cryptographers and security researchers. If you want to help out, or help sponsor an audit, please do get in touch.

-

Indices and Tables