Compare commits

...

57 Commits

Author SHA1 Message Date
Mark Qvist e738c9561a Updated manual 2023-02-17 21:53:07 +01:00
Mark Qvist 994d1c8ee5 Updated roadmap 2023-02-17 21:41:41 +01:00
Mark Qvist ce21800537 Merge branch 'master' of https://git.unsigned.io/markqvist/Reticulum 2023-02-17 21:33:04 +01:00
Mark Qvist d02cdd5471 Added JSON output to rnstatus 2023-02-17 21:29:35 +01:00
Mark Qvist 7018e412d5 Updated roadmap 2023-02-17 21:28:13 +01:00
Mark Qvist 94f7505076 Updated docs 2023-02-17 21:25:14 +01:00
Mark Qvist b82ecf047a Added Link establishment rate calculation 2023-02-17 09:54:18 +01:00
Mark Qvist f21b93403a Updated documentation 2023-02-17 09:53:27 +01:00
Mark Qvist 59c88bc43b Merge branch 'master' of github.com:markqvist/Reticulum 2023-02-15 12:53:37 +01:00
Mark Qvist 8e98c1b038 Updated roadmap 2023-02-15 12:51:41 +01:00
Mark Qvist 4d3570fe4c Updated version 2023-02-15 12:28:06 +01:00
markqvist 3706769c33 Updated link. Fixes #216. 2023-02-09 22:27:11 +01:00
Mark Qvist ce91c34b21 Merge branch 'master' of https://git.unsigned.io/markqvist/Reticulum 2023-02-09 16:22:39 +01:00
Mark Qvist e37aa5e51a Added contribution guidelines 2023-02-09 16:18:59 +01:00
Mark Qvist 80af0f4539 Updated roadmap 2023-02-09 14:07:30 +01:00
Mark Qvist fc818f00f1 Merge branch 'master' of github.com:markqvist/Reticulum 2023-02-09 11:54:06 +01:00
Mark Qvist a55d39b7d4 Added Link ID to response_generator callback signature 2023-02-09 11:52:54 +01:00
Mark Qvist 8e264359db Fixed link 2023-02-09 11:25:51 +01:00
markqvist cbaeaa9f81 Merge pull request #203 from Erethon/rnodeconf-typo
rnodeconf: Typo fix on board versions
2023-02-04 19:21:21 +01:00
Dionysis Grigoropoulos 323c2285ce rnodeconf: Typo fix on board versions 2023-02-04 17:16:57 +02:00
Mark Qvist 5b6d0ec337 Updated manual 2023-02-04 16:00:07 +01:00
Mark Qvist 2bbb0f5ec2 Fixed missing entrypoint 2023-02-04 15:59:58 +01:00
Mark Qvist e385c79abd Updated manual 2023-02-04 15:38:44 +01:00
Mark Qvist 86faf6c28d Updated roadmap 2023-02-04 15:36:11 +01:00
Mark Qvist 6d8a3f09e5 Updated readme 2023-02-04 15:35:55 +01:00
Mark Qvist 1e88a390f4 Updated manual 2023-02-04 14:28:28 +01:00
Mark Qvist e9ae255f84 Added fallback version URL to rnodeconf updater 2023-02-04 14:18:11 +01:00
Mark Qvist 42dfee8557 Added Bluetooth pairing PIN output 2023-02-04 13:45:12 +01:00
Mark Qvist 177e724457 Updated roadmap 2023-02-04 12:17:05 +01:00
Mark Qvist 1b55ac7f24 Added destination hash generation and announce functionality to rnid utility 2023-02-03 20:27:39 +01:00
Mark Qvist 5447ed85c1 Updated documentation 2023-02-03 11:32:54 +01:00
Mark Qvist d7aacba797 Cleanup 2023-02-03 10:13:36 +01:00
Mark Qvist b92ddeccff Cleanup 2023-02-03 08:29:32 +01:00
Mark Qvist 6fac96ec18 Mask entire header 2023-02-03 00:11:11 +01:00
Mark Qvist 53ceafcebd Improved IFAC mask derivation 2023-02-02 23:59:02 +01:00
Mark Qvist 4df67304d6 Added payload masking to interfaces with IFAC enabled 2023-02-02 20:48:52 +01:00
Mark Qvist ac07ba1368 Added Identity generation to rnid utility 2023-02-02 19:26:27 +01:00
Mark Qvist ece064d46e Updated version 2023-02-02 19:05:15 +01:00
Mark Qvist 86ae42a049 Updated docs 2023-02-02 19:04:52 +01:00
Mark Qvist 08e480387b Added signing and validation to rnid 2023-02-02 19:02:05 +01:00
Mark Qvist f4241ae9c2 Added basic rnid utility 2023-02-02 17:45:59 +01:00
Mark Qvist b6928b7d83 Merge branch 'master' of github.com:markqvist/Reticulum 2023-02-02 10:40:58 +01:00
markqvist 3b2fbe02c6 Merge pull request #189 from Erethon/master
Fix bug where announce_identity could be undefined
2023-02-02 10:41:42 +01:00
markqvist a38bde7801 Merge pull request #191 from Erethon/packet-header-fix
packet: Fix header_type matching according to IFAC
2023-02-02 10:22:44 +01:00
markqvist df132d1d59 Merge pull request #199 from Erethon/doc-fixes
docs: Fix typos, remove old info about rnsconfig
2023-02-02 10:16:13 +01:00
Mark Qvist 143f7fa683 Merge branch 'master' of github.com:markqvist/Reticulum 2023-02-02 10:15:41 +01:00
Dionysis Grigoropoulos feb614d186 docs: Fix typos, remove old info about rnsconfig 2023-02-01 22:30:56 +02:00
Mark Qvist 159be78f23 Updated docs 2023-02-01 15:44:23 +01:00
Mark Qvist 4a6c6568e2 Merge branch 'master' of github.com:markqvist/Reticulum 2023-02-01 13:45:05 +01:00
Mark Qvist e64fa08c74 Updated documentation. Fixes #197. 2023-02-01 13:44:00 +01:00
markqvist 6651976423 Merge pull request #193 from jooray/patch-1
Fix a typo
2023-01-28 23:10:14 +01:00
Juraj Bednar 5decf22b8b Fix a typo
Fix documentation: rncp called instead of rnx in rnx example
2023-01-28 21:32:37 +01:00
Mark Qvist a731a8b047 Merge branch 'master' of https://git.unsigned.io/markqvist/Reticulum 2023-01-27 18:51:37 +01:00
Mark Qvist 9bb9571fc9 Updated documentation 2023-01-27 18:51:25 +01:00
Dionysis Grigoropoulos 6ecae615de packet: Fix header_type matching according to IFAC
Ever since IFAC/Interface Access Codes were introduced, the header type
is one bit long and not two.
2023-01-27 15:29:06 +02:00
Dionysis Grigoropoulos 72ca6316f6 Fix bug where announce_identity could be undefined 2023-01-26 22:05:38 +02:00
Mark Qvist 0f023cc533 Updated roadmap 2023-01-19 15:14:15 +01:00
42 changed files with 1088 additions and 139 deletions
+23
View File
@@ -0,0 +1,23 @@
# Contributing to Reticulum
Welcome, and thank you for your interest in contributing to Reticulum!
Apart from writing code, there are many ways in which you can contribute. Before getting started, please read these guidelines.
## Asking Questions
If you want to ask a question, do not open an issue.
Instead, ask away on the [discussions](https://github.com/markqvist/Reticulum/discussions) or on the [Reticulum Matrix channel](https://unsigned.io/contact.html#reticulum:matrix.org) at `#reticulum:matrix.org`
## Providing Feedback
Likewise, feedback, ideas and feature requests are a very welcome way to contribute, and should also be posted on the [discussions](https://github.com/markqvist/Reticulum/discussions), or on the [Reticulum Matrix channel](https://unsigned.io/contact.html#reticulum:matrix.org) at `#reticulum:matrix.org`
## Reporting Issues
If you have found a bug or issue in Reticulum, please report it on the [issue tracker](https://github.com/markqvist/Reticulum/issues).
## Writing Code
If you are interested in contributing code, fixing open issues or adding features, please coordinate the effort with the maintainer or one of the main developers first, to ensure your efforts are in alignment with the [Roadmap](./Roadmap.md) and current development focus.
+2 -2
View File
@@ -23,8 +23,8 @@ APP_NAME = "example_utilities"
# A reference to the latest client link that connected
latest_client_link = None
def random_text_generator(path, data, request_id, remote_identity, requested_at):
RNS.log("Generating response to request "+RNS.prettyhexrep(request_id))
def random_text_generator(path, data, request_id, link_id, remote_identity, requested_at):
RNS.log("Generating response to request "+RNS.prettyhexrep(request_id)+" on link "+RNS.prettyhexrep(link_id))
texts = ["They looked up", "On each full moon", "Becky was upset", "Ill stay away from it", "The pet shop stocks everything"]
return texts[random.randint(0, len(texts)-1)]
+2 -2
View File
@@ -62,7 +62,7 @@ For more info, see [reticulum.network](https://reticulum.network/)
- Total bandwidth cost of setting up an encrypted link is 3 packets totaling 297 bytes
- Low cost of keeping links open at only 0.44 bits per second
## Development Roadmap
## Roadmap
While Reticulum is already a fully featured and functional networking stack, many improvements and additions are actively being worked on, and planned for the future.
To learn more about the direction and future of Reticulum, please see the [Development Roadmap](./Roadmap.md).
@@ -156,7 +156,7 @@ useful.
Currently, the following interfaces are supported:
- Any Ethernet device
- LoRa using [RNode](https://unsigned.io/projects/rnode/)
- LoRa using [RNode](https://unsigned.io/rnode/)
- Packet Radio TNCs (with or without AX.25)
- KISS-compatible hardware and software modems
- Any device with a serial port
+1 -1
View File
@@ -296,7 +296,7 @@ class Destination:
Registers a request handler.
:param path: The path for the request handler to be registered.
:param response_generator: A function or method with the signature *response_generator(path, data, request_id, remote_identity, requested_at)* to be called. Whatever this funcion returns will be sent as a response to the requester. If the function returns ``None``, no response will be sent.
:param response_generator: A function or method with the signature *response_generator(path, data, request_id, link_id, remote_identity, requested_at)* to be called. Whatever this funcion returns will be sent as a response to the requester. If the function returns ``None``, no response will be sent.
:param allow: One of ``RNS.Destination.ALLOW_NONE``, ``RNS.Destination.ALLOW_ALL`` or ``RNS.Destination.ALLOW_LIST``. If ``RNS.Destination.ALLOW_LIST`` is set, the request handler will only respond to requests for identified peers in the supplied list.
:param allowed_list: A list of *bytes-like* :ref:`RNS.Identity<api-identity>` hashes.
:raises: ``ValueError`` if any of the supplied arguments are invalid.
+25 -7
View File
@@ -26,6 +26,7 @@ from RNS.Cryptography import Fernet
from time import sleep
from .vendor import umsgpack as umsgpack
import threading
import inspect
import math
import time
import RNS
@@ -276,6 +277,10 @@ class Link:
self.activated_at = time.time()
RNS.Transport.activate_link(self)
RNS.log("Link "+str(self)+" established with "+str(self.destination)+", RTT is "+str(round(self.rtt, 3))+"s", RNS.LOG_VERBOSE)
if self.rtt != None and self.establishment_cost != None and self.rtt > 0 and self.establishment_cost > 0:
self.establishment_rate = self.establishment_cost/self.rtt
rtt_data = umsgpack.packb(self.rtt)
rtt_packet = RNS.Packet(self, rtt_data, context=RNS.Packet.LRRTT)
rtt_packet.send()
@@ -362,11 +367,6 @@ class Link:
def rtt_packet(self, packet):
try:
# TODO: This is crude, we should use the delta
# to model a more representative per-bit round
# trip time, and use that to set a sensible RTT
# expectancy for the link. This will have to do
# for now though.
measured_rtt = time.time() - self.request_time
plaintext = self.decrypt(packet.data)
rtt = umsgpack.unpackb(plaintext)
@@ -374,13 +374,25 @@ class Link:
self.status = Link.ACTIVE
self.activated_at = time.time()
if self.rtt != None and self.establishment_cost != None and self.rtt > 0 and self.establishment_cost > 0:
self.establishment_rate = self.establishment_cost/self.rtt
if self.owner.callbacks.link_established != None:
self.owner.callbacks.link_established(self)
except Exception as e:
RNS.log("Error occurred while processing RTT packet, tearing down link. The contained exception was: "+str(e), RNS.LOG_ERROR)
self.teardown()
def get_establishment_rate(self):
"""
:returns: The data transfer rate at which the link establishment procedure ocurred, in bits per second.
"""
if self.establishment_rate != None:
return self.establishment_rate*8
else:
return None
def get_salt(self):
return self.link_id
@@ -568,7 +580,13 @@ class Link:
if allowed:
RNS.log("Handling request "+RNS.prettyhexrep(request_id)+" for: "+str(path), RNS.LOG_DEBUG)
response = response_generator(path, request_data, request_id, self.__remote_identity, requested_at)
if len(inspect.signature(response_generator).parameters) == 5:
response = response_generator(path, request_data, request_id, self.__remote_identity, requested_at)
elif len(inspect.signature(response_generator).parameters) == 6:
response = response_generator(path, request_data, request_id, self.link_id, self.__remote_identity, requested_at)
else:
raise TypeError("Invalid signature for response generator callback")
if response != None:
packed_response = umsgpack.packb([request_id, response])
+2 -4
View File
@@ -58,9 +58,7 @@ class Packet:
# Header types
HEADER_1 = 0x00 # Normal header format
HEADER_2 = 0x01 # Header format used for packets in transport
HEADER_3 = 0x02 # Reserved
HEADER_4 = 0x03 # Reserved
header_types = [HEADER_1, HEADER_2, HEADER_3, HEADER_4]
header_types = [HEADER_1, HEADER_2]
# Packet context types
NONE = 0x00 # Generic data packet
@@ -215,7 +213,7 @@ class Packet:
self.flags = self.raw[0]
self.hops = self.raw[1]
self.header_type = (self.flags & 0b11000000) >> 6
self.header_type = (self.flags & 0b01000000) >> 6
self.transport_type = (self.flags & 0b00110000) >> 4
self.destination_type = (self.flags & 0b00001100) >> 2
self.packet_type = (self.flags & 0b00000011)
+50 -5
View File
@@ -584,14 +584,39 @@ class Transport:
try:
if hasattr(interface, "ifac_identity") and interface.ifac_identity != None:
# Calculate packet access code
ifac = interface.ifac_identity.sign(raw)[-interface.ifac_size:]
ifac = interface.ifac_identity.sign(raw)[-interface.ifac_size:]
# Generate mask
mask = RNS.Cryptography.hkdf(
length=len(raw)+interface.ifac_size,
derive_from=ifac,
salt=interface.ifac_key,
context=None,
)
# Set IFAC flag
new_header = bytes([raw[0] | 0x80, raw[1]])
# Assemble new payload with IFAC and send it
# Assemble new payload with IFAC
new_raw = new_header+ifac+raw[2:]
interface.processOutgoing(new_raw)
# Mask payload
i = 0; masked_raw = b""
for byte in new_raw:
if i == 0:
# Mask first header byte, but make sure the
# IFAC flag is still set
masked_raw += bytes([byte ^ mask[i] | 0x80])
elif i == 1 or i > interface.ifac_size+1:
# Mask second header byte and payload
masked_raw += bytes([byte ^ mask[i]])
else:
# Don't mask the IFAC itself
masked_raw += bytes([byte])
i += 1
# Send it
interface.processOutgoing(masked_raw)
else:
interface.processOutgoing(raw)
@@ -905,6 +930,26 @@ class Transport:
# Extract IFAC
ifac = raw[2:2+interface.ifac_size]
# Generate mask
mask = RNS.Cryptography.hkdf(
length=len(raw),
derive_from=ifac,
salt=interface.ifac_key,
context=None,
)
# Unmask payload
i = 0; unmasked_raw = b""
for byte in raw:
if i <= 1 or i > interface.ifac_size+1:
# Unmask header bytes and payload
unmasked_raw += bytes([byte ^ mask[i]])
else:
# Don't unmask IFAC itself
unmasked_raw += bytes([byte])
i += 1
raw = unmasked_raw
# Unset IFAC flag
new_header = bytes([raw[0] & 0x7f, raw[1]])
@@ -1427,12 +1472,12 @@ class Transport:
# Check that the announced destination matches
# the handlers aspect filter
execute_callback = False
announce_identity = RNS.Identity.recall(packet.destination_hash)
if handler.aspect_filter == None:
# If the handlers aspect filter is set to
# None, we execute the callback in all cases
execute_callback = True
else:
announce_identity = RNS.Identity.recall(packet.destination_hash)
handler_expected_hash = RNS.Destination.hash_from_name_and_identity(handler.aspect_filter, announce_identity)
if packet.destination_hash == handler_expected_hash:
execute_callback = True
@@ -2359,4 +2404,4 @@ class Transport:
@staticmethod
def exit_handler():
if not Transport.owner.is_connected_to_shared_instance:
Transport.persist_data()
Transport.persist_data()
+519
View File
@@ -0,0 +1,519 @@
#!/usr/bin/env python3
# MIT License
#
# Copyright (c) 2023 Mark Qvist / unsigned.io
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
import RNS
import argparse
import time
import sys
import os
import base64
from RNS._version import __version__
APP_NAME = "rnid"
SIG_EXT = "rsg"
ENCRYPT_EXT = "rfe"
CHUNK_SIZE = 16*1024*1024
def spin(until=None, msg=None, timeout=None):
i = 0
syms = "⢄⢂⢁⡁⡈⡐⡠"
if timeout != None:
timeout = time.time()+timeout
print(msg+" ", end=" ")
while (timeout == None or time.time()<timeout) and not until():
time.sleep(0.1)
print(("\b\b"+syms[i]+" "), end="")
sys.stdout.flush()
i = (i+1)%len(syms)
print("\r"+" "*len(msg)+" \r", end="")
if timeout != None and time.time() > timeout:
return False
else:
return True
def main():
try:
parser = argparse.ArgumentParser(description="Reticulum Identity & Encryption Utility")
# parser.add_argument("file", nargs="?", default=None, help="input file path", type=str)
parser.add_argument("--config", metavar="path", action="store", default=None, help="path to alternative Reticulum config directory", type=str)
parser.add_argument("-i", "--identity", metavar="identity", action="store", default=None, help="hexadecimal Reticulum Destination hash or path to Identity file", type=str)
parser.add_argument("-g", "--generate", metavar="path", action="store", default=None, help="generate a new Identity")
parser.add_argument("-v", "--verbose", action="count", default=0, help="increase verbosity")
parser.add_argument("-q", "--quiet", action="count", default=0, help="decrease verbosity")
parser.add_argument("-a", "--announce", metavar="aspects", action="store", default=None, help="announce a destination based on this Identity")
parser.add_argument("-H", "--hash", metavar="aspects", action="store", default=None, help="show destination hash5s for other aspects for this Identity")
parser.add_argument("-e", "--encrypt", metavar="path", action="store", default=None, help="encrypt file")
parser.add_argument("-d", "--decrypt", metavar="path", action="store", default=None, help="decrypt file")
parser.add_argument("-s", "--sign", metavar="path", action="store", default=None, help="sign file")
parser.add_argument("-V", "--validate", metavar="path", action="store", default=None, help="validate signature")
parser.add_argument("-r", "--read", metavar="path", action="store", default=None, help="input file path", type=str)
parser.add_argument("-w", "--write", metavar="path", action="store", default=None, help="output file path", type=str)
parser.add_argument("-f", "--force", action="store_true", default=None, help="write output even if it overwrites existing files")
parser.add_argument("-I", "--stdin", action="store_true", default=False, help=argparse.SUPPRESS) # "read input from STDIN instead of file"
parser.add_argument("-O", "--stdout", action="store_true", default=False, help=argparse.SUPPRESS) # help="write output to STDOUT instead of file",
parser.add_argument("-R", "--request", action="store_true", default=False, help="request unknown Identities from the network")
parser.add_argument("-t", action="store", metavar="seconds", type=float, help="identity request timeout before giving up", default=RNS.Transport.PATH_REQUEST_TIMEOUT)
parser.add_argument("-p", "--print-identity", action="store_true", default=False, help="print identity info and exit")
parser.add_argument("-P", "--print-private", action="store_true", default=False, help="allow displaying private keys")
parser.add_argument("-b", "--base64", action="store_true", default=False, help=argparse.SUPPRESS) # help="Use base64-encoded input and output")
parser.add_argument("--version", action="version", version="rncp {version}".format(version=__version__))
args = parser.parse_args()
ops = 0;
for t in [args.encrypt, args.decrypt, args.validate, args.sign]:
if t:
ops += 1
if ops > 1:
RNS.log("This utility currently only supports one of the encrypt, decrypt, sign or verify operations per invocation", RNS.LOG_ERROR)
exit(1)
if not args.read:
if args.encrypt:
args.read = args.encrypt
if args.decrypt:
args.read = args.decrypt
if args.sign:
args.read = args.sign
identity_str = args.identity
if not args.generate and not identity_str:
print("\nNo identity provided, cannot continue\n")
parser.print_help()
print("")
exit(2)
else:
targetloglevel = 4
verbosity = args.verbose
quietness = args.quiet
if verbosity != 0 or quietness != 0:
targetloglevel = targetloglevel+verbosity-quietness
# Start Reticulum
reticulum = RNS.Reticulum(configdir=args.config, loglevel=targetloglevel)
RNS.compact_log_fmt = True
if args.stdout:
RNS.loglevel = -1
if args.generate:
identity = RNS.Identity()
if not args.force and os.path.isfile(args.generate):
RNS.log("Identity file "+str(args.generate)+" already exists. Not overwriting.", RNS.LOG_ERROR)
exit(3)
else:
try:
identity.to_file(args.generate)
RNS.log("New identity written to "+str(args.generate))
exit(0)
except Exception as e:
RNS.log("An error ocurred while saving the generated Identity.", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
exit(4)
identity = None
if len(identity_str) == RNS.Reticulum.TRUNCATED_HASHLENGTH//8*2 and not os.path.isfile(identity_str):
# Try recalling Identity from hex-encoded hash
try:
destination_hash = bytes.fromhex(identity_str)
identity = RNS.Identity.recall(destination_hash)
if identity == None:
if not args.request:
RNS.log("Could not recall Identity for "+RNS.prettyhexrep(destination_hash)+".", RNS.LOG_ERROR)
RNS.log("You can query the network for unknown Identities with the -R option.", RNS.LOG_ERROR)
exit(5)
else:
RNS.Transport.request_path(destination_hash)
def spincheck():
return RNS.Identity.recall(destination_hash) != None
spin(spincheck, "Requesting unknown Identity for "+RNS.prettyhexrep(destination_hash), args.t)
if not spincheck():
RNS.log("Identity request timed out", RNS.LOG_ERROR)
exit(6)
else:
RNS.log("Received Identity "+str(identity)+" for destination "+RNS.prettyhexrep(destination_hash)+" from the network")
identity = RNS.Identity.recall(destination_hash)
else:
RNS.log("Recalled Identity "+str(identity)+" for destination "+RNS.prettyhexrep(destination_hash))
except Exception as e:
RNS.log("Invalid hexadecimal hash provided", RNS.LOG_ERROR)
exit(7)
else:
# Try loading Identity from file
if not os.path.isfile(identity_str):
RNS.log("Specified Identity file not found")
exit(8)
else:
try:
identity = RNS.Identity.from_file(identity_str)
RNS.log("Loaded Identity "+str(identity)+" from "+str(identity_str))
except Exception as e:
RNS.log("Could not decode Identity from specified file")
exit(9)
if identity != None:
if args.hash:
try:
aspects = args.hash.split(".")
if not len(aspects) > 1:
RNS.log("Invalid destination aspects specified", RNS.LOG_ERROR)
exit(32)
else:
app_name = aspects[0]
aspects = aspects[1:]
if identity.pub != None:
destination = RNS.Destination(identity, RNS.Destination.OUT, RNS.Destination.SINGLE, app_name, *aspects)
RNS.log("The "+str(args.hash)+" destination for this Identity is "+RNS.prettyhexrep(destination.hash))
RNS.log("The full destination specifier is "+str(destination))
time.sleep(0.25)
exit(0)
else:
raise KeyError("No public key known")
except Exception as e:
RNS.log("An error ocurred while attempting to send the announce.", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
exit(0)
if args.announce:
try:
aspects = args.announce.split(".")
if not len(aspects) > 1:
RNS.log("Invalid destination aspects specified", RNS.LOG_ERROR)
exit(32)
else:
app_name = aspects[0]
aspects = aspects[1:]
if identity.prv != None:
destination = RNS.Destination(identity, RNS.Destination.IN, RNS.Destination.SINGLE, app_name, *aspects)
RNS.log("Created destination "+str(destination))
RNS.log("Announcing destination "+RNS.prettyhexrep(destination.hash))
destination.announce()
time.sleep(0.25)
exit(0)
else:
destination = RNS.Destination(identity, RNS.Destination.OUT, RNS.Destination.SINGLE, app_name, *aspects)
RNS.log("The "+str(args.announce)+" destination for this Identity is "+RNS.prettyhexrep(destination.hash))
RNS.log("The full destination specifier is "+str(destination))
RNS.log("Cannot announce this destination, since the private key is not held")
time.sleep(0.25)
exit(33)
except Exception as e:
RNS.log("An error ocurred while attempting to send the announce.", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
exit(0)
if args.print_identity:
RNS.log("Public Key : "+RNS.hexrep(identity.pub_bytes, delimit=False))
if identity.prv:
if args.print_private:
RNS.log("Private Key : "+RNS.hexrep(identity.prv_bytes, delimit=False))
else:
RNS.log("Private Key : Hidden")
exit(0)
if args.validate:
if not args.read and args.validate.lower().endswith("."+SIG_EXT):
args.read = str(args.validate).replace("."+SIG_EXT, "")
if not os.path.isfile(args.validate):
RNS.log("Signature file "+str(args.read)+" not found", RNS.LOG_ERROR)
exit(10)
if not os.path.isfile(args.read):
RNS.log("Input file "+str(args.read)+" not found", RNS.LOG_ERROR)
exit(11)
data_input = None
if args.read:
if not os.path.isfile(args.read):
RNS.log("Input file "+str(args.read)+" not found", RNS.LOG_ERROR)
exit(12)
else:
try:
data_input = open(args.read, "rb")
except Exception as e:
RNS.log("Could not open input file for reading", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
exit(13)
# TODO: Actually expand this to a good solution
# probably need to create a wrapper that takes
# into account not closing stdin when done
# elif args.stdin:
# data_input = sys.stdin
data_output = None
if args.encrypt and not args.write and not args.stdout and args.read:
args.write = str(args.read)+"."+ENCRYPT_EXT
if args.decrypt and not args.write and not args.stdout and args.read and args.read.lower().endswith("."+ENCRYPT_EXT):
args.write = str(args.read).replace("."+ENCRYPT_EXT, "")
if args.sign and identity.prv == None:
RNS.log("Specified Identity does not hold a private key. Cannot sign.", RNS.LOG_ERROR)
exit(14)
if args.sign and not args.write and not args.stdout and args.read:
args.write = str(args.read)+"."+SIG_EXT
if args.write:
if not args.force and os.path.isfile(args.write):
RNS.log("Output file "+str(args.write)+" already exists. Not overwriting.", RNS.LOG_ERROR)
exit(15)
else:
try:
data_output = open(args.write, "wb")
except Exception as e:
RNS.log("Could not open output file for writing", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
exit(15)
# TODO: Actually expand this to a good solution
# probably need to create a wrapper that takes
# into account not closing stdout when done
# elif args.stdout:
# data_output = sys.stdout
if args.sign:
if identity.prv == None:
RNS.log("Specified Identity does not hold a private key. Cannot sign.", RNS.LOG_ERROR)
exit(16)
if not data_input:
if not args.stdout:
RNS.log("Signing requested, but no input data specified", RNS.LOG_ERROR)
exit(17)
else:
if not data_output:
if not args.stdout:
RNS.log("Signing requested, but no output specified", RNS.LOG_ERROR)
exit(18)
if not args.stdout:
RNS.log("Signing "+str(args.read))
try:
data_output.write(identity.sign(data_input.read()))
data_output.close()
data_input.close()
if not args.stdout:
if args.read:
RNS.log("File "+str(args.read)+" signed with "+str(identity)+" to "+str(args.write))
exit(0)
except Exception as e:
if not args.stdout:
RNS.log("An error ocurred while encrypting data.", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
try:
data_output.close()
except:
pass
try:
data_input.close()
except:
pass
exit(19)
if args.validate:
if not data_input:
if not args.stdout:
RNS.log("Signature verification requested, but no input data specified", RNS.LOG_ERROR)
exit(20)
else:
# if not args.stdout:
# RNS.log("Verifying "+str(args.validate)+" for "+str(args.read))
try:
try:
sig_input = open(args.validate, "rb")
except Exception as e:
RNS.log("An error ocurred while opening "+str(args.validate)+".", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
exit(21)
validated = identity.validate(sig_input.read(), data_input.read())
sig_input.close()
data_input.close()
if not validated:
if not args.stdout:
RNS.log("Signature "+str(args.validate)+" for file "+str(args.read)+" is invalid", RNS.LOG_ERROR)
exit(22)
else:
if not args.stdout:
RNS.log("Signature "+str(args.validate)+" for file "+str(args.read)+" made by Identity "+str(identity)+" is valid")
exit(0)
except Exception as e:
if not args.stdout:
RNS.log("An error ocurred while validating signature.", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
try:
data_output.close()
except:
pass
try:
data_input.close()
except:
pass
exit(23)
if args.encrypt:
if not data_input:
if not args.stdout:
RNS.log("Encryption requested, but no input data specified", RNS.LOG_ERROR)
exit(24)
else:
if not data_output:
if not args.stdout:
RNS.log("Encryption requested, but no output specified", RNS.LOG_ERROR)
exit(25)
if not args.stdout:
RNS.log("Encrypting "+str(args.read))
try:
more_data = True
while more_data:
chunk = data_input.read(CHUNK_SIZE)
if chunk:
data_output.write(identity.encrypt(chunk))
else:
more_data = False
data_output.close()
data_input.close()
if not args.stdout:
if args.read:
RNS.log("File "+str(args.read)+" encrypted for "+str(identity)+" to "+str(args.write))
exit(0)
except Exception as e:
if not args.stdout:
RNS.log("An error ocurred while encrypting data.", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
try:
data_output.close()
except:
pass
try:
data_input.close()
except:
pass
exit(26)
if args.decrypt:
if identity.prv == None:
RNS.log("Specified Identity does not hold a private key. Cannot decrypt.", RNS.LOG_ERROR)
exit(27)
if not data_input:
if not args.stdout:
RNS.log("Decryption requested, but no input data specified", RNS.LOG_ERROR)
exit(28)
else:
if not data_output:
if not args.stdout:
RNS.log("Decryption requested, but no output specified", RNS.LOG_ERROR)
exit(29)
if not args.stdout:
RNS.log("Decrypting "+str(args.read)+"...")
try:
more_data = True
while more_data:
chunk = data_input.read(CHUNK_SIZE)
if chunk:
plaintext = identity.decrypt(chunk)
if plaintext == None:
if not args.stdout:
RNS.log("Data could not be decrypted with the specified Identity")
exit(30)
else:
data_output.write(plaintext)
else:
more_data = False
data_output.close()
data_input.close()
if not args.stdout:
if args.read:
RNS.log("File "+str(args.read)+" decrypted with "+str(identity)+" to "+str(args.write))
exit(0)
except Exception as e:
if not args.stdout:
RNS.log("An error ocurred while decrypting data.", RNS.LOG_ERROR)
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
try:
data_output.close()
except:
pass
try:
data_input.close()
except:
pass
exit(31)
if True:
pass
elif False:
pass
else:
print("")
parser.print_help()
print("")
except KeyboardInterrupt:
print("")
exit(255)
if __name__ == "__main__":
main()
+45 -4
View File
@@ -78,6 +78,7 @@ class KISS():
CMD_BLINK = 0x30
CMD_RANDOM = 0x40
CMD_BT_CTRL = 0x46
CMD_BT_PIN = 0x62
CMD_BOARD = 0x47
CMD_PLATFORM = 0x48
CMD_MCU = 0x49
@@ -386,6 +387,21 @@ class RNode():
RNS.log("Radio reporting bandwidth is "+str(self.r_bandwidth/1000.0)+" KHz")
self.updateBitrate()
elif (command == KISS.CMD_BT_PIN):
if (byte == KISS.FESC):
escape = True
else:
if (escape):
if (byte == KISS.TFEND):
byte = KISS.FEND
if (byte == KISS.TFESC):
byte = KISS.FESC
escape = False
command_buffer = command_buffer+bytes([byte])
if (len(command_buffer) == 4):
self.r_bt_pin = command_buffer[0] << 24 | command_buffer[1] << 16 | command_buffer[2] << 8 | command_buffer[3]
RNS.log("Bluetooth pairing PIN is: {:06d}".format(self.r_bt_pin))
elif (command == KISS.CMD_DEV_HASH):
if (byte == KISS.FESC):
escape = True
@@ -865,6 +881,7 @@ class RNode():
selected_version = None
selected_hash = None
firmware_version_url = "https://unsigned.io/firmware/latest/?v="+program_version+"&variant="
fallback_firmware_version_url = "https://github.com/markqvist/rnode_firmware/releases/latest/download/release.json"
def ensure_firmware_file(fw_filename):
global selected_version, selected_hash, upd_nocheck
if fw_filename == "extracted_rnode_firmware.zip":
@@ -903,7 +920,30 @@ def ensure_firmware_file(fw_filename):
if selected_version == None:
if not upd_nocheck:
try:
urlretrieve(firmware_version_url+fw_filename, UPD_DIR+"/"+fw_filename+".version.latest")
try:
urlretrieve(firmware_version_url+fw_filename, UPD_DIR+"/"+fw_filename+".version.latest")
except Exception as e:
RNS.log("")
RNS.log("WARNING!")
RNS.log("Failed to retrieve latest version information for your board from the default server")
RNS.log("Will retry using the following fallback URL: "+fallback_firmware_version_url)
RNS.log("")
RNS.log("Hit enter if you want to proceed")
input()
try:
urlretrieve(fallback_firmware_version_url, UPD_DIR+"/fallback_release_info.json")
import json
with open(UPD_DIR+"/fallback_release_info.json", "rb") as rif:
rdat = json.loads(rif.read())
variant = rdat[fw_filename]
with open(UPD_DIR+"/"+fw_filename+".version.latest", "wb") as verf:
inf_str = str(variant["version"])+" "+str(variant["hash"])
verf.write(inf_str.encode("utf-8"))
except Exception as e:
RNS.log("Error while trying fallback URL: "+str(e))
raise e
except Exception as e:
RNS.log("Failed to retrive latest version information for your board.")
RNS.log("Check your internet connection and try again.")
@@ -1347,8 +1387,8 @@ def main():
print(" / \\ Select this option if you have put toghether an RNode")
print(" | of your own design, or if you are prototyping one.")
print("")
print("[3] LilyGO LoRa32 v2.1 (aka T3 v1.6.1)")
print("[4] LilyGO LoRa32 v2.0 (aka T3 v1.6)")
print("[3] LilyGO LoRa32 v2.1 (aka T3 v1.6 / T3 v1.6.1)")
print("[4] LilyGO LoRa32 v2.0")
print("[5] LilyGO T-Beam")
print("[6] Heltec LoRa32 v2")
print(" .")
@@ -2481,8 +2521,9 @@ def main():
rnode.leave()
if args.bluetooth_pair:
RNS.log("Putting device into Bluetooth pairing mode...")
RNS.log("Putting device into Bluetooth pairing mode. Press enter to exit when done.")
rnode.bluetooth_pair()
input()
rnode.leave()
if args.info:
+15 -2
View File
@@ -46,7 +46,7 @@ def size_str(num, suffix='B'):
return "%.2f%s%s" % (num, last_unit, suffix)
def program_setup(configdir, dispall=False, verbosity=0, name_filter=None):
def program_setup(configdir, dispall=False, verbosity=0, name_filter=None,json=False):
reticulum = RNS.Reticulum(configdir = configdir, loglevel = 3+verbosity)
stats = None
@@ -56,6 +56,11 @@ def program_setup(configdir, dispall=False, verbosity=0, name_filter=None):
pass
if stats != None:
if json:
import json
print(json.dumps(stats))
exit()
for ifstat in stats["interfaces"]:
name = ifstat["name"]
@@ -175,6 +180,14 @@ def main():
help="show all interfaces",
default=False
)
parser.add_argument(
"-j",
"--json",
action="store_true",
help="output in JSON format",
default=False
)
parser.add_argument('-v', '--verbose', action='count', default=0)
@@ -187,7 +200,7 @@ def main():
else:
configarg = None
program_setup(configdir = configarg, dispall = args.all, verbosity=args.verbose, name_filter=args.filter)
program_setup(configdir = configarg, dispall = args.all, verbosity=args.verbose, name_filter=args.filter, json=args.json)
except KeyboardInterrupt:
print("")
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.4.7"
__version__ = "0.4.9"
+8 -8
View File
@@ -18,20 +18,19 @@ For each release cycle of Reticulum, improvements and additions from the five [P
- [x] Improve storage persist call on local client connect/disconnect
- [x] Better path invalidation on roaming interfaces
- [x] Improved roaming support on Android
- [x] Add bluetooth pairing code output to rnodeconf
- [x] Add `rnid` utility with encryption, signing and Identity funcionality
- [x] JSON output mode for rnstatus
- [ ] Add automatic retries to all use cases of the `Request` API
- [ ] Updating the documentation to reflect recent changes and improvements
- [ ] Add bluetooth pairing code output to rnodeconf
- [ ] Transit traffic display in rnstatus
- [ ] JSON output mode for rnstatus
- [ ] Add `rnid` utility
- [ ] Add `rnsign` utility
- [ ] Add `rncrypt` utility
- [ ] Create a standalone RNS Daemon app for Android
- Targets for related applications
- [x] Add offline & paper message transport to LXMF
- [x] Implement paper messaging in Nomad Network
- [x] Implement paper messaging in Sideband
- [x] Add spatial and multi-interface roaming support in Sideband
- [x] Expand device support in Sideband to support older Android devices
- [x] And input fields, data submission and dynamic request links to Nomad Network
- [x] Add bandwidth-based weighting to LXMF propagation node sync peer prioritisation
## Primary Efforts
The development path for Reticulum is currently laid out in five distinct areas: *Comprehensibility*, *Universality*, *Functionality*, *Usability & Utility* and *Interfaceability*. Conceptualising the development of Reticulum into these areas serves to advance the implementation and work towards the Foundational Goals & Values of Reticulum.
@@ -78,6 +77,7 @@ These efforts seek to broaden the universality of the Reticulum software and har
These efforts aim to expand and improve the core functionality and reliability of Reticulum.
- Improve storage persist call on local client connect/disconnect
- Add automatic retries to all use cases of the `Request` API
- Faster path invalidation on physical topography changes
- Better path invalidation on roaming interfaces
- Add a `Buffer` class to the API, for handling stream-like buffers over Reticulum
@@ -126,7 +126,7 @@ The Reticulum ecosystem is enriched by several other software and hardware proje
This section lists, in no particular order, various important efforts that would be beneficial to the goals of Reticulum.
- The [RNode](https://unsigned.io/rnode/) project
- [ ] Evolve RNode into a self-replicating system, so that anyone can use an existing RNode to create more RNodes, and bootstrap functional networks based on Reticulum, even in absence of the Internet.
- [x] Evolve RNode into a self-replicating system, so that anyone can use an existing RNode to create more RNodes, and bootstrap functional networks based on Reticulum, even in absence of the Internet.
- [ ] Create a WebUSB-based bootstrapping utility, and integrate this directly into the [RNode Bootstrap Console](#), both on-device, and on an Internet-reachable copy. This will make it much easier to create new RNodes for average users.
## Release History
Binary file not shown.
+1 -1
View File
@@ -1,4 +1,4 @@
# Sphinx build info version 1
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
config: afc56b8a3660cd0f3eeb6ca077eaba56
config: 9738e36d7743271d1e6118c152b32349
tags: 645f666f9bcd5a90fca523b33c5a78b7
+4
View File
@@ -0,0 +1,4 @@
********************************************
An Explanation of Reticulum for Human Beings
********************************************
@@ -115,8 +115,8 @@ Creating a Network With Reticulum
=============================================
To create a network, you will need to specify one or more *interfaces* for
Reticulum to use. This is done in the Reticulum configuration file, which by
default is located at ``~/.reticulum/config``. You can edit this file by hand,
or use the interactive ``rnsconfig`` utility.
default is located at ``~/.reticulum/config``. You can get an example
configuration file with all options via ``rnsd --exampleconfig``.
When Reticulum is started for the first time, it will create a default
configuration file, with one active interface. This default interface uses
@@ -197,7 +197,7 @@ by adding one of the following interfaces to your ``.reticulum/config`` file:
target_port = 4965
# TCP/IP interface to the Frankfurt hub
[[RNS Testnet Dublin]]
[[RNS Testnet Frankfurt]]
type = TCPClientInterface
enabled = yes
target_host = frankfurt.connect.reticulum.network
@@ -234,7 +234,7 @@ chapter for a guide. If you prefer purchasing a ready-made unit, you can refer t
refer to these additional external resources:
* `How To Make Your Own RNodes <https://unsigned.io/how-to-make-your-own-rnodes/>`_
* `Installing RNode Firmware on Compatible LoRa Devices <https://unsigned.io/installing-rnode-firmware-on-t-beam-and-lora32-devices/>`_
* `Installing RNode Firmware on Compatible LoRa Devices <https://unsigned.io/installing-rnode-firmware-on-supported-devices/>`_
* `Private, Secure and Uncensorable Messaging Over a LoRa Mesh <https://unsigned.io/private-messaging-over-lora/>`_
* `RNode Firmware <https://github.com/markqvist/RNode_Firmware/>`_
+11 -11
View File
@@ -107,13 +107,13 @@ guide the design of Reticulum:
Introduction & Basic Functionality
==================================
Reticulum is a networking stack suited for high-latency, low-bandwidth links. Reticulum is at its
Reticulum is a networking stack suited for high-latency, low-bandwidth links. Reticulum is at its
core a *message oriented* system. It is suited for both local point-to-point or point-to-multipoint
scenarios where all nodes are within range of each other, as well as scenarios where packets need
to be transported over multiple hops in a complex network to reach the recipient.
Reticulum does away with the idea of addresses and ports known from IP, TCP and UDP. Instead
Reticulum uses the singular concept of *destinations*. Any application using Reticulum as its
Reticulum uses the singular concept of *destinations*. Any application using Reticulum as its
networking stack will need to create one or more destinations to receive data, and know the
destinations it needs to send data to.
@@ -220,7 +220,7 @@ packet.
In actual use of *single* destination naming, it is advisable not to use any uniquely identifying
features in aspect naming. Aspect names should be general terms describing what kind of destination
is represented. The uniquely identifying aspect is always achieved by the appending the public key,
is represented. The uniquely identifying aspect is always achieved by appending the public key,
which expands the destination into a uniquely identifiable one. Reticulum does this automatically.
Any destination on a Reticulum network can be addressed and reached simply by knowing its
@@ -239,7 +239,7 @@ To recap, the different destination types should be used in the following situat
* **Plain**
When plain-text communication is desirable, for example when broadcasting information, or for local discovery purposes.
To communicate with a *single* destination, you need to know its public key. Any method for
To communicate with a *single* destination, you need to know its public key. Any method for
obtaining the public key is valid, but Reticulum includes a simple mechanism for making other
nodes aware of your destinations public key, called the *announce*. It is also possible to request
an unknown public key from the network, as all transport instances serve as a distributed ledger
@@ -287,7 +287,7 @@ In Reticulum, destinations are allowed to move around the network at will. This
protocols such as IP, where an address is always expected to stay within the network segment it was assigned in.
This limitation does not exist in Reticulum, and any destination is *completely portable* over the entire topography
of the network, and *can even be moved to other Reticulum networks* than the one it was created in, and
still become reachable. To update it's reachability, a destination simply needs to send an announce on any
still become reachable. To update its reachability, a destination simply needs to send an announce on any
networks it is part of. After a short while, it will be globally reachable in the network.
Seeing how *single* destinations are always tied to a private/public key pair leads us to the next topic.
@@ -368,7 +368,7 @@ If it is a *Transport Node*, it should be given the configuration directive ``en
The Announce Mechanism in Detail
--------------------------------
When an *announce* for a destination is transmitted by from a Reticulum instance, it will be forwarded by
When an *announce* for a destination is transmitted by a Reticulum instance, it will be forwarded by
any transport node receiving it, but according to some specific rules:
@@ -385,7 +385,7 @@ any transport node receiving it, but according to some specific rules:
announces is set at 2%, but can be configured on a per-interface basis.
* | If any given interface does not have enough bandwidth available for retransmitting the announce,
the announce will be assigned a priority inversely proportional to it's hop count, and be inserted
the announce will be assigned a priority inversely proportional to its hop count, and be inserted
into a queue managed by the interface.
* | When the interface has bandwidth available for processing an announce, it will prioritise announces
@@ -431,7 +431,7 @@ For exchanges of small amounts of information, Reticulum offers the *Packet* API
* | A packet is always created with an associated destination and some payload data. When the packet is sent
to a *single* destination type, Reticulum will automatically create an ephemeral encryption key, perform
an ECDH key exchange with the destinations public key, and encrypt the information.
an ECDH key exchange with the destination's public key, and encrypt the information.
* | It is important to note that this key exchange does not require any network traffic. The sender already
knows the public key of the destination from an earlier received *announce*, and can thus perform the ECDH
@@ -447,8 +447,8 @@ For exchanges of small amounts of information, Reticulum offers the *Packet* API
* | Once the packet has been received and decrypted by the addressed destination, that destination can opt
to *prove* its receipt of the packet. It does this by calculating the SHA-256 hash of the received packet,
and signing this hash with it's Ed25519 signing key. Transport nodes in the network can then direct this
*proof* back to the packets origin, where the signature can be verified against the destinations known
and signing this hash with its Ed25519 signing key. Transport nodes in the network can then direct this
*proof* back to the packets origin, where the signature can be verified against the destination's known
public signing key.
* | In case the packet is addressed to a *group* destination type, the packet will be encrypted with the
@@ -465,7 +465,7 @@ For exchanges of larger amounts of data, or when longer sessions of bidirectiona
forward the packet will take note of this *link request*.
* | Second, if the destination accepts the *link request* , it will send back a packet that proves the
authenticity of its identity (and the receipt of the link request) to the initiating node. All
authenticity of its identity (and the receipt of the link request) to the initiating node. All
nodes that initially forwarded the packet will also be able to verify this proof, and thus
accept the validity of the *link* throughout the network.
+2 -2
View File
@@ -377,7 +377,7 @@ output.
# Run rnx on the listening system, specifying which identities
# are allowed to execute commands
rncp --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
rnx --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
# From another system, run a command
rnx 7a55144adf826958a9529a3bcf08b149 "cat /proc/cpuinfo"
@@ -565,4 +565,4 @@ If you want to automatically start ``rnsd`` at boot, run:
.. code:: text
sudo systemctl enable rnsd
sudo systemctl enable rnsd
+2 -2
View File
@@ -162,7 +162,7 @@ Caveat Emptor
==============
Reticulum is an experimental networking stack, 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
mind, it has not yet been externally security audited, and there could very well be
privacy-breaking bugs. To be considered secure, Reticulum needs a thorough
security review by independent cryptographers and security researchers. If you
want to help out, or help sponsor an audit, please do get in touch.
want to help out with this, or can help sponsor an audit, please do get in touch.
+1 -1
View File
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.4.7 beta',
VERSION: '0.4.9 beta',
LANGUAGE: 'en',
COLLAPSE_INDEX: false,
BUILDER: 'html',
+5 -5
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Support Reticulum" href="support.html" /><link rel="prev" title="Building Networks" href="networks.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>Code Examples - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>Code Examples - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@@ -1632,8 +1632,8 @@ the link has been established.</p>
<span class="c1"># A reference to the latest client link that connected</span>
<span class="n">latest_client_link</span> <span class="o">=</span> <span class="kc">None</span>
<span class="k">def</span> <span class="nf">random_text_generator</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">request_id</span><span class="p">,</span> <span class="n">remote_identity</span><span class="p">,</span> <span class="n">requested_at</span><span class="p">):</span>
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">&quot;Generating response to request &quot;</span><span class="o">+</span><span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">request_id</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">random_text_generator</span><span class="p">(</span><span class="n">path</span><span class="p">,</span> <span class="n">data</span><span class="p">,</span> <span class="n">request_id</span><span class="p">,</span> <span class="n">link_id</span><span class="p">,</span> <span class="n">remote_identity</span><span class="p">,</span> <span class="n">requested_at</span><span class="p">):</span>
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">&quot;Generating response to request &quot;</span><span class="o">+</span><span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">request_id</span><span class="p">)</span><span class="o">+</span><span class="s2">&quot; on link &quot;</span><span class="o">+</span><span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">link_id</span><span class="p">))</span>
<span class="n">texts</span> <span class="o">=</span> <span class="p">[</span><span class="s2">&quot;They looked up&quot;</span><span class="p">,</span> <span class="s2">&quot;On each full moon&quot;</span><span class="p">,</span> <span class="s2">&quot;Becky was upset&quot;</span><span class="p">,</span> <span class="s2">&quot;Ill stay away from it&quot;</span><span class="p">,</span> <span class="s2">&quot;The pet shop stocks everything&quot;</span><span class="p">]</span>
<span class="k">return</span> <span class="n">texts</span><span class="p">[</span><span class="n">random</span><span class="o">.</span><span class="n">randint</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="nb">len</span><span class="p">(</span><span class="n">texts</span><span class="p">)</span><span class="o">-</span><span class="mi">1</span><span class="p">)]</span>
+270
View File
@@ -0,0 +1,270 @@
<!doctype html>
<html class="no-js" lang="en">
<head><meta charset="utf-8"/>
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><meta name="generator" content="Docutils 0.17.1: http://docutils.sourceforge.net/" />
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>An Explanation of Reticulum for Human Beings - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
<link rel="stylesheet" type="text/css" href="_static/custom.css" />
<style>
body {
--color-code-background: #f8f8f8;
--color-code-foreground: black;
}
@media not print {
body[data-theme="dark"] {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
--color-background-primary: #202b38;
--color-background-secondary: #161f27;
--color-foreground-primary: #dbdbdb;
--color-foreground-secondary: #a9b1ba;
--color-brand-primary: #41adff;
--color-background-hover: #161f27;
--color-api-name: #ffbe85;
--color-api-pre-name: #efae75;
}
@media (prefers-color-scheme: dark) {
body:not([data-theme="light"]) {
--color-code-background: #202020;
--color-code-foreground: #d0d0d0;
--color-background-primary: #202b38;
--color-background-secondary: #161f27;
--color-foreground-primary: #dbdbdb;
--color-foreground-secondary: #a9b1ba;
--color-brand-primary: #41adff;
--color-background-hover: #161f27;
--color-api-name: #ffbe85;
--color-api-pre-name: #efae75;
}
}
}
</style></head>
<body>
<script>
document.body.dataset.theme = localStorage.getItem("theme") || "auto";
</script>
<svg xmlns="http://www.w3.org/2000/svg" style="display: none;">
<symbol id="svg-toc" viewBox="0 0 24 24">
<title>Contents</title>
<svg stroke="currentColor" fill="currentColor" stroke-width="0" viewBox="0 0 1024 1024">
<path d="M408 442h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8zm-8 204c0 4.4 3.6 8 8 8h480c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8H408c-4.4 0-8 3.6-8 8v56zm504-486H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zm0 632H120c-4.4 0-8 3.6-8 8v56c0 4.4 3.6 8 8 8h784c4.4 0 8-3.6 8-8v-56c0-4.4-3.6-8-8-8zM115.4 518.9L271.7 642c5.8 4.6 14.4.5 14.4-6.9V388.9c0-7.4-8.5-11.5-14.4-6.9L115.4 505.1a8.74 8.74 0 0 0 0 13.8z"/>
</svg>
</symbol>
<symbol id="svg-menu" viewBox="0 0 24 24">
<title>Menu</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-menu">
<line x1="3" y1="12" x2="21" y2="12"></line>
<line x1="3" y1="6" x2="21" y2="6"></line>
<line x1="3" y1="18" x2="21" y2="18"></line>
</svg>
</symbol>
<symbol id="svg-arrow-right" viewBox="0 0 24 24">
<title>Expand</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather-chevron-right">
<polyline points="9 18 15 12 9 6"></polyline>
</svg>
</symbol>
<symbol id="svg-sun" viewBox="0 0 24 24">
<title>Light mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="feather-sun">
<circle cx="12" cy="12" r="5"></circle>
<line x1="12" y1="1" x2="12" y2="3"></line>
<line x1="12" y1="21" x2="12" y2="23"></line>
<line x1="4.22" y1="4.22" x2="5.64" y2="5.64"></line>
<line x1="18.36" y1="18.36" x2="19.78" y2="19.78"></line>
<line x1="1" y1="12" x2="3" y2="12"></line>
<line x1="21" y1="12" x2="23" y2="12"></line>
<line x1="4.22" y1="19.78" x2="5.64" y2="18.36"></line>
<line x1="18.36" y1="5.64" x2="19.78" y2="4.22"></line>
</svg>
</symbol>
<symbol id="svg-moon" viewBox="0 0 24 24">
<title>Dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-moon">
<path stroke="none" d="M0 0h24v24H0z" fill="none" />
<path d="M12 3c.132 0 .263 0 .393 0a7.5 7.5 0 0 0 7.92 12.446a9 9 0 1 1 -8.313 -12.454z" />
</svg>
</symbol>
<symbol id="svg-sun-half" viewBox="0 0 24 24">
<title>Auto light/dark mode</title>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" stroke="currentColor"
stroke-width="1.5" stroke-linecap="round" stroke-linejoin="round" class="icon-tabler-shadow">
<path stroke="none" d="M0 0h24v24H0z" fill="none"/>
<circle cx="12" cy="12" r="9" />
<path d="M13 12h5" />
<path d="M13 15h4" />
<path d="M13 18h1" />
<path d="M13 9h4" />
<path d="M13 6h1" />
</svg>
</symbol>
</svg>
<input type="checkbox" class="sidebar-toggle" name="__navigation" id="__navigation">
<input type="checkbox" class="sidebar-toggle" name="__toc" id="__toc">
<label class="overlay sidebar-overlay" for="__navigation">
<div class="visually-hidden">Hide navigation sidebar</div>
</label>
<label class="overlay toc-overlay" for="__toc">
<div class="visually-hidden">Hide table of contents sidebar</div>
</label>
<div class="page">
<header class="mobile-header">
<div class="header-left">
<label class="nav-overlay-icon" for="__navigation">
<div class="visually-hidden">Toggle site navigation sidebar</div>
<i class="icon"><svg><use href="#svg-menu"></use></svg></i>
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
<button class="theme-toggle">
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-header-icon no-toc" for="__toc">
<div class="visually-hidden">Toggle table of contents sidebar</div>
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
</label>
</div>
</header>
<aside class="sidebar-drawer">
<div class="sidebar-container">
<div class="sidebar-sticky"><a class="sidebar-brand centered" href="index.html">
<div class="sidebar-logo-container">
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
<input type="hidden" name="check_keywords" value="yes">
<input type="hidden" name="area" value="default">
</form>
<div id="searchbox"></div><div class="sidebar-scroll"><div class="sidebar-tree">
<ul>
<li class="toctree-l1"><a class="reference internal" href="whatis.html">What is Reticulum?</a></li>
<li class="toctree-l1"><a class="reference internal" href="gettingstartedfast.html">Getting Started Fast</a></li>
<li class="toctree-l1"><a class="reference internal" href="using.html">Using Reticulum on Your System</a></li>
<li class="toctree-l1"><a class="reference internal" href="understanding.html">Understanding Reticulum</a></li>
<li class="toctree-l1"><a class="reference internal" href="hardware.html">Communications Hardware</a></li>
<li class="toctree-l1"><a class="reference internal" href="interfaces.html">Supported Interfaces</a></li>
<li class="toctree-l1"><a class="reference internal" href="networks.html">Building Networks</a></li>
<li class="toctree-l1"><a class="reference internal" href="examples.html">Code Examples</a></li>
<li class="toctree-l1"><a class="reference internal" href="support.html">Support Reticulum</a></li>
</ul>
<ul>
<li class="toctree-l1"><a class="reference internal" href="reference.html">API Reference</a></li>
</ul>
</div>
</div>
</div>
</div>
</aside>
<div class="main">
<div class="content">
<div class="article-container">
<a href="#" class="back-to-top muted-link">
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8v12z"></path>
</svg>
<span>Back to top</span>
</a>
<div class="content-icon-container">
<div class="theme-toggle-container theme-toggle-content">
<button class="theme-toggle">
<div class="visually-hidden">Toggle Light / Dark / Auto color theme</div>
<svg class="theme-icon-when-auto"><use href="#svg-sun-half"></use></svg>
<svg class="theme-icon-when-dark"><use href="#svg-moon"></use></svg>
<svg class="theme-icon-when-light"><use href="#svg-sun"></use></svg>
</button>
</div>
<label class="toc-overlay-icon toc-content-icon no-toc" for="__toc">
<div class="visually-hidden">Toggle table of contents sidebar</div>
<i class="icon"><svg><use href="#svg-toc"></use></svg></i>
</label>
</div>
<article role="main">
<section id="an-explanation-of-reticulum-for-human-beings">
<h1>An Explanation of Reticulum for Human Beings<a class="headerlink" href="#an-explanation-of-reticulum-for-human-beings" title="Permalink to this heading">#</a></h1>
</section>
</article>
</div>
<footer>
<div class="related-pages">
</div>
<div class="bottom-of-page">
<div class="left-details">
<div class="copyright">
Copyright &#169; 2022, Mark Qvist
</div>
Generated with <a href="https://www.sphinx-doc.org/">Sphinx</a> and
<a href="https://github.com/pradyunsg/furo">Furo</a>
</div>
<div class="right-details">
<div class="icons">
</div>
</div>
</div>
</footer>
</div>
<aside class="toc-drawer no-toc">
</aside>
</div>
</div><script data-url_root="./" id="documentation_options" src="_static/documentation_options.js"></script>
<script src="_static/jquery.js"></script>
<script src="_static/underscore.js"></script>
<script src="_static/_sphinx_javascript_frameworks_compat.js"></script>
<script src="_static/doctools.js"></script>
<script src="_static/sphinx_highlight.js"></script>
<script src="_static/scripts/furo.js"></script>
<script src="_static/clipboard.min.js"></script>
<script src="_static/copybutton.js"></script>
</body>
</html>
+7 -5
View File
@@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="#" /><link rel="search" title="Search" href="search.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/><title>Index - Reticulum Network Stack 0.4.7 beta documentation</title>
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/><title>Index - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -139,7 +139,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -165,7 +165,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@@ -331,6 +331,8 @@
<table style="width: 100%" class="indextable genindextable"><tr>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Resource.get_data_size">get_data_size() (RNS.Resource method)</a>
</li>
<li><a href="reference.html#RNS.Link.get_establishment_rate">get_establishment_rate() (RNS.Link method)</a>
</li>
<li><a href="reference.html#RNS.Resource.get_hash">get_hash() (RNS.Resource method)</a>
</li>
@@ -349,11 +351,11 @@
</li>
</ul></li>
<li><a href="reference.html#RNS.Identity.get_public_key">get_public_key() (RNS.Identity method)</a>
</li>
<li><a href="reference.html#RNS.Identity.get_random_hash">get_random_hash() (RNS.Identity static method)</a>
</li>
</ul></td>
<td style="width: 33%; vertical-align: top;"><ul>
<li><a href="reference.html#RNS.Identity.get_random_hash">get_random_hash() (RNS.Identity static method)</a>
</li>
<li><a href="reference.html#RNS.Link.get_remote_identity">get_remote_identity() (RNS.Link method)</a>
</li>
<li><a href="reference.html#RNS.RequestReceipt.get_request_id">get_request_id() (RNS.RequestReceipt method)</a>
+7 -7
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Using Reticulum on Your System" href="using.html" /><link rel="prev" title="What is Reticulum?" href="whatis.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>Getting Started Fast - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>Getting Started Fast - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@@ -304,8 +304,8 @@ network status and connectivity.</p>
<h2>Creating a Network With Reticulum<a class="headerlink" href="#creating-a-network-with-reticulum" title="Permalink to this heading">#</a></h2>
<p>To create a network, you will need to specify one or more <em>interfaces</em> for
Reticulum to use. This is done in the Reticulum configuration file, which by
default is located at <code class="docutils literal notranslate"><span class="pre">~/.reticulum/config</span></code>. You can edit this file by hand,
or use the interactive <code class="docutils literal notranslate"><span class="pre">rnsconfig</span></code> utility.</p>
default is located at <code class="docutils literal notranslate"><span class="pre">~/.reticulum/config</span></code>. You can get an example
configuration file with all options via <code class="docutils literal notranslate"><span class="pre">rnsd</span> <span class="pre">--exampleconfig</span></code>.</p>
<p>When Reticulum is started for the first time, it will create a default
configuration file, with one active interface. This default interface uses
your existing Ethernet and WiFi networks (if any), and only allows you to
@@ -369,7 +369,7 @@ by adding one of the following interfaces to your <code class="docutils literal
<span class="n">target_port</span> <span class="o">=</span> <span class="mi">4965</span>
<span class="c1"># TCP/IP interface to the Frankfurt hub</span>
<span class="p">[[</span><span class="n">RNS</span> <span class="n">Testnet</span> <span class="n">Dublin</span><span class="p">]]</span>
<span class="p">[[</span><span class="n">RNS</span> <span class="n">Testnet</span> <span class="n">Frankfurt</span><span class="p">]]</span>
<span class="nb">type</span> <span class="o">=</span> <span class="n">TCPClientInterface</span>
<span class="n">enabled</span> <span class="o">=</span> <span class="n">yes</span>
<span class="n">target_host</span> <span class="o">=</span> <span class="n">frankfurt</span><span class="o">.</span><span class="n">connect</span><span class="o">.</span><span class="n">reticulum</span><span class="o">.</span><span class="n">network</span>
@@ -404,7 +404,7 @@ chapter for a guide. If you prefer purchasing a ready-made unit, you can refer t
refer to these additional external resources:</p>
<ul class="simple">
<li><p><a class="reference external" href="https://unsigned.io/how-to-make-your-own-rnodes/">How To Make Your Own RNodes</a></p></li>
<li><p><a class="reference external" href="https://unsigned.io/installing-rnode-firmware-on-t-beam-and-lora32-devices/">Installing RNode Firmware on Compatible LoRa Devices</a></p></li>
<li><p><a class="reference external" href="https://unsigned.io/installing-rnode-firmware-on-supported-devices/">Installing RNode Firmware on Compatible LoRa Devices</a></p></li>
<li><p><a class="reference external" href="https://unsigned.io/private-messaging-over-lora/">Private, Secure and Uncensorable Messaging Over a LoRa Mesh</a></p></li>
<li><p><a class="reference external" href="https://github.com/markqvist/RNode_Firmware/">RNode Firmware</a></p></li>
</ul>
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Supported Interfaces" href="interfaces.html" /><link rel="prev" title="Understanding Reticulum" href="understanding.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>Communications Hardware - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>Communications Hardware - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="What is Reticulum?" href="whatis.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>Reticulum Network Stack 0.4.7 beta documentation</title>
<title>Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="#"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="#"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Building Networks" href="networks.html" /><link rel="prev" title="Communications Hardware" href="hardware.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>Supported Interfaces - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>Supported Interfaces - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Code Examples" href="examples.html" /><link rel="prev" title="Supported Interfaces" href="interfaces.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>Building Networks - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>Building Networks - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
Binary file not shown.
+15 -4
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="prev" title="Support Reticulum" href="support.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>API Reference - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>API Reference - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@@ -720,7 +720,7 @@ proofs should be returned for received packets.</p>
<dt class="field-odd">Parameters</dt>
<dd class="field-odd"><ul class="simple">
<li><p><strong>path</strong> The path for the request handler to be registered.</p></li>
<li><p><strong>response_generator</strong> A function or method with the signature <em>response_generator(path, data, request_id, remote_identity, requested_at)</em> to be called. Whatever this funcion returns will be sent as a response to the requester. If the function returns <code class="docutils literal notranslate"><span class="pre">None</span></code>, no response will be sent.</p></li>
<li><p><strong>response_generator</strong> A function or method with the signature <em>response_generator(path, data, request_id, link_id, remote_identity, requested_at)</em> to be called. Whatever this funcion returns will be sent as a response to the requester. If the function returns <code class="docutils literal notranslate"><span class="pre">None</span></code>, no response will be sent.</p></li>
<li><p><strong>allow</strong> One of <code class="docutils literal notranslate"><span class="pre">RNS.Destination.ALLOW_NONE</span></code>, <code class="docutils literal notranslate"><span class="pre">RNS.Destination.ALLOW_ALL</span></code> or <code class="docutils literal notranslate"><span class="pre">RNS.Destination.ALLOW_LIST</span></code>. If <code class="docutils literal notranslate"><span class="pre">RNS.Destination.ALLOW_LIST</span></code> is set, the request handler will only respond to requests for identified peers in the supplied list.</p></li>
<li><p><strong>allowed_list</strong> A list of <em>bytes-like</em> <a class="reference internal" href="#api-identity"><span class="std std-ref">RNS.Identity</span></a> hashes.</p></li>
</ul>
@@ -1057,6 +1057,16 @@ thus preserved. This method can be used for authentication.</p>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Link.get_establishment_rate">
<span class="sig-name descname"><span class="pre">get_establishment_rate</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.get_establishment_rate" title="Permalink to this definition">#</a></dt>
<dd><dl class="field-list simple">
<dt class="field-odd">Returns</dt>
<dd class="field-odd"><p>The data transfer rate at which the link establishment procedure ocurred, in bits per second.</p>
</dd>
</dl>
</dd></dl>
<dl class="py method">
<dt class="sig sig-object py" id="RNS.Link.no_inbound_for">
<span class="sig-name descname"><span class="pre">no_inbound_for</span></span><span class="sig-paren">(</span><span class="sig-paren">)</span><a class="headerlink" href="#RNS.Link.no_inbound_for" title="Permalink to this definition">#</a></dt>
@@ -1588,6 +1598,7 @@ will announce it.</p>
<li><a class="reference internal" href="#RNS.Link.STALE_TIME"><code class="docutils literal notranslate"><span class="pre">STALE_TIME</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.identify"><code class="docutils literal notranslate"><span class="pre">identify()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.request"><code class="docutils literal notranslate"><span class="pre">request()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.get_establishment_rate"><code class="docutils literal notranslate"><span class="pre">get_establishment_rate()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.no_inbound_for"><code class="docutils literal notranslate"><span class="pre">no_inbound_for()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.no_outbound_for"><code class="docutils literal notranslate"><span class="pre">no_outbound_for()</span></code></a></li>
<li><a class="reference internal" href="#RNS.Link.inactive_for"><code class="docutils literal notranslate"><span class="pre">inactive_for()</span></code></a></li>
+3 -3
View File
@@ -4,7 +4,7 @@
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<meta name="color-scheme" content="light dark"><link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="#" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/><title>Search - Reticulum Network Stack 0.4.7 beta documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/><title>Search - Reticulum Network Stack 0.4.9 beta documentation</title><link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo-extensions.css?digest=30d1aed668e5c3a91c3e3bf6a60b675221979f0e" />
@@ -138,7 +138,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -164,7 +164,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="#" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="API Reference" href="reference.html" /><link rel="prev" title="Code Examples" href="examples.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>Support Reticulum - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>Support Reticulum - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
+14 -14
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Communications Hardware" href="hardware.html" /><link rel="prev" title="Using Reticulum on Your System" href="using.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>Understanding Reticulum - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>Understanding Reticulum - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@@ -337,12 +337,12 @@ needs to be purchased.</p>
</section>
<section id="introduction-basic-functionality">
<span id="understanding-basicfunctionality"></span><h2>Introduction &amp; Basic Functionality<a class="headerlink" href="#introduction-basic-functionality" title="Permalink to this heading">#</a></h2>
<p>Reticulum is a networking stack suited for high-latency, low-bandwidth links. Reticulum is at its
<p>Reticulum is a networking stack suited for high-latency, low-bandwidth links. Reticulum is at its
core a <em>message oriented</em> system. It is suited for both local point-to-point or point-to-multipoint
scenarios where all nodes are within range of each other, as well as scenarios where packets need
to be transported over multiple hops in a complex network to reach the recipient.</p>
<p>Reticulum does away with the idea of addresses and ports known from IP, TCP and UDP. Instead
Reticulum uses the singular concept of <em>destinations</em>. Any application using Reticulum as its
Reticulum uses the singular concept of <em>destinations</em>. Any application using Reticulum as its
networking stack will need to create one or more destinations to receive data, and know the
destinations it needs to send data to.</p>
<p>All destinations in Reticulum are _represented_ as a 16 byte hash. This hash is derived from truncating a full
@@ -442,7 +442,7 @@ addressable, because their public keys will differ.</p></li>
</ul>
<p>In actual use of <em>single</em> destination naming, it is advisable not to use any uniquely identifying
features in aspect naming. Aspect names should be general terms describing what kind of destination
is represented. The uniquely identifying aspect is always achieved by the appending the public key,
is represented. The uniquely identifying aspect is always achieved by appending the public key,
which expands the destination into a uniquely identifiable one. Reticulum does this automatically.</p>
<p>Any destination on a Reticulum network can be addressed and reached simply by knowing its
destination hash (and public key, but if the public key is not known, it can be requested from the
@@ -468,7 +468,7 @@ indirectly, but must first be established through a <em>single</em> destination.
</dl>
</li>
</ul>
<p>To communicate with a <em>single</em> destination, you need to know its public key. Any method for
<p>To communicate with a <em>single</em> destination, you need to know its public key. Any method for
obtaining the public key is valid, but Reticulum includes a simple mechanism for making other
nodes aware of your destinations public key, called the <em>announce</em>. It is also possible to request
an unknown public key from the network, as all transport instances serve as a distributed ledger
@@ -509,7 +509,7 @@ certain pattern. This will be detailed in the section
protocols such as IP, where an address is always expected to stay within the network segment it was assigned in.
This limitation does not exist in Reticulum, and any destination is <em>completely portable</em> over the entire topography
of the network, and <em>can even be moved to other Reticulum networks</em> than the one it was created in, and
still become reachable. To update its reachability, a destination simply needs to send an announce on any
still become reachable. To update its reachability, a destination simply needs to send an announce on any
networks it is part of. After a short while, it will be globally reachable in the network.</p>
<p>Seeing how <em>single</em> destinations are always tied to a private/public key pair leads us to the next topic.</p>
</section>
@@ -565,7 +565,7 @@ is the default setting.</p>
</section>
<section id="the-announce-mechanism-in-detail">
<span id="understanding-announce"></span><h3>The Announce Mechanism in Detail<a class="headerlink" href="#the-announce-mechanism-in-detail" title="Permalink to this heading">#</a></h3>
<p>When an <em>announce</em> for a destination is transmitted by from a Reticulum instance, it will be forwarded by
<p>When an <em>announce</em> for a destination is transmitted by a Reticulum instance, it will be forwarded by
any transport node receiving it, but according to some specific rules:</p>
<ul>
<li><div class="line-block">
@@ -590,7 +590,7 @@ announces is set at 2%, but can be configured on a per-interface basis.</div>
</li>
<li><div class="line-block">
<div class="line">If any given interface does not have enough bandwidth available for retransmitting the announce,
the announce will be assigned a priority inversely proportional to its hop count, and be inserted
the announce will be assigned a priority inversely proportional to its hop count, and be inserted
into a queue managed by the interface.</div>
</div>
</li>
@@ -639,7 +639,7 @@ expect. Reticulum offers two ways to do this.</p>
<li><div class="line-block">
<div class="line">A packet is always created with an associated destination and some payload data. When the packet is sent
to a <em>single</em> destination type, Reticulum will automatically create an ephemeral encryption key, perform
an ECDH key exchange with the destinations public key, and encrypt the information.</div>
an ECDH key exchange with the destinations public key, and encrypt the information.</div>
</div>
</li>
<li><div class="line-block">
@@ -665,8 +665,8 @@ packet.</div>
<li><div class="line-block">
<div class="line">Once the packet has been received and decrypted by the addressed destination, that destination can opt
to <em>prove</em> its receipt of the packet. It does this by calculating the SHA-256 hash of the received packet,
and signing this hash with its Ed25519 signing key. Transport nodes in the network can then direct this
<em>proof</em> back to the packets origin, where the signature can be verified against the destinations known
and signing this hash with its Ed25519 signing key. Transport nodes in the network can then direct this
<em>proof</em> back to the packets origin, where the signature can be verified against the destinations known
public signing key.</div>
</div>
</li>
@@ -689,7 +689,7 @@ forward the packet will take note of this <em>link request</em>.</div>
</li>
<li><div class="line-block">
<div class="line">Second, if the destination accepts the <em>link request</em> , it will send back a packet that proves the
authenticity of its identity (and the receipt of the link request) to the initiating node. All
authenticity of its identity (and the receipt of the link request) to the initiating node. All
nodes that initially forwarded the packet will also be able to verify this proof, and thus
accept the validity of the <em>link</em> throughout the network.</div>
</div>
+4 -4
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Understanding Reticulum" href="understanding.html" /><link rel="prev" title="Getting Started Fast" href="gettingstartedfast.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>Using Reticulum on Your System - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>Using Reticulum on Your System - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@@ -557,7 +557,7 @@ execute commands on remote systems over Reticulum, and to view returned command
output.</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span># Run rnx on the listening system, specifying which identities
# are allowed to execute commands
rncp --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
rnx --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
# From another system, run a command
rnx 7a55144adf826958a9529a3bcf08b149 &quot;cat /proc/cpuinfo&quot;
+5 -5
View File
@@ -6,7 +6,7 @@
<link rel="index" title="Index" href="genindex.html" /><link rel="search" title="Search" href="search.html" /><link rel="next" title="Getting Started Fast" href="gettingstartedfast.html" /><link rel="prev" title="Reticulum Network Stack Manual" href="index.html" />
<meta name="generator" content="sphinx-5.2.2, furo 2022.09.29"/>
<title>What is Reticulum? - Reticulum Network Stack 0.4.7 beta documentation</title>
<title>What is Reticulum? - Reticulum Network Stack 0.4.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/styles/furo.css?digest=d81277517bee4d6b0349d71bb2661d4890b5617c" />
<link rel="stylesheet" type="text/css" href="_static/copybutton.css" />
@@ -141,7 +141,7 @@
</label>
</div>
<div class="header-center">
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.7 beta documentation</div></a>
<a href="index.html"><div class="brand">Reticulum Network Stack 0.4.9 beta documentation</div></a>
</div>
<div class="header-right">
<div class="theme-toggle-container theme-toggle-header">
@@ -167,7 +167,7 @@
<img class="sidebar-logo" src="_static/rns_logo_512.png" alt="Logo"/>
</div>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.7 beta documentation</span>
<span class="sidebar-brand-text">Reticulum Network Stack 0.4.9 beta documentation</span>
</a><form class="sidebar-search-container" method="get" action="search.html" role="search">
<input class="sidebar-search" placeholder=Search name="q" aria-label="Search">
@@ -354,10 +354,10 @@ network, and vice versa.</p>
<h2>Caveat Emptor<a class="headerlink" href="#caveat-emptor" title="Permalink to this heading">#</a></h2>
<p>Reticulum is an experimental networking stack, 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
mind, it has not yet been externally security audited, and there could very well be
privacy-breaking bugs. To be considered secure, Reticulum needs a thorough
security review by independent cryptographers and security researchers. If you
want to help out, or help sponsor an audit, please do get in touch.</p>
want to help out with this, or can help sponsor an audit, please do get in touch.</p>
</section>
</section>
+4
View File
@@ -0,0 +1,4 @@
********************************************
An Explanation of Reticulum for Human Beings
********************************************
+4 -4
View File
@@ -115,8 +115,8 @@ Creating a Network With Reticulum
=============================================
To create a network, you will need to specify one or more *interfaces* for
Reticulum to use. This is done in the Reticulum configuration file, which by
default is located at ``~/.reticulum/config``. You can edit this file by hand,
or use the interactive ``rnsconfig`` utility.
default is located at ``~/.reticulum/config``. You can get an example
configuration file with all options via ``rnsd --exampleconfig``.
When Reticulum is started for the first time, it will create a default
configuration file, with one active interface. This default interface uses
@@ -197,7 +197,7 @@ by adding one of the following interfaces to your ``.reticulum/config`` file:
target_port = 4965
# TCP/IP interface to the Frankfurt hub
[[RNS Testnet Dublin]]
[[RNS Testnet Frankfurt]]
type = TCPClientInterface
enabled = yes
target_host = frankfurt.connect.reticulum.network
@@ -234,7 +234,7 @@ chapter for a guide. If you prefer purchasing a ready-made unit, you can refer t
refer to these additional external resources:
* `How To Make Your Own RNodes <https://unsigned.io/how-to-make-your-own-rnodes/>`_
* `Installing RNode Firmware on Compatible LoRa Devices <https://unsigned.io/installing-rnode-firmware-on-t-beam-and-lora32-devices/>`_
* `Installing RNode Firmware on Compatible LoRa Devices <https://unsigned.io/installing-rnode-firmware-on-supported-devices/>`_
* `Private, Secure and Uncensorable Messaging Over a LoRa Mesh <https://unsigned.io/private-messaging-over-lora/>`_
* `RNode Firmware <https://github.com/markqvist/RNode_Firmware/>`_
+11 -11
View File
@@ -107,13 +107,13 @@ guide the design of Reticulum:
Introduction & Basic Functionality
==================================
Reticulum is a networking stack suited for high-latency, low-bandwidth links. Reticulum is at its
Reticulum is a networking stack suited for high-latency, low-bandwidth links. Reticulum is at its
core a *message oriented* system. It is suited for both local point-to-point or point-to-multipoint
scenarios where all nodes are within range of each other, as well as scenarios where packets need
to be transported over multiple hops in a complex network to reach the recipient.
Reticulum does away with the idea of addresses and ports known from IP, TCP and UDP. Instead
Reticulum uses the singular concept of *destinations*. Any application using Reticulum as its
Reticulum uses the singular concept of *destinations*. Any application using Reticulum as its
networking stack will need to create one or more destinations to receive data, and know the
destinations it needs to send data to.
@@ -220,7 +220,7 @@ packet.
In actual use of *single* destination naming, it is advisable not to use any uniquely identifying
features in aspect naming. Aspect names should be general terms describing what kind of destination
is represented. The uniquely identifying aspect is always achieved by the appending the public key,
is represented. The uniquely identifying aspect is always achieved by appending the public key,
which expands the destination into a uniquely identifiable one. Reticulum does this automatically.
Any destination on a Reticulum network can be addressed and reached simply by knowing its
@@ -239,7 +239,7 @@ To recap, the different destination types should be used in the following situat
* **Plain**
When plain-text communication is desirable, for example when broadcasting information, or for local discovery purposes.
To communicate with a *single* destination, you need to know its public key. Any method for
To communicate with a *single* destination, you need to know its public key. Any method for
obtaining the public key is valid, but Reticulum includes a simple mechanism for making other
nodes aware of your destinations public key, called the *announce*. It is also possible to request
an unknown public key from the network, as all transport instances serve as a distributed ledger
@@ -287,7 +287,7 @@ In Reticulum, destinations are allowed to move around the network at will. This
protocols such as IP, where an address is always expected to stay within the network segment it was assigned in.
This limitation does not exist in Reticulum, and any destination is *completely portable* over the entire topography
of the network, and *can even be moved to other Reticulum networks* than the one it was created in, and
still become reachable. To update it's reachability, a destination simply needs to send an announce on any
still become reachable. To update its reachability, a destination simply needs to send an announce on any
networks it is part of. After a short while, it will be globally reachable in the network.
Seeing how *single* destinations are always tied to a private/public key pair leads us to the next topic.
@@ -368,7 +368,7 @@ If it is a *Transport Node*, it should be given the configuration directive ``en
The Announce Mechanism in Detail
--------------------------------
When an *announce* for a destination is transmitted by from a Reticulum instance, it will be forwarded by
When an *announce* for a destination is transmitted by a Reticulum instance, it will be forwarded by
any transport node receiving it, but according to some specific rules:
@@ -385,7 +385,7 @@ any transport node receiving it, but according to some specific rules:
announces is set at 2%, but can be configured on a per-interface basis.
* | If any given interface does not have enough bandwidth available for retransmitting the announce,
the announce will be assigned a priority inversely proportional to it's hop count, and be inserted
the announce will be assigned a priority inversely proportional to its hop count, and be inserted
into a queue managed by the interface.
* | When the interface has bandwidth available for processing an announce, it will prioritise announces
@@ -431,7 +431,7 @@ For exchanges of small amounts of information, Reticulum offers the *Packet* API
* | A packet is always created with an associated destination and some payload data. When the packet is sent
to a *single* destination type, Reticulum will automatically create an ephemeral encryption key, perform
an ECDH key exchange with the destinations public key, and encrypt the information.
an ECDH key exchange with the destination's public key, and encrypt the information.
* | It is important to note that this key exchange does not require any network traffic. The sender already
knows the public key of the destination from an earlier received *announce*, and can thus perform the ECDH
@@ -447,8 +447,8 @@ For exchanges of small amounts of information, Reticulum offers the *Packet* API
* | Once the packet has been received and decrypted by the addressed destination, that destination can opt
to *prove* its receipt of the packet. It does this by calculating the SHA-256 hash of the received packet,
and signing this hash with it's Ed25519 signing key. Transport nodes in the network can then direct this
*proof* back to the packets origin, where the signature can be verified against the destinations known
and signing this hash with its Ed25519 signing key. Transport nodes in the network can then direct this
*proof* back to the packets origin, where the signature can be verified against the destination's known
public signing key.
* | In case the packet is addressed to a *group* destination type, the packet will be encrypted with the
@@ -465,7 +465,7 @@ For exchanges of larger amounts of data, or when longer sessions of bidirectiona
forward the packet will take note of this *link request*.
* | Second, if the destination accepts the *link request* , it will send back a packet that proves the
authenticity of its identity (and the receipt of the link request) to the initiating node. All
authenticity of its identity (and the receipt of the link request) to the initiating node. All
nodes that initially forwarded the packet will also be able to verify this proof, and thus
accept the validity of the *link* throughout the network.
+2 -2
View File
@@ -377,7 +377,7 @@ output.
# Run rnx on the listening system, specifying which identities
# are allowed to execute commands
rncp --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
rnx --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
# From another system, run a command
rnx 7a55144adf826958a9529a3bcf08b149 "cat /proc/cpuinfo"
@@ -565,4 +565,4 @@ If you want to automatically start ``rnsd`` at boot, run:
.. code:: text
sudo systemctl enable rnsd
sudo systemctl enable rnsd
+2 -2
View File
@@ -162,7 +162,7 @@ Caveat Emptor
==============
Reticulum is an experimental networking stack, 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
mind, it has not yet been externally security audited, and there could very well be
privacy-breaking bugs. To be considered secure, Reticulum needs a thorough
security review by independent cryptographers and security researchers. If you
want to help out, or help sponsor an audit, please do get in touch.
want to help out with this, or can help sponsor an audit, please do get in touch.
+1
View File
@@ -43,6 +43,7 @@ setuptools.setup(
'rnstatus=RNS.Utilities.rnstatus:main',
'rnprobe=RNS.Utilities.rnprobe:main',
'rnpath=RNS.Utilities.rnpath:main',
'rnid=RNS.Utilities.rnid:main',
'rncp=RNS.Utilities.rncp:main',
'rnx=RNS.Utilities.rnx:main',
'rnodeconf=RNS.Utilities.rnodeconf:main',