Compare commits

...

37 Commits

Author SHA1 Message Date
Mark Qvist fd2cc1231f Updated readme 2022-07-04 23:55:43 +02:00
Mark Qvist 76950ee3de Updated manual 2022-07-04 23:46:21 +02:00
markqvist 8565b2fdf5 Update README.md 2022-07-03 09:29:35 +02:00
markqvist 2a915eab2d Merge pull request #76 from joshuafuller/master
Fix some minor spelling errors
2022-07-03 09:28:40 +02:00
Joshua Fuller 36654c1414 Fix some minor spelling errors 2022-07-02 17:32:39 -05:00
Mark Qvist fdf0456cf0 Updated readme and docs 2022-07-02 18:41:57 +02:00
Mark Qvist 8cff18f8ce Improved cache handling 2022-07-02 15:15:47 +02:00
Mark Qvist 5e072affe4 Changed job timing 2022-07-02 13:34:17 +02:00
Mark Qvist fc4c7638a6 Added cache job scheduler 2022-07-02 13:24:07 +02:00
Mark Qvist 532f9ee665 Added cache cleaning 2022-07-02 13:12:54 +02:00
Mark Qvist 4a725de935 Improved rnx interactive mode 2022-07-02 10:38:35 +02:00
Mark Qvist 2335a71427 Fixed --no-auth option in rncp 2022-07-02 09:48:15 +02:00
Mark Qvist 3e70dd6134 Fixed --no-auth option in rncp 2022-07-02 09:33:05 +02:00
Mark Qvist 474521056b Updated packet sizes in docs 2022-07-02 08:45:57 +02:00
Mark Qvist d33154bfdb Cleanup 2022-07-02 08:45:40 +02:00
Mark Qvist 8f82a2b87f Updated documentation to reflect 128-bit address space 2022-07-01 23:34:02 +02:00
Mark Qvist 304610c682 Updated documentation to reflect 128-bit address space 2022-07-01 23:30:20 +02:00
Mark Qvist bc39a1acf1 Fixed static size index 2022-07-01 21:16:01 +02:00
Mark Qvist 20b7278f7b Updated documentation 2022-07-01 21:15:15 +02:00
Mark Qvist 1f66a9b0c0 Updated readme 2022-07-01 21:13:55 +02:00
Mark Qvist f464ecfcb5 Updated website 2022-07-01 17:31:07 +02:00
Mark Qvist 49fdeb9bc4 Updated readme 2022-07-01 17:30:51 +02:00
Mark Qvist 40560a31f2 Version updated 2022-07-01 10:27:31 +02:00
Mark Qvist f7d8a4b3b3 Updated tests 2022-06-30 20:37:51 +02:00
Mark Qvist c498bf5668 Updated examples 2022-06-30 20:07:48 +02:00
Mark Qvist 2e19304ebf Fixed static length calculation in proof destination generation 2022-06-30 19:33:35 +02:00
Mark Qvist 1cd7c85a52 Cleanup 2022-06-30 19:32:47 +02:00
Mark Qvist 171f43f4e3 Cleanup 2022-06-30 19:32:29 +02:00
Mark Qvist 09a1088437 Added description about Fernet modifications 2022-06-30 19:32:08 +02:00
Mark Qvist 6346bc54a8 Updated readme 2022-06-30 19:31:13 +02:00
Mark Qvist 40e25d8e40 Fixed static destination size 2022-06-30 19:12:44 +02:00
Mark Qvist e19438fdcc Added license headers 2022-06-30 19:10:51 +02:00
markqvist d85ea07b5e Update README.md 2022-06-30 14:07:58 +02:00
Mark Qvist 4dda0e8a5b Updated readme 2022-06-30 14:06:55 +02:00
Mark Qvist 5faf13d505 Expanded address space to 128 bits 2022-06-30 14:02:57 +02:00
Mark Qvist 2be1c7633d Updated readme 2022-06-27 20:17:23 +02:00
Mark Qvist 6ac2f437b9 Updated documentation 2022-06-22 23:26:08 +02:00
54 changed files with 665 additions and 432 deletions
+6 -4
View File
@@ -120,14 +120,16 @@ def client(destination_hexhash, configpath, timeout=None):
# We need a binary representation of the destination
# hash that was entered on the command line
try:
if len(destination_hexhash) != 20:
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
if len(destination_hexhash) != dest_len:
raise ValueError(
"Destination length is invalid, must be 20 hexadecimal characters (10 bytes)"
"Destination length is invalid, must be {hex} hexadecimal characters ({byte} bytes).".format(hex=dest_len, byte=dest_len//2)
)
destination_hash = bytes.fromhex(destination_hexhash)
except:
RNS.log("Invalid destination entered. Check your input!\n")
except Exception as e:
RNS.log("Invalid destination entered. Check your input!")
RNS.log(str(e)+"\n")
exit()
# We must first initialise Reticulum
+6 -2
View File
@@ -215,8 +215,12 @@ def client(destination_hexhash, configpath):
# We need a binary representation of the destination
# hash that was entered on the command line
try:
if len(destination_hexhash) != 20:
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
if len(destination_hexhash) != dest_len:
raise ValueError(
"Destination length is invalid, must be {hex} hexadecimal characters ({byte} bytes).".format(hex=dest_len, byte=dest_len//2)
)
destination_hash = bytes.fromhex(destination_hexhash)
except:
RNS.log("Invalid destination entered. Check your input!\n")
+7 -3
View File
@@ -84,7 +84,7 @@ def client_connected(link):
def client_disconnected(link):
RNS.log("Client disconnected")
def remote_identified(identity):
def remote_identified(link, identity):
RNS.log("Remote identified as: "+str(identity))
def server_packet_received(message, packet):
@@ -124,8 +124,12 @@ def client(destination_hexhash, configpath):
# We need a binary representation of the destination
# hash that was entered on the command line
try:
if len(destination_hexhash) != 20:
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
if len(destination_hexhash) != dest_len:
raise ValueError(
"Destination length is invalid, must be {hex} hexadecimal characters ({byte} bytes).".format(hex=dest_len, byte=dest_len//2)
)
destination_hash = bytes.fromhex(destination_hexhash)
except:
RNS.log("Invalid destination entered. Check your input!\n")
+6 -2
View File
@@ -110,8 +110,12 @@ def client(destination_hexhash, configpath):
# We need a binary representation of the destination
# hash that was entered on the command line
try:
if len(destination_hexhash) != 20:
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
if len(destination_hexhash) != dest_len:
raise ValueError(
"Destination length is invalid, must be {hex} hexadecimal characters ({byte} bytes).".format(hex=dest_len, byte=dest_len//2)
)
destination_hash = bytes.fromhex(destination_hexhash)
except:
RNS.log("Invalid destination entered. Check your input!\n")
+6 -2
View File
@@ -110,8 +110,12 @@ def client(destination_hexhash, configpath):
# We need a binary representation of the destination
# hash that was entered on the command line
try:
if len(destination_hexhash) != 20:
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
if len(destination_hexhash) != dest_len:
raise ValueError(
"Destination length is invalid, must be {hex} hexadecimal characters ({byte} bytes).".format(hex=dest_len, byte=dest_len//2)
)
destination_hash = bytes.fromhex(destination_hexhash)
except:
RNS.log("Invalid destination entered. Check your input!\n")
+6 -2
View File
@@ -166,8 +166,12 @@ def client(destination_hexhash, configpath):
# We need a binary representation of the destination
# hash that was entered on the command line
try:
if len(destination_hexhash) != 20:
raise ValueError("Destination length is invalid, must be 20 hexadecimal characters (10 bytes)")
dest_len = (RNS.Reticulum.TRUNCATED_HASHLENGTH//8)*2
if len(destination_hexhash) != dest_len:
raise ValueError(
"Destination length is invalid, must be {hex} hexadecimal characters ({byte} bytes).".format(hex=dest_len, byte=dest_len//2)
)
destination_hash = bytes.fromhex(destination_hexhash)
except:
RNS.log("Invalid destination entered. Check your input!\n")
+39 -28
View File
@@ -5,7 +5,7 @@ Reticulum Network Stack β
Reticulum is the cryptography-based networking stack for wide-area networks built on readily available hardware. It can operate even with very high latency and extremely low bandwidth. Reticulum allows you to build wide-area networks with off-the-shelf tools, and offers end-to-end encryption and connectivity, initiator anonymity, autoconfiguring cryptographically backed multi-hop transport, efficient addressing, unforgeable delivery acknowledgements and more.
The vision of Reticulum is to allow anyone to be their own network operator, and to make it cheap and easy to cover vast areas with a myriad of independent, interconnectable and autonomous networks. Reticulum **is not** *one* network. It is **a tool** for building *thousands of networks*. Networks without kill-switches, surveillance, censorship and control. Networks that can freely interoperate, associate and disassociate with each other, and require no central oversight. Networks for human beings. *Networks for the people*.
The vision of Reticulum is to allow anyone to be their own network operator, and to make it cheap and easy to cover vast areas with a myriad of independent, inter-connectable and autonomous networks. Reticulum **is not** *one* network. It is **a tool** for building *thousands of networks*. Networks without kill-switches, surveillance, censorship and control. Networks that can freely interoperate, associate and disassociate with each other, and require no central oversight. Networks for human beings. *Networks for the people*.
Reticulum is a complete networking stack, and does not rely on IP or higher layers, but it is possible to use IP as the underlying carrier for Reticulum. It is therefore trivial to tunnel Reticulum over the Internet or private IP networks.
@@ -21,11 +21,11 @@ You can also [download the Reticulum manual as a PDF](https://github.com/markqvi
For more info, see [unsigned.io/projects/reticulum](https://unsigned.io/projects/reticulum/)
## Notable Features
- Coordination-less globally unique adressing and identification
- Coordination-less globally unique addressing and identification
- Fully self-configuring multi-hop routing
- Complete initiator anonymity, communicate without revealing your identity
- Asymmetric X25519 encryption and Ed25519 signatures as a basis for all communication
- Forward Secrecy with ephemereal Elliptic Curve Diffie-Hellman keys on Curve25519
- Forward Secrecy with ephemeral Elliptic Curve Diffie-Hellman keys on Curve25519
- Reticulum uses the [Fernet](https://github.com/fernet/spec/blob/master/Spec.md) specification for on-the-wire / over-the-air encryption
- Keys are ephemeral and derived from an ECDH key exchange on Curve25519
- AES-128 in CBC mode with PKCS7 padding
@@ -34,14 +34,14 @@ For more info, see [unsigned.io/projects/reticulum](https://unsigned.io/projects
- Unforgeable packet delivery confirmations
- A variety of supported interface types
- An intuitive and easy-to-use API
- Reliable and efficient transfer of arbritrary amounts of data
- Reliable and efficient transfer of arbitrary amounts of data
- Reticulum can handle a few bytes of data or files of many gigabytes
- Sequencing, transfer coordination and checksumming is automatic
- Sequencing, transfer coordination and checksumming are automatic
- The API is very easy to use, and provides transfer progress
- Lightweight, flexible and expandable Request/Response mechanism
- Efficient link establishment
- Total bandwidth cost of setting up an encrypted link is 3 packets totalling 237 bytes
- Low cost of keeping links open at only 0.62 bits per second
- Total bandwidth cost of setting up an encrypted link is 3 packets totaling 265 bytes
- Low cost of keeping links open at only 0.44 bits per second
## Examples of Reticulum Applications
If you want to quickly get an idea of what Reticulum can do, take a look at the following resources.
@@ -51,11 +51,11 @@ If you want to quickly get an idea of what Reticulum can do, take a look at the
- The Android, Linux and macOS app [Sideband](https://unsigned.io/sideband) has a graphical interface and focuses on ease of use.
## Where can Reticulum be used?
Over practically any medium that can support at least a half-duplex channel with 500 bits per second throughput, and an MTU of 500 bytes. Data radios, modems, LoRa radios, serial lines, AX.25 TNCs, amateur radio digital modes, ad-hoc WiFi, free-space optical links and similar systems are all examples of the types of interfaces Reticulum was designed for.
Over practically any medium that can support at least a half-duplex channel with 500 bits per second throughput, and an MTU of 500 bytes. Data radios, modems, LoRa radios, serial lines, AX.25 TNCs, amateur radio digital modes, WiFi and Ethernet devices, free-space optical links, and similar systems are all examples of the types of physical devices Reticulum can use.
An open-source LoRa-based interface called [RNode](https://unsigned.io/projects/rnode/) has been designed specifically for use with Reticulum. It is possible to build yourself, or it can be purchased as a complete transceiver that just needs a USB connection to the host.
An open-source LoRa-based interface called [RNode](https://markqvist.github.io/Reticulum/manual/hardware.html#rnode) has been designed specifically for use with Reticulum. It is possible to build yourself, or it can be purchased as a complete transceiver that just needs a USB connection to the host.
Reticulum can also be encapsulated over existing IP networks, so there's nothing stopping you from using it over wired ethernet or your local WiFi network, where it'll work just as well. In fact, one of the strengths of Reticulum is how easily it allows you to connect different mediums into a self-configuring, resilient and encrypted mesh.
Reticulum can also be encapsulated over existing IP networks, so there's nothing stopping you from using it over wired ethernet, your local WiFi network or the Internet, where it'll work just as well. In fact, one of the strengths of Reticulum is how easily it allows you to connect different mediums into a self-configuring, resilient and encrypted mesh, using any available mixture of available infrastructure.
As an example, it's possible to set up a Raspberry Pi connected to both a LoRa radio, a packet radio TNC and a WiFi network. Once the interfaces are configured, Reticulum will take care of the rest, and any device on the WiFi network can communicate with nodes on the LoRa and packet radio sides of the network, and vice versa.
@@ -71,19 +71,19 @@ pip3 install rns
You can then start any program that uses Reticulum, or start Reticulum as a system service with [the rnsd utility](https://markqvist.github.io/Reticulum/manual/using.html#the-rnsd-utility).
When first started, Reticulum will create a default configuration file, providing basic connectivity to other Reticulum peers. The default config file contains examples for using Reticulum with LoRa transceivers (specifically [RNode](https://unsigned.io/projects/rnode/)), packet radio TNCs/modems, TCP and UDP.
When first started, Reticulum will create a default configuration file, providing basic connectivity to other Reticulum peers that might be locally reachable. The default config file contains a few examples, and references for creating a more complex configuration.
You can use the examples in the config file to expand communication over many mediums such as packet radio or LoRa (with [RNode](https://unsigned.io/projects/rnode/)), serial ports, or over fast IP links and the Internet using the UDP and TCP interfaces. For more detailed examples, take a look at the [Supported Interfaces](https://markqvist.github.io/Reticulum/manual/interfaces.html) section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/).
For more detailed examples on how to expand communication over many mediums such as packet radio or LoRa, serial ports, or over fast IP links and the Internet using the UDP and TCP interfaces, take a look at the [Supported Interfaces](https://markqvist.github.io/Reticulum/manual/interfaces.html) section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/).
## Included Utilities
Reticulum includes a range of useful utilities for managing your networks, viewing status and information, and other tasks. You can read more about these programs in the [Included Utility Programs](https://markqvist.github.io/Reticulum/manual/using.html#included-utility-programs) section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/).
- The system daemon `rnsd` for running Reticulum as an always-available service
- An interface status utility called `rnstatus`, that displays information about interfaces
- The path lookup and and management tool `rnpath` letting you view and modify path tables
- The path lookup and management tool `rnpath` letting you view and modify path tables
- A diagnostics tool called `rnprobe` for checking connectivity to destinations
- A simple file transfer program called `rncp` making easy to copy files to remote systems
- The remote command execution program `rnx` that let's you run commands and programs and retrieve output from remote systems
- A simple file transfer program called `rncp` making it easy to copy files to remote systems
- The remote command execution program `rnx` let's you run commands and programs and retrieve output from remote systems
All tools, including `rnx` and `rncp`, work reliably and well even over very low-bandwidth links like LoRa or Packet Radio.
@@ -112,12 +112,10 @@ Currently, the usable performance envelope is approximately 500 bits per second
Reticulum should currently be considered beta software. All core protocol features are implemented and functioning, but additions will probably occur as real-world use is explored. There will be bugs. The API and wire-format can be considered relatively stable at the moment, but could change if warranted.
## Development Roadmap
- Version 0.3.9
- Expansion of address space to 128 bits
- Performance and memory optimisations
- Utilities for managing identities, signing and encryption
- Version 0.4.0
- Improving [the manual](https://markqvist.github.io/Reticulum/manual/) with sections specifically for beginners
- Performance and memory optimisations
- Utilities for managing identities, signing and encryption
- User friendly interface configuration tool
- Support for radio and modem interfaces on Android
- More interface types for even broader compatibility
@@ -125,6 +123,7 @@ Reticulum should currently be considered beta software. All core protocol featur
- More LoRa transceivers
- IR Transceivers
- Planned, but not yet scheduled
- Distributed Destination Naming System
- Network-wide path balancing
- Globally routable multicast
- Bindings for other programming languages
@@ -139,8 +138,7 @@ Reticulum should currently be considered beta software. All core protocol featur
- MQTT
- SPI
- i²c
- Tor
## Dependencies
The installation of the default `rns` package requires the dependencies listed below. Almost all systems and distributions have readily available packages for these dependencies, and when the `rns` package is installed with `pip`, they will be downloaded and installed as well.
@@ -158,11 +156,10 @@ No matter how Reticulum is installed and started, it will load external dependen
## Public Testnet
If you just want to get started experimenting without building any physical networks, you are welcome to join the Unsigned.io RNS Testnet. The testnet is just that, an informal network for testing and experimenting. It will be up most of the time, and anyone can join, but it also means that there's no guarantees for service availability.
The testnet runs the very latest version of Reticulum (often even a short while before it is publicly released). Sometimes experimental versions of Reticulum might be deployed to nodes on the testnet, which means strange behaviour might occur. If none of that scares you, you can join the testnet via eihter TCP or I2P. Just add one of the following interfaces to your Reticulum configuration file:
The testnet runs the very latest version of Reticulum (often even a short while before it is publicly released). Sometimes experimental versions of Reticulum might be deployed to nodes on the testnet, which means strange behaviour might occur. If none of that scares you, you can join the testnet via either TCP or I2P. Just add one of the following interfaces to your Reticulum configuration file:
```
# For connecting over TCP/IP:
# For connecting over TCP/IP on v0.3.8:
[[RNS Testnet Frankfurt]]
type = TCPClientInterface
interface_enabled = yes
@@ -171,12 +168,25 @@ The testnet runs the very latest version of Reticulum (often even a short while
target_port = 4965
# For connecting over I2P:
# For connecting over I2P on v0.3.8:
[[RNS Testnet I2P Node A]]
type = I2PInterface
interface_enabled = yes
peers = ykzlw5ujbaqc2xkec4cpvgyxj257wcrmmgkuxqmqcur7cq3w3lha.b32.i2p
# For connecting over TCP/IP on v0.3.9+:
[[RNS Testnet Dublin]]
type = TCPClientInterface
enabled = yes
target_host = dublin.connect.reticulum.network
target_port = 4965
# For connecting over I2P on v0.3.9+:
[[RNS Testnet I2P Hub A]]
type = I2PInterface
enabled = yes
peers = uxg5kubabakh3jtnvsipingbr5574dle7bubvip7llfvwx2tgrua.b32.i2p
```
The testnet also contains a number of [Nomad Network](https://github.com/markqvist/nomadnet) nodes, and LXMF propagation nodes.
@@ -203,14 +213,15 @@ You can help support the continued development of open, free and private communi
Are certain features in the development roadmap are important to you or your organisation? Make them a reality quickly by sponsoring their implementation.
## Cryptographic Primitives
Reticulum has been designed to use a simple suite of efficient, strong and modern cryptographic primitives, with widely available implementations that can be used both on general-purpose CPUs and on microcontrollers. The necessary primitives are:
Reticulum uses a simple suite of efficient, strong and modern cryptographic primitives, with widely available implementations that can be used both on general-purpose CPUs and on microcontrollers. The necessary primitives are:
- Ed25519 for signatures
- X22519 for ECDH key exchanges
- HKDF for key derivation
- Fernet for encrypted tokens
- Modified Fernet for encrypted tokens
- AES-128 in CBC mode
- HMAC for message authentication
- No Fernet version and timestamp fields
- SHA-256
- SHA-512
+13 -6
View File
@@ -28,9 +28,16 @@ from RNS.Cryptography import PKCS7
from RNS.Cryptography.AES import AES_128_CBC
class Fernet():
FERNET_VERSION = 0x80
FERNET_OVERHEAD = 57 # In bytes
OPTIMISED_FERNET_OVERHEAD = 54 # In bytes
"""
This class provides a slightly modified implementation of the Fernet spec
found at: https://github.com/fernet/spec/blob/master/Spec.md
According to the spec, a Fernet token includes a one byte VERSION and
eight byte TIMESTAMP field at the start of each token. These fields are
not relevant to Reticulum. They are therefore stripped from this
implementation, since they incur overhead and leak initiator metadata.
"""
FERNET_OVERHEAD = 48 # Bytes
@staticmethod
def generate_key():
@@ -73,7 +80,7 @@ class Fernet():
iv = iv,
)
signed_parts = b"\x80"+current_time.to_bytes(length=8, byteorder="big")+iv+ciphertext
signed_parts = iv+ciphertext
return signed_parts + HMAC.new(self._signing_key, signed_parts).digest()
@@ -85,8 +92,8 @@ class Fernet():
if not self.verify_hmac(token):
raise ValueError("Fernet token HMAC was invalid")
iv = token[9:25]
ciphertext = token[25:-32]
iv = token[:16]
ciphertext = token[16:-32]
try:
plaintext = PKCS7.unpad(
+21 -3
View File
@@ -1,6 +1,24 @@
#!/usr/bin/python
__author__ = 'Thomas Dixon'
__license__ = 'MIT'
# MIT License
#
# Copyright (c) 2017 Thomas Dixon
#
# 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 copy
import struct
+21 -3
View File
@@ -1,6 +1,24 @@
#!/usr/bin/python
__author__ = 'Thomas Dixon'
__license__ = 'MIT'
# MIT License
#
# Copyright (c) 2017 Thomas Dixon
#
# 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 copy, struct, sys
+7 -3
View File
@@ -53,9 +53,7 @@ class Identity:
"""
# Non-configurable constants
FERNET_VERSION = RNS.Cryptography.Fernet.FERNET_VERSION
FERNET_OVERHEAD = RNS.Cryptography.Fernet.FERNET_OVERHEAD
OPTIMISED_FERNET_OVERHEAD = RNS.Cryptography.Fernet.OPTIMISED_FERNET_OVERHEAD
AES128_BLOCKSIZE = 16 # In bytes
HASHLENGTH = 256 # In bits
SIGLENGTH = KEYSIZE # In bits
@@ -137,8 +135,14 @@ class Identity:
if os.path.isfile(RNS.Reticulum.storagepath+"/known_destinations"):
try:
file = open(RNS.Reticulum.storagepath+"/known_destinations","rb")
Identity.known_destinations = umsgpack.load(file)
loaded_known_destinations = umsgpack.load(file)
file.close()
Identity.known_destinations = {}
for known_destination in loaded_known_destinations:
if len(known_destination) == RNS.Reticulum.TRUNCATED_HASHLENGTH//8:
Identity.known_destinations[known_destination] = loaded_known_destinations[known_destination]
RNS.log("Loaded "+str(len(Identity.known_destinations))+" known destination from storage", RNS.LOG_VERBOSE)
except:
RNS.log("Error loading known destinations from disk, file will be recreated on exit", RNS.LOG_ERROR)
-2
View File
@@ -310,8 +310,6 @@ class I2PController:
else:
i2ptunnel = self.i2plib_tunnels[i2p_b32]
if hasattr(i2ptunnel, "status"):
# TODO: Remove
# RNS.log(str(i2ptunnel.status))
i2p_exception = i2ptunnel.status["exception"]
if i2ptunnel.status["setup_ran"] == False:
+4 -4
View File
@@ -51,7 +51,7 @@ class LocalClientInterface(Interface):
self.txb = 0
# TODO: Remove at some point
self.rxptime = 0
# self.rxptime = 0
self.HW_MTU = 1064
@@ -142,13 +142,13 @@ class LocalClientInterface(Interface):
self.parent_interface.rxb += len(data)
# TODO: Remove at some point
processing_start = time.time()
# processing_start = time.time()
self.owner.inbound(data, self)
# TODO: Remove at some point
duration = time.time() - processing_start
self.rxptime += duration
# duration = time.time() - processing_start
# self.rxptime += duration
def processOutgoing(self, data):
if self.online:
+4 -13
View File
@@ -59,7 +59,7 @@ class Link:
ECPUBSIZE = 32+32
KEYSIZE = 32
MDU = math.floor((RNS.Reticulum.MTU-RNS.Reticulum.IFAC_MIN_SIZE-RNS.Reticulum.HEADER_MINSIZE-RNS.Identity.OPTIMISED_FERNET_OVERHEAD)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1
MDU = math.floor((RNS.Reticulum.MTU-RNS.Reticulum.IFAC_MIN_SIZE-RNS.Reticulum.HEADER_MINSIZE-RNS.Identity.FERNET_OVERHEAD)/RNS.Identity.AES128_BLOCKSIZE)*RNS.Identity.AES128_BLOCKSIZE - 1
ESTABLISHMENT_TIMEOUT_PER_HOP = RNS.Reticulum.DEFAULT_PER_HOP_TIMEOUT
"""
@@ -788,16 +788,7 @@ class Link:
RNS.log("Could not "+str(self)+" instantiate Fernet while performin encryption on link. The contained exception was: "+str(e), RNS.LOG_ERROR)
raise e
# The fernet token VERSION field is stripped here and
# reinserted on the receiving end, since it is always
# set to 0x80.
#
# Since we're also quite content with supporting time-
# stamps until the year 8921556 AD, we'll also strip 2
# bytes from the timestamp field and reinsert those as
# 0x00 when received.
ciphertext = self.fernet.encrypt(plaintext)[3:]
return ciphertext
return self.fernet.encrypt(plaintext)
except Exception as e:
RNS.log("Encryption on link "+str(self)+" failed. The contained exception was: "+str(e), RNS.LOG_ERROR)
@@ -809,8 +800,8 @@ class Link:
if not self.fernet:
self.fernet = Fernet(self.derived_key)
plaintext = self.fernet.decrypt(bytes([RNS.Identity.FERNET_VERSION, 0x00, 0x00]) + ciphertext)
return plaintext
return self.fernet.decrypt(ciphertext)
except Exception as e:
RNS.log("Decryption failed on link "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
+12 -10
View File
@@ -216,16 +216,18 @@ class Packet:
self.destination_type = (self.flags & 0b00001100) >> 2
self.packet_type = (self.flags & 0b00000011)
DST_LEN = RNS.Reticulum.TRUNCATED_HASHLENGTH//8
if self.header_type == Packet.HEADER_2:
self.transport_id = self.raw[2:12]
self.destination_hash = self.raw[12:22]
self.context = ord(self.raw[22:23])
self.data = self.raw[23:]
self.transport_id = self.raw[2:DST_LEN+2]
self.destination_hash = self.raw[DST_LEN+2:2*DST_LEN+2]
self.context = ord(self.raw[2*DST_LEN+2:2*DST_LEN+3])
self.data = self.raw[2*DST_LEN+3:]
else:
self.transport_id = None
self.destination_hash = self.raw[2:12]
self.context = ord(self.raw[12:13])
self.data = self.raw[13:]
self.destination_hash = self.raw[2:DST_LEN+2]
self.context = ord(self.raw[DST_LEN+2:DST_LEN+3])
self.data = self.raw[DST_LEN+3:]
self.packed = False
self.update_hash()
@@ -252,7 +254,7 @@ class Packet:
if not self.packed:
self.pack()
if RNS.Transport.outbound(self):
return self.receipt
else:
@@ -313,7 +315,7 @@ class Packet:
def get_hashable_part(self):
hashable_part = bytes([self.raw[0] & 0b00001111])
if self.header_type == Packet.HEADER_2:
hashable_part += self.raw[12:]
hashable_part += self.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
else:
hashable_part += self.raw[2:]
@@ -321,7 +323,7 @@ class Packet:
class ProofDestination:
def __init__(self, packet):
self.hash = packet.get_hash()[:10];
self.hash = packet.get_hash()[:RNS.Reticulum.TRUNCATED_HASHLENGTH//8];
self.type = RNS.Destination.SINGLE
def encrypt(self, plaintext):
+52 -2
View File
@@ -40,7 +40,7 @@ import threading
import atexit
import struct
import array
import os.path
import time
import os
import RNS
@@ -117,7 +117,7 @@ class Reticulum:
DEFAULT_PER_HOP_TIMEOUT = 5
# Length of truncated hashes in bits.
TRUNCATED_HASHLENGTH = 80
TRUNCATED_HASHLENGTH = 128
HEADER_MINSIZE = 2+1+(TRUNCATED_HASHLENGTH//8)*1
HEADER_MAXSIZE = 2+1+(TRUNCATED_HASHLENGTH//8)*2
@@ -126,6 +126,9 @@ class Reticulum:
MDU = MTU - HEADER_MAXSIZE - IFAC_MIN_SIZE
RESOURCE_CACHE = 24*60*60
JOB_INTERVAL = 15*60
router = None
config = None
@@ -202,6 +205,7 @@ class Reticulum:
self.is_shared_instance = False
self.is_connected_to_shared_instance = False
self.is_standalone_instance = False
self.jobs_thread = None
if not os.path.isdir(Reticulum.storagepath):
os.makedirs(Reticulum.storagepath)
@@ -249,6 +253,19 @@ class Reticulum:
signal.signal(signal.SIGINT, Reticulum.sigint_handler)
signal.signal(signal.SIGTERM, Reticulum.sigterm_handler)
def __start_jobs(self):
if self.jobs_thread == None:
self.jobs_thread = threading.Thread(target=self.__jobs)
self.jobs_thread.setDaemon(True)
self.jobs_thread.start()
def __jobs(self):
while True:
# Clean caches
self.__clean_caches()
time.sleep(Reticulum.JOB_INTERVAL)
def __start_local_interface(self):
if self.share_instance:
try:
@@ -261,6 +278,8 @@ class Reticulum:
self.is_shared_instance = True
RNS.log("Started shared instance interface: "+str(interface), RNS.LOG_DEBUG)
self.__start_jobs()
except Exception as e:
try:
interface = LocalInterface.LocalClientInterface(
@@ -285,6 +304,7 @@ class Reticulum:
self.is_shared_instance = False
self.is_standalone_instance = True
self.is_connected_to_shared_instance = False
self.__start_jobs()
def __apply_config(self):
if "logging" in self.config:
@@ -862,6 +882,36 @@ class Reticulum:
def __clean_caches(self):
RNS.log("Cleaning resource and packet caches...", RNS.LOG_EXTREME)
now = time.time()
# Clean resource caches
for filename in os.listdir(self.resourcepath):
try:
if len(filename) == (RNS.Identity.HASHLENGTH//8)*2:
filepath = self.resourcepath + "/" + filename
mtime = os.path.getmtime(filepath)
age = now - mtime
if age > Reticulum.RESOURCE_CACHE:
os.unlink(filepath)
except Exception as e:
RNS.log("Error while cleaning resources cache, the contained exception was: "+str(e), RNS.LOG_ERROR)
# Clean packet caches
for filename in os.listdir(self.cachepath):
try:
if len(filename) == (RNS.Identity.HASHLENGTH//8)*2:
filepath = self.cachepath + "/" + filename
mtime = os.path.getmtime(filepath)
age = now - mtime
if age > RNS.Transport.DESTINATION_TIMEOUT:
os.unlink(filepath)
except Exception as e:
RNS.log("Error while cleaning resources cache, the contained exception was: "+str(e), RNS.LOG_ERROR)
def __create_default_config(self):
self.config = ConfigObj(__default_rns_config__)
self.config.filename = Reticulum.configpath
+29 -33
View File
@@ -68,7 +68,7 @@ class Transport:
PATH_REQUEST_RW = 2 # Path request random window
LINK_TIMEOUT = RNS.Link.STALE_TIME * 1.25
REVERSE_TIMEOUT = 30*60 # Reverse table entries are removed after max 30 minutes
REVERSE_TIMEOUT = 30*60 # Reverse table entries are removed after 30 minutes
DESTINATION_TIMEOUT = 60*60*24*7 # Destination table entries are removed if unused for one week
MAX_RECEIPTS = 1024 # Maximum number of receipts to keep track of
MAX_RATE_TIMESTAMPS = 16 # Maximum number of announce timestamps to keep per destination
@@ -181,29 +181,31 @@ class Transport:
for serialised_entry in serialised_destinations:
destination_hash = serialised_entry[0]
timestamp = serialised_entry[1]
received_from = serialised_entry[2]
hops = serialised_entry[3]
expires = serialised_entry[4]
random_blobs = serialised_entry[5]
receiving_interface = Transport.find_interface_from_hash(serialised_entry[6])
announce_packet = Transport.get_cached_packet(serialised_entry[7])
if announce_packet != None and receiving_interface != None:
announce_packet.unpack()
# We increase the hops, since reading a packet
# from cache is equivalent to receiving it again
# over an interface. It is cached with it's non-
# increased hop-count.
announce_packet.hops += 1
Transport.destination_table[destination_hash] = [timestamp, received_from, hops, expires, random_blobs, receiving_interface, announce_packet]
RNS.log("Loaded path table entry for "+RNS.prettyhexrep(destination_hash)+" from storage", RNS.LOG_DEBUG)
else:
RNS.log("Could not reconstruct path table entry from storage for "+RNS.prettyhexrep(destination_hash), RNS.LOG_DEBUG)
if announce_packet == None:
RNS.log("The announce packet could not be loaded from cache", RNS.LOG_DEBUG)
if receiving_interface == None:
RNS.log("The interface is no longer available", RNS.LOG_DEBUG)
if len(destination_hash) == RNS.Reticulum.TRUNCATED_HASHLENGTH//8:
timestamp = serialised_entry[1]
received_from = serialised_entry[2]
hops = serialised_entry[3]
expires = serialised_entry[4]
random_blobs = serialised_entry[5]
receiving_interface = Transport.find_interface_from_hash(serialised_entry[6])
announce_packet = Transport.get_cached_packet(serialised_entry[7])
if announce_packet != None and receiving_interface != None:
announce_packet.unpack()
# We increase the hops, since reading a packet
# from cache is equivalent to receiving it again
# over an interface. It is cached with it's non-
# increased hop-count.
announce_packet.hops += 1
Transport.destination_table[destination_hash] = [timestamp, received_from, hops, expires, random_blobs, receiving_interface, announce_packet]
RNS.log("Loaded path table entry for "+RNS.prettyhexrep(destination_hash)+" from storage", RNS.LOG_DEBUG)
else:
RNS.log("Could not reconstruct path table entry from storage for "+RNS.prettyhexrep(destination_hash), RNS.LOG_DEBUG)
if announce_packet == None:
RNS.log("The announce packet could not be loaded from cache", RNS.LOG_DEBUG)
if receiving_interface == None:
RNS.log("The interface is no longer available", RNS.LOG_DEBUG)
if len(Transport.destination_table) == 1:
specifier = "entry"
@@ -658,10 +660,6 @@ class Transport:
tx_time = (len(packet.raw)*8) / interface.bitrate
wait_time = (tx_time / interface.announce_cap)
interface.announce_allowed_at = outbound_time + wait_time
# TODO: Clean
# wait_time_str = str(round(wait_time*1000,3))+"ms"
# RNS.log("Next announce on "+str(interface)+" allowed in "+wait_time_str, RNS.LOG_EXTREME)
else:
should_transmit = False
@@ -955,13 +953,13 @@ class Transport:
new_raw = packet.raw[0:1]
new_raw += struct.pack("!B", packet.hops)
new_raw += next_hop
new_raw += packet.raw[12:]
new_raw += packet.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
elif remaining_hops == 1:
# Strip transport headers and transmit
new_flags = (RNS.Packet.HEADER_1) << 6 | (Transport.BROADCAST) << 4 | (packet.flags & 0b00001111)
new_raw = struct.pack("!B", new_flags)
new_raw += struct.pack("!B", packet.hops)
new_raw += packet.raw[12:]
new_raw += packet.raw[(RNS.Identity.TRUNCATED_HASHLENGTH//8)+2:]
elif remaining_hops == 0:
# Just increase hop count and transmit
new_raw = packet.raw[0:1]
@@ -1848,12 +1846,10 @@ class Transport:
)
else:
# TODO: Reset this to debug level
RNS.log("Ignoring duplicate path request for "+RNS.prettyhexrep(destination_hash)+" with tag "+RNS.prettyhexrep(unique_tag), RNS.LOG_WARNING)
RNS.log("Ignoring duplicate path request for "+RNS.prettyhexrep(destination_hash)+" with tag "+RNS.prettyhexrep(unique_tag), RNS.LOG_DEBUG)
else:
# TODO: Reset this to debug level
RNS.log("Ignoring tagless path request for "+RNS.prettyhexrep(destination_hash), RNS.LOG_WARNING)
RNS.log("Ignoring tagless path request for "+RNS.prettyhexrep(destination_hash), RNS.LOG_DEBUG)
except Exception as e:
RNS.log("Error while handling path request. The contained exception was: "+str(e), RNS.LOG_ERROR)
+21 -13
View File
@@ -34,7 +34,7 @@ APP_NAME = "rncp"
allow_all = False
allowed_identity_hashes = []
def receive(configdir, verbosity = 0, quietness = 0, allowed = [], display_identity = False, limit = None, disable_auth = None,disable_announce=False):
def receive(configdir, verbosity = 0, quietness = 0, allowed = [], display_identity = False, limit = None, disable_auth = None, disable_announce = False):
global allow_all, allowed_identity_hashes
identity = None
@@ -96,21 +96,29 @@ def receive_link_established(link):
link.set_resource_concluded_callback(receive_resource_concluded)
def receive_sender_identified(link, identity):
global allow_all
if identity.hash in allowed_identity_hashes:
RNS.log("Authenticated sender", RNS.LOG_VERBOSE)
else:
RNS.log("Sender not allowed, tearing down link", RNS.LOG_VERBOSE)
link.teardown()
if not allow_all:
RNS.log("Sender not allowed, tearing down link", RNS.LOG_VERBOSE)
link.teardown()
else:
pass
def receive_resource_callback(resource):
global allow_all
sender_identity = resource.link.get_remote_identity()
if sender_identity != None:
if sender_identity.hash in allowed_identity_hashes:
print("Allowing sender")
return True
print("Rejecting sender")
if allow_all:
return True
return False
def receive_resource_started(resource):
@@ -212,7 +220,7 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
temp_file.write(real_file.read())
temp_file.seek(0)
print("\r \r", end="")
print("\r \r", end="")
reticulum = RNS.Reticulum(configdir=configdir, loglevel=targetloglevel)
@@ -240,10 +248,10 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
i = (i+1)%len(syms)
if not RNS.Transport.has_path(destination_hash):
print("\r \rPath not found")
print("\r \rPath not found")
exit(1)
else:
print("\r \rEstablishing link with "+RNS.prettyhexrep(destination_hash)+" ", end=" ")
print("\r \rEstablishing link with "+RNS.prettyhexrep(destination_hash)+" ", end=" ")
receiver_identity = RNS.Identity.recall(destination_hash)
receiver_destination = RNS.Destination(
@@ -262,10 +270,10 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
i = (i+1)%len(syms)
if not RNS.Transport.has_path(destination_hash):
print("\r \rCould not establish link with "+RNS.prettyhexrep(destination_hash))
print("\r \rCould not establish link with "+RNS.prettyhexrep(destination_hash))
exit(1)
else:
print("\r \rAdvertising file resource ", end=" ")
print("\r \rAdvertising file resource ", end=" ")
link.identify(identity)
resource = RNS.Resource(temp_file, link, callback = sender_progress, progress_callback = sender_progress)
@@ -279,10 +287,10 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
if resource.status > RNS.Resource.COMPLETE:
print("\r \rFile was not accepted by "+RNS.prettyhexrep(destination_hash))
print("\r \rFile was not accepted by "+RNS.prettyhexrep(destination_hash))
exit(1)
else:
print("\r \rTransferring file ", end=" ")
print("\r \rTransferring file ", end=" ")
while not resource_done:
time.sleep(0.1)
@@ -294,7 +302,7 @@ def send(configdir, verbosity = 0, quietness = 0, destination = None, file = Non
i = (i+1)%len(syms)
if current_resource.status != RNS.Resource.COMPLETE:
print("\r \rThe transfer failed")
print("\r \rThe transfer failed")
exit(1)
else:
print("\r \r"+str(file_path)+" copied to "+RNS.prettyhexrep(destination_hash))
+23 -6
View File
@@ -337,13 +337,15 @@ def execute(configdir, identitypath = None, verbosity = 0, quietness = 0, detail
if link == None or link.status == RNS.Link.CLOSED or link.status == RNS.Link.PENDING:
link = RNS.Link(listener_destination)
link.did_identify = False
if not spin(until=lambda: link.status == RNS.Link.ACTIVE, msg="Establishing link with "+RNS.prettyhexrep(destination_hash), timeout=timeout):
print("Could not establish link with "+RNS.prettyhexrep(destination_hash))
exit(243)
if not noid:
if not noid and not link.did_identify:
link.identify(identity)
link.did_identify = True
if stdin != None:
stdin = stdin.encode("utf-8")
@@ -380,7 +382,10 @@ def execute(configdir, identitypath = None, verbosity = 0, quietness = 0, detail
if request_receipt.status == RNS.RequestReceipt.FAILED:
print("Could not request remote execution")
exit(244)
if interactive:
return
else:
exit(244)
spin(
until=lambda:request_receipt.status != RNS.RequestReceipt.DELIVERED,
@@ -390,7 +395,10 @@ def execute(configdir, identitypath = None, verbosity = 0, quietness = 0, detail
if request_receipt.status == RNS.RequestReceipt.FAILED:
print("No result was received")
exit(245)
if interactive:
return
else:
exit(245)
spin_stat(
until=lambda:request_receipt.status != RNS.RequestReceipt.RECEIVING,
@@ -399,7 +407,10 @@ def execute(configdir, identitypath = None, verbosity = 0, quietness = 0, detail
if request_receipt.status == RNS.RequestReceipt.FAILED:
print("Receiving result failed")
exit(246)
if interactive:
return
else:
exit(246)
if request_receipt.response != None:
try:
@@ -414,7 +425,10 @@ def execute(configdir, identitypath = None, verbosity = 0, quietness = 0, detail
except Exception as e:
print("Received invalid result")
exit(247)
if interactive:
return
else:
exit(247)
if executed:
if detailed:
@@ -484,7 +498,10 @@ def execute(configdir, identitypath = None, verbosity = 0, quietness = 0, detail
exit(248)
else:
print("No response")
exit(249)
if interactive:
return
else:
exit(249)
try:
if not interactive:
+51
View File
@@ -172,6 +172,57 @@ def prettysize(num, suffix='B'):
return "%.2f%s%s" % (num, last_unit, suffix)
def prettytime(time, verbose=False):
days = int(time // (24 * 3600))
time = time % (24 * 3600)
hours = int(time // 3600)
time %= 3600
minutes = int(time // 60)
time %= 60
seconds = round(time, 2)
ss = "" if seconds == 1 else "s"
sm = "" if minutes == 1 else "s"
sh = "" if hours == 1 else "s"
sd = "" if days == 1 else "s"
components = []
if days > 0:
components.append(str(days)+" day"+sd if verbose else str(days)+"d")
if hours > 0:
components.append(str(hours)+" hour"+sh if verbose else str(hours)+"h")
if minutes > 0:
components.append(str(minutes)+" minute"+sm if verbose else str(minutes)+"m")
if seconds > 0:
components.append(str(seconds)+" second"+ss if verbose else str(seconds)+"s")
i = 0
tstr = ""
for c in components:
i += 1
if i == 1:
pass
elif i < len(components):
tstr += ", "
elif i == len(components):
tstr += " and "
tstr += c
return tstr
def phyparams():
print("Required Physical Layer MTU : "+str(Reticulum.MTU)+" bytes")
print("Plaintext Packet MDU : "+str(Packet.PLAIN_MDU)+" bytes")
print("Encrypted Packet MDU : "+str(Packet.ENCRYPTED_MDU)+" bytes")
print("Link Curve : "+str(Link.CURVE))
print("Link Packet MDU : "+str(Packet.ENCRYPTED_MDU)+" bytes")
print("Link Public Key Size : "+str(Link.ECPUBSIZE*8)+" bits")
print("Link Private Key Size : "+str(Link.KEYSIZE*8)+" bits")
def panic():
os._exit(255)
+1 -1
View File
@@ -1 +1 @@
__version__ = "0.3.8"
__version__ = "0.3.9"
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: 450b6695e9c51c393c691ba688e02b3c
config: d4963122ff51d6bca74c9598f37a0cc1
tags: 645f666f9bcd5a90fca523b33c5a78b7
@@ -161,20 +161,25 @@ by adding one of the following interfaces to your ``.reticulum/config`` file:
.. code::
# For connecting over TCP/IP:
[[RNS Testnet Frankfurt]]
# TCP/IP interface to the Dublin hub
[[RNS Testnet Dublin]]
type = TCPClientInterface
interface_enabled = yes
outgoing = True
target_host = frankfurt.rns.unsigned.io
enabled = yes
target_host = dublin.connect.reticulum.network
target_port = 4965
# TCP/IP interface to the Frankfurt hub
[[RNS Testnet Dublin]]
type = TCPClientInterface
enabled = yes
target_host = frankfurt.connect.reticulum.network
target_port = 5377
# For connecting over I2P:
[[RNS Testnet I2P Node A]]
# Interface to I2P hub A
[[RNS Testnet I2P Hub A]]
type = I2PInterface
interface_enabled = yes
peers = ykzlw5ujbaqc2xkec4cpvgyxj257wcrmmgkuxqmqcur7cq3w3lha.b32.i2p
enabled = yes
peers = uxg5kubabakh3jtnvsipingbr5574dle7bubvip7llfvwx2tgrua.b32.i2p
Many other Reticulum instances are connecting to this testnet, and you can also join it
via other entry points if you know them. There is absolutely no control over the network
+1 -1
View File
@@ -681,7 +681,7 @@ the default mode.
other nodes in the network. As an example, if a vehicle is
equipped with an external LoRa interface, and an internal,
WiFi-based interface, that serves devices that are moving
_with_ the vehicle, the external LoRa interface should be
*with* the vehicle, the external LoRa interface should be
configured as ``roaming``, and the internal interface can
be left in the default mode. With transport enabled, such
a setup will allow all internal devices to reach each other,
+1 -3
View File
@@ -14,9 +14,7 @@ Donations are gratefully accepted via the following channels:
.. code:: text
Monero:
84FpY1QbxHcgdseePYNmhTHcrgMX4nFf
BYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD1
9b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
Ethereum:
0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a
+29 -29
View File
@@ -117,29 +117,29 @@ Reticulum uses the singular concept of *destinations*. Any application using Ret
networking stack will need to create one or more destinations to receive data, and know the
destinations it needs to send data to.
All destinations in Reticulum are represented as a 10 byte hash, derived from truncating a full
All destinations in Reticulum are _represented_ as a 16 byte hash. This hash is derived from truncating a full
SHA-256 hash of identifying characteristics of the destination. To users, the destination addresses
will be displayed as 10 bytes in hexadecimal representation, as in the following example: ``<80e29bf7cccaf31431b3>``.
will be displayed as 16 hexadecimal bytes, like this example: ``<13425ec15b621c1d928589718000d814>``.
The truncation size of 10 bytes (80 bits) for destinations has been choosen as a reasonable tradeoff between address space
The truncation size of 16 bytes (128 bits) for destinations has been choosen as a reasonable tradeoff
between address space
and packet overhead. The address space accomodated by this size can support many billions of
simultaneously active devices on the same network, while keeping packet overhead low, which is
essential on low-bandwidth networks. In the very unlikely case that this address space nears
congestion, a one-line code change can upgrade the Reticulum address space all the way up to 256
bits, ensuring the Reticulum address space could potentially support galactic-scale networks.
This is obviusly complete and ridiculous over-allocation, and as such, the current 80 bits should
This is obviusly complete and ridiculous over-allocation, and as such, the current 128 bits should
be sufficient, even far into the future.
By default Reticulum encrypts all data using elliptic curve cryptography. Any packet sent to a
destination is encrypted with a derived ephemeral key. Reticulum can also set up an encrypted
channel to a destination with *Forward Secrecy* and *Initiator Anonymity* using a elliptic
curve cryptography and ephemeral keys derived from a Diffie Hellman exchange on Curve25519. In
Reticulum terminology, this is called a *Link*. The multi-hop transport, coordination, verification
channel to a destination, called a *Link*. Both data sent over Links and single packets offer
*Forward Secrecy* and *Initiator Anonymity*, by using an Elliptic Curve Diffie Hellman key exchange
on Curve25519 to derive ephemeral keys. The multi-hop transport, coordination, verification
and reliability layers are fully autonomous and also based on elliptic curve cryptography.
Reticulum also offers symmetric key encryption for group-oriented communications, as well as
unencrypted packets for broadcast purposes, or situations where you need the communication to be in
plain text.
unencrypted packets for local broadcast purposes.
Reticulum can connect to a variety of interfaces such as radio modems, data radios and serial ports,
and offers the possibility to easily tunnel Reticulum traffic over IP links such as the Internet or
@@ -186,7 +186,7 @@ Destination Naming
^^^^^^^^^^^^^^^^^^
Destinations are created and named in an easy to understand dotted notation of *aspects*, and
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 80 bits. The
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 128 bits. The
top level aspect should always be a unique identifier for the application using the destination.
The next levels of aspects can be defined in any way by the creator of the application.
@@ -202,7 +202,7 @@ application name, a device type and measurement type, like this:
aspects : remotesensor, temperature
full name : environmentlogger.remotesensor.temperature
hash : fa7ddfab5213f916dea
hash : 4faf1b2e0a077e6a9d92fa051f256038
For the *single* destination, Reticulum will automatically append the associated public key as a
destination aspect before hashing. This is done to ensure only the correct destination is reached,
@@ -493,10 +493,10 @@ terms of bandwidth, so it can be used just for a short exchange, and then recrea
also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is
more suitable to the application. The procedure also inserts the *link id* , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this *link id*.
The combined bandwidth cost of setting up a link is 3 packets totalling 237 bytes (more info in the
The combined bandwidth cost of setting up a link is 3 packets totalling 265 bytes (more info in the
:ref:`Binary Packet Format<understanding-packetformat>` section). The amount of bandwidth used on keeping
a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
a link open is practically negligible, at 0.45 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 96% channel capacity for actual data.
Link Establishment in Detail
@@ -683,7 +683,7 @@ Wire Format
A Reticulum packet is composed of the following fields:
[HEADER 2 bytes] [ADDRESSES 10/20 bytes] [CONTEXT 1 byte] [DATA 0-477 bytes]
[HEADER 2 bytes] [ADDRESSES 16/32 bytes] [CONTEXT 1 byte] [DATA 0-465 bytes]
* The HEADER field is 2 bytes long.
* Byte 1: [IFAC Flag], [Header Type], [Propagation Type], [Destination Type] and [Packet Type]
@@ -695,15 +695,15 @@ Wire Format
capabilities and configuration.
* The ADDRESSES field contains either 1 or 2 addresses.
* Each address is 10 bytes long.
* Each address is 16 bytes long.
* The Header Type flag in the HEADER field determines
whether the ADDRESSES field contains 1 or 2 addresses.
* Addresses are Reticulum hashes truncated to 10 bytes.
* Addresses are SHA-256 hashes truncated to 16 bytes.
* The CONTEXT field is 1 byte.
* It is used by Reticulum to determine packet context.
* The DATA field is between 0 and 477 bytes.
* The DATA field is between 0 and 465 bytes.
* It contains the packets data payload.
IFAC Flag
@@ -714,8 +714,8 @@ Wire Format
Header Types
-----------------
type 1 0 Two byte header, one 10 byte address field
type 2 1 Two byte header, two 10 byte address fields
type 1 0 Two byte header, one 16 byte address field
type 2 1 Two byte header, two 16 byte address fields
Propagation Types
@@ -747,7 +747,7 @@ Wire Format
HEADER FIELD DESTINATION FIELDS CONTEXT FIELD DATA FIELD
_______|_______ ________________|________________ ________|______ __|_
| | | | | | | |
01010000 00000100 [HASH1, 10 bytes] [HASH2, 10 bytes] [CONTEXT, 1 byte] [DATA]
01010000 00000100 [HASH1, 16 bytes] [HASH2, 16 bytes] [CONTEXT, 1 byte] [DATA]
|| | | | |
|| | | | +-- Hops = 4
|| | | +------- Packet Type = DATA
@@ -762,7 +762,7 @@ Wire Format
HEADER FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
_______|_______ _______|_______ ________|______ __|_
| | | | | | | |
00000000 00000111 [HASH1, 10 bytes] [CONTEXT, 1 byte] [DATA]
00000000 00000111 [HASH1, 16 bytes] [CONTEXT, 1 byte] [DATA]
|| | | | |
|| | | | +-- Hops = 0
|| | | +------- Packet Type = DATA
@@ -777,7 +777,7 @@ Wire Format
HEADER FIELD IFAC FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
_______|_______ ______|______ _______|_______ ________|______ __|_
| | | | | | | | | |
10000000 00000111 [IFAC, N bytes] [HASH1, 10 bytes] [CONTEXT, 1 byte] [DATA]
10000000 00000111 [IFAC, N bytes] [HASH1, 16 bytes] [CONTEXT, 1 byte] [DATA]
|| | | | |
|| | | | +-- Hops = 0
|| | | +------- Packet Type = DATA
@@ -795,12 +795,12 @@ Wire Format
wire size counting all fields including headers,
but excluding any interface access codes.
- Path Request : 33 bytes
- Announce : 151 bytes
- Link Request : 77 bytes
- Link Proof : 77 bytes
- Link RTT packet : 83 bytes
- Link keepalive : 14 bytes
- Path Request : 51 bytes
- Announce : 157 bytes
- Link Request : 83 bytes
- Link Proof : 83 bytes
- Link RTT packet : 99 bytes
- Link keepalive : 20 bytes
.. _understanding-announcepropagation:
+13 -13
View File
@@ -223,7 +223,7 @@ interfaces, similar to the ``ifconfig`` program.
Traffic : 8.49 KB↑
9.23 KB↓
Reticulum Transport Instance <5245a8efe1788c6a70e1> running
Reticulum Transport Instance <5245a8efe1788c6a1cd36144a270e13b> running
.. code:: text
@@ -248,10 +248,10 @@ destinations on the Reticulum network.
.. code:: text
# Run rnpath
rnpath eca6f4e4dc26ae329e61
rnpath c89b4da064bf66d280f0e4d8abfd9806
# Example output
Path found, destination <eca6f4e4dc26ae329e61> is 4 hops away via <56b115c30cd386cad69c> on TCPInterface[Testnet/frankfurt.rns.unsigned.io:4965]
Path found, destination <c89b4da064bf66d280f0e4d8abfd9806> is 4 hops away via <f53a1c4278e0726bb73fcc623d6ce763> on TCPInterface[Testnet/frankfurt.connect.reticulu.network:4965]
.. code:: text
@@ -285,11 +285,11 @@ destinations will not have this option enabled, and will not be probable.
.. code:: text
# Run rnprobe
rnprobe example_utilities.echo.request 9382f334de63217a4278
rnprobe example_utilities.echo.request 2d03725b327348980d570f739a3a5708
# Example output
Sent 16 byte probe to <9382f334de63217a4278>
Valid reply received from <9382f334de63217a4278>
Sent 16 byte probe to <2d03725b327348980d570f739a3a5708>
Valid reply received from <2d03725b327348980d570f739a3a5708>
Round-trip time is 38.469 milliseconds over 2 hops
.. code:: text
@@ -319,10 +319,10 @@ files through Reticulum.
# Run rncp on the receiving system, specifying which identities
# are allowed to send files
rncp --receive -a 940ea3f9e1037d38758f -a e28d5aee4317c24a9041
rncp --receive -a 1726dbad538775b5bf9b0ea25a4079c8 -a c50cc4e4f7838b6c31f60ab9032cbc62
# From another system, copy a file to the receiving system
rncp ~/path/to/file.tgz 256320d405d6d525d1e9
rncp ~/path/to/file.tgz 73cbd378bb0286ed11a707c13447bb1e
You can specify as many allowed senders as needed, or complete disable authentication.
@@ -362,21 +362,21 @@ output.
# Run rnx on the listening system, specifying which identities
# are allowed to execute commands
rncp --listen -a 8111c4ff2968ab0c1286 -a 590256654482b4ba4038
rncp --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
# From another system, run a command
rnx ad9a4c9da60089d41c29 "cat /proc/cpuinfo"
rnx 7a55144adf826958a9529a3bcf08b149 "cat /proc/cpuinfo"
# Or enter the interactive mode pseudo-shell
rnx ad9a4c9da60089d41c29 -x
rnx 7a55144adf826958a9529a3bcf08b149 -x
# The default identity file is stored in
# ~/.reticulum/identities/rnx, but you can use
# another one, which will be created if it does
# not already exist
rnx ad9a4c9da60089d41c29 -i /path/to/identity
rnx 7a55144adf826958a9529a3bcf08b149 -i /path/to/identity -x
You can specify as many allowed senders as needed, or complete disable authentication.
You can specify as many allowed senders as needed, or completely disable authentication.
.. code:: text
+3 -3
View File
@@ -46,11 +46,11 @@ What does Reticulum Offer?
* Efficient link establishment
* Total bandwidth cost of setting up a link is only 3 packets, totalling 237 bytes
* Total bandwidth cost of setting up a link is only 3 packets, totalling 265 bytes
* Low cost of keeping links open at only 0.62 bits per second
* Low cost of keeping links open at only 0.44 bits per second
* Reliable and efficient transfer of arbritrary amounts of data
* Reliable and efficient transfer of arbitrary amounts of data
* Reticulum can handle a few bytes of data or files of many gigabytes
+1 -1
View File
@@ -1,6 +1,6 @@
var DOCUMENTATION_OPTIONS = {
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
VERSION: '0.3.8 beta',
VERSION: '0.3.9 beta',
LANGUAGE: 'None',
COLLAPSE_INDEX: false,
BUILDER: 'html',
+44 -16
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Code Examples &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Code Examples &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -16,6 +16,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="API Reference" href="reference.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
@@ -24,10 +25,13 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="support.html" title="Support Reticulum"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="reference.html" title="API Reference"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Code Examples</a></li>
</ul>
</div>
@@ -586,14 +590,16 @@ the Packet interface.</p>
<span class="c1"># We need a binary representation of the destination</span>
<span class="c1"># hash that was entered on the command line</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">20</span><span class="p">:</span>
<span class="n">dest_len</span> <span class="o">=</span> <span class="p">(</span><span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="o">.</span><span class="n">TRUNCATED_HASHLENGTH</span><span class="o">//</span><span class="mi">8</span><span class="p">)</span><span class="o">*</span><span class="mi">2</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="n">dest_len</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;Destination length is invalid, must be 20 hexadecimal characters (10 bytes)&quot;</span>
<span class="s2">&quot;Destination length is invalid, must be </span><span class="si">{hex}</span><span class="s2"> hexadecimal characters (</span><span class="si">{byte}</span><span class="s2"> bytes).&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">hex</span><span class="o">=</span><span class="n">dest_len</span><span class="p">,</span> <span class="n">byte</span><span class="o">=</span><span class="n">dest_len</span><span class="o">//</span><span class="mi">2</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">destination_hash</span> <span class="o">=</span> <span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span>
<span class="k">except</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;Invalid destination entered. Check your input!</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</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;Invalid destination entered. Check your input!&quot;</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="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">+</span><span class="s2">&quot;</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
<span class="n">exit</span><span class="p">()</span>
<span class="c1"># We must first initialise Reticulum</span>
@@ -912,8 +918,12 @@ destination, and passing traffic back and forth over the link.</p>
<span class="c1"># We need a binary representation of the destination</span>
<span class="c1"># hash that was entered on the command line</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">20</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Destination length is invalid, must be 20 hexadecimal characters (10 bytes)&quot;</span><span class="p">)</span>
<span class="n">dest_len</span> <span class="o">=</span> <span class="p">(</span><span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="o">.</span><span class="n">TRUNCATED_HASHLENGTH</span><span class="o">//</span><span class="mi">8</span><span class="p">)</span><span class="o">*</span><span class="mi">2</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="n">dest_len</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;Destination length is invalid, must be </span><span class="si">{hex}</span><span class="s2"> hexadecimal characters (</span><span class="si">{byte}</span><span class="s2"> bytes).&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">hex</span><span class="o">=</span><span class="n">dest_len</span><span class="p">,</span> <span class="n">byte</span><span class="o">=</span><span class="n">dest_len</span><span class="o">//</span><span class="mi">2</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">destination_hash</span> <span class="o">=</span> <span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span>
<span class="k">except</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;Invalid destination entered. Check your input!</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
@@ -1181,7 +1191,7 @@ the link has been established.</p>
<span class="k">def</span> <span class="nf">client_disconnected</span><span class="p">(</span><span class="n">link</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;Client disconnected&quot;</span><span class="p">)</span>
<span class="k">def</span> <span class="nf">remote_identified</span><span class="p">(</span><span class="n">identity</span><span class="p">):</span>
<span class="k">def</span> <span class="nf">remote_identified</span><span class="p">(</span><span class="n">link</span><span class="p">,</span> <span class="n">identity</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;Remote identified as: &quot;</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">identity</span><span class="p">))</span>
<span class="k">def</span> <span class="nf">server_packet_received</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
@@ -1221,8 +1231,12 @@ the link has been established.</p>
<span class="c1"># We need a binary representation of the destination</span>
<span class="c1"># hash that was entered on the command line</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">20</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Destination length is invalid, must be 20 hexadecimal characters (10 bytes)&quot;</span><span class="p">)</span>
<span class="n">dest_len</span> <span class="o">=</span> <span class="p">(</span><span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="o">.</span><span class="n">TRUNCATED_HASHLENGTH</span><span class="o">//</span><span class="mi">8</span><span class="p">)</span><span class="o">*</span><span class="mi">2</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="n">dest_len</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;Destination length is invalid, must be </span><span class="si">{hex}</span><span class="s2"> hexadecimal characters (</span><span class="si">{byte}</span><span class="s2"> bytes).&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">hex</span><span class="o">=</span><span class="n">dest_len</span><span class="p">,</span> <span class="n">byte</span><span class="o">=</span><span class="n">dest_len</span><span class="o">//</span><span class="mi">2</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">destination_hash</span> <span class="o">=</span> <span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span>
<span class="k">except</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;Invalid destination entered. Check your input!</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
@@ -1524,8 +1538,12 @@ the link has been established.</p>
<span class="c1"># We need a binary representation of the destination</span>
<span class="c1"># hash that was entered on the command line</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">20</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Destination length is invalid, must be 20 hexadecimal characters (10 bytes)&quot;</span><span class="p">)</span>
<span class="n">dest_len</span> <span class="o">=</span> <span class="p">(</span><span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="o">.</span><span class="n">TRUNCATED_HASHLENGTH</span><span class="o">//</span><span class="mi">8</span><span class="p">)</span><span class="o">*</span><span class="mi">2</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="n">dest_len</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;Destination length is invalid, must be </span><span class="si">{hex}</span><span class="s2"> hexadecimal characters (</span><span class="si">{byte}</span><span class="s2"> bytes).&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">hex</span><span class="o">=</span><span class="n">dest_len</span><span class="p">,</span> <span class="n">byte</span><span class="o">=</span><span class="n">dest_len</span><span class="o">//</span><span class="mi">2</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">destination_hash</span> <span class="o">=</span> <span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span>
<span class="k">except</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;Invalid destination entered. Check your input!</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
@@ -1921,8 +1939,12 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
<span class="c1"># We need a binary representation of the destination</span>
<span class="c1"># hash that was entered on the command line</span>
<span class="k">try</span><span class="p">:</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="mi">20</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span><span class="s2">&quot;Destination length is invalid, must be 20 hexadecimal characters (10 bytes)&quot;</span><span class="p">)</span>
<span class="n">dest_len</span> <span class="o">=</span> <span class="p">(</span><span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="o">.</span><span class="n">TRUNCATED_HASHLENGTH</span><span class="o">//</span><span class="mi">8</span><span class="p">)</span><span class="o">*</span><span class="mi">2</span>
<span class="k">if</span> <span class="nb">len</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span> <span class="o">!=</span> <span class="n">dest_len</span><span class="p">:</span>
<span class="k">raise</span> <span class="ne">ValueError</span><span class="p">(</span>
<span class="s2">&quot;Destination length is invalid, must be </span><span class="si">{hex}</span><span class="s2"> hexadecimal characters (</span><span class="si">{byte}</span><span class="s2"> bytes).&quot;</span><span class="o">.</span><span class="n">format</span><span class="p">(</span><span class="nb">hex</span><span class="o">=</span><span class="n">dest_len</span><span class="p">,</span> <span class="n">byte</span><span class="o">=</span><span class="n">dest_len</span><span class="o">//</span><span class="mi">2</span><span class="p">)</span>
<span class="p">)</span>
<span class="n">destination_hash</span> <span class="o">=</span> <span class="nb">bytes</span><span class="o">.</span><span class="n">fromhex</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">)</span>
<span class="k">except</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;Invalid destination entered. Check your input!</span><span class="se">\n</span><span class="s2">&quot;</span><span class="p">)</span>
@@ -2336,6 +2358,9 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
<h4>Previous topic</h4>
<p class="topless"><a href="reference.html"
title="previous chapter">API Reference</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="support.html"
title="next chapter">Support Reticulum</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
@@ -2363,10 +2388,13 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="support.html" title="Support Reticulum"
>next</a> |</li>
<li class="right" >
<a href="reference.html" title="API Reference"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Code Examples</a></li>
</ul>
</div>
+3 -3
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Index &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Index &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -23,7 +23,7 @@
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
accesskey="I">index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Index</a></li>
</ul>
</div>
@@ -440,7 +440,7 @@
<li class="right" style="margin-right: 10px">
<a href="#" title="General Index"
>index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Index</a></li>
</ul>
</div>
+17 -12
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Getting Started Fast &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Getting Started Fast &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -31,7 +31,7 @@
<li class="right" >
<a href="whatis.html" title="What is Reticulum?"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
</ul>
</div>
@@ -164,20 +164,25 @@ easier setup, use TCP.</p>
<h2>Connect to the Public Testnet<a class="headerlink" href="#connect-to-the-public-testnet" title="Permalink to this headline"></a></h2>
<p>An experimental public testnet has been made accessible over both I2P and TCP. You can join it
by adding one of the following interfaces to your <code class="docutils literal notranslate"><span class="pre">.reticulum/config</span></code> file:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># For connecting over TCP/IP:</span>
<span class="p">[[</span><span class="n">RNS</span> <span class="n">Testnet</span> <span class="n">Frankfurt</span><span class="p">]]</span>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># TCP/IP interface to the Dublin 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="nb">type</span> <span class="o">=</span> <span class="n">TCPClientInterface</span>
<span class="n">interface_enabled</span> <span class="o">=</span> <span class="n">yes</span>
<span class="n">outgoing</span> <span class="o">=</span> <span class="kc">True</span>
<span class="n">target_host</span> <span class="o">=</span> <span class="n">frankfurt</span><span class="o">.</span><span class="n">rns</span><span class="o">.</span><span class="n">unsigned</span><span class="o">.</span><span class="n">io</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">dublin</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>
<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="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>
<span class="n">target_port</span> <span class="o">=</span> <span class="mi">5377</span>
<span class="c1"># For connecting over I2P:</span>
<span class="p">[[</span><span class="n">RNS</span> <span class="n">Testnet</span> <span class="n">I2P</span> <span class="n">Node</span> <span class="n">A</span><span class="p">]]</span>
<span class="c1"># Interface to I2P hub A</span>
<span class="p">[[</span><span class="n">RNS</span> <span class="n">Testnet</span> <span class="n">I2P</span> <span class="n">Hub</span> <span class="n">A</span><span class="p">]]</span>
<span class="nb">type</span> <span class="o">=</span> <span class="n">I2PInterface</span>
<span class="n">interface_enabled</span> <span class="o">=</span> <span class="n">yes</span>
<span class="n">peers</span> <span class="o">=</span> <span class="n">ykzlw5ujbaqc2xkec4cpvgyxj257wcrmmgkuxqmqcur7cq3w3lha</span><span class="o">.</span><span class="n">b32</span><span class="o">.</span><span class="n">i2p</span>
<span class="n">enabled</span> <span class="o">=</span> <span class="n">yes</span>
<span class="n">peers</span> <span class="o">=</span> <span class="n">uxg5kubabakh3jtnvsipingbr5574dle7bubvip7llfvwx2tgrua</span><span class="o">.</span><span class="n">b32</span><span class="o">.</span><span class="n">i2p</span>
</pre></div>
</div>
<p>Many other Reticulum instances are connecting to this testnet, and you can also join it
@@ -414,7 +419,7 @@ section of this manual.</p>
<li class="right" >
<a href="whatis.html" title="What is Reticulum?"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
</ul>
</div>
+3 -3
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Communications Hardware &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Communications Hardware &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -31,7 +31,7 @@
<li class="right" >
<a href="understanding.html" title="Understanding Reticulum"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Communications Hardware</a></li>
</ul>
</div>
@@ -307,7 +307,7 @@ connectivity for client devices.</p>
<li class="right" >
<a href="understanding.html" title="Understanding Reticulum"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Communications Hardware</a></li>
</ul>
</div>
+3 -3
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Reticulum Network Stack Manual &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Reticulum Network Stack Manual &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -27,7 +27,7 @@
<li class="right" >
<a href="whatis.html" title="What is Reticulum?"
accesskey="N">next</a> |</li>
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
</ul>
</div>
@@ -246,7 +246,7 @@ to participate in the development of Reticulum itself.</p>
<li class="right" >
<a href="whatis.html" title="What is Reticulum?"
>next</a> |</li>
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
</ul>
</div>
+14 -14
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Supported Interfaces &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Supported Interfaces &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -16,8 +16,8 @@
<link rel="index" title="Index" href="genindex.html" />
<link rel="search" title="Search" href="search.html" />
<link rel="next" title="Communication Hardware" href="hardware.html" />
<link rel="prev" title="Building Networks" href="networks.html" />
<link rel="next" title="Building Networks" href="networks.html" />
<link rel="prev" title="Communications Hardware" href="hardware.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@@ -26,12 +26,12 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="hardware.html" title="Communication Hardware"
<a href="networks.html" title="Building Networks"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="networks.html" title="Building Networks"
<a href="hardware.html" title="Communications Hardware"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Supported Interfaces</a></li>
</ul>
</div>
@@ -669,7 +669,7 @@ roaming (physically mobile), seen from the perspective of
other nodes in the network. As an example, if a vehicle is
equipped with an external LoRa interface, and an internal,
WiFi-based interface, that serves devices that are moving
_with_ the vehicle, the external LoRa interface should be
<em>with</em> the vehicle, the external LoRa interface should be
configured as <code class="docutils literal notranslate"><span class="pre">roaming</span></code>, and the internal interface can
be left in the default mode. With transport enabled, such
a setup will allow all internal devices to reach each other,
@@ -773,11 +773,11 @@ that a large span of network types can seamlessly <em>co-exist</em> and intercon
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="networks.html"
title="previous chapter">Building Networks</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="hardware.html"
title="next chapter">Communication Hardware</a></p>
title="previous chapter">Communications Hardware</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="networks.html"
title="next chapter">Building Networks</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
@@ -806,12 +806,12 @@ that a large span of network types can seamlessly <em>co-exist</em> and intercon
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="hardware.html" title="Communication Hardware"
<a href="networks.html" title="Building Networks"
>next</a> |</li>
<li class="right" >
<a href="networks.html" title="Building Networks"
<a href="hardware.html" title="Communications Hardware"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Supported Interfaces</a></li>
</ul>
</div>
+13 -13
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Building Networks &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Building Networks &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -16,8 +16,8 @@
<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="Using Reticulum on Your System" href="using.html" />
<link rel="next" title="API Reference" href="reference.html" />
<link rel="prev" title="Supported Interfaces" href="interfaces.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@@ -26,12 +26,12 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="interfaces.html" title="Supported Interfaces"
<a href="reference.html" title="API Reference"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="using.html" title="Using Reticulum on Your System"
<a href="interfaces.html" title="Supported Interfaces"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Building Networks</a></li>
</ul>
</div>
@@ -234,11 +234,11 @@ connected outliers are now an integral part of the network.</p>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="using.html"
title="previous chapter">Using Reticulum on Your System</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="interfaces.html"
title="next chapter">Supported Interfaces</a></p>
title="previous chapter">Supported Interfaces</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="reference.html"
title="next chapter">API Reference</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
@@ -267,12 +267,12 @@ connected outliers are now an integral part of the network.</p>
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="interfaces.html" title="Supported Interfaces"
<a href="reference.html" title="API Reference"
>next</a> |</li>
<li class="right" >
<a href="using.html" title="Using Reticulum on Your System"
<a href="interfaces.html" title="Supported Interfaces"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Building Networks</a></li>
</ul>
</div>
+10 -10
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>API Reference &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>API Reference &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -17,7 +17,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="Understanding Reticulum" href="understanding.html" />
<link rel="prev" title="Building Networks" href="networks.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@@ -29,9 +29,9 @@
<a href="examples.html" title="Code Examples"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="understanding.html" title="Understanding Reticulum"
<a href="networks.html" title="Building Networks"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">API Reference</a></li>
</ul>
</div>
@@ -157,7 +157,7 @@ for all encrypted communication over Reticulum networks.</p>
<dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Identity.TRUNCATED_HASHLENGTH">
<span class="sig-name descname"><span class="pre">TRUNCATED_HASHLENGTH</span></span><em class="property"> <span class="pre">=</span> <span class="pre">80</span></em><a class="headerlink" href="#RNS.Identity.TRUNCATED_HASHLENGTH" title="Permalink to this definition"></a></dt>
<span class="sig-name descname"><span class="pre">TRUNCATED_HASHLENGTH</span></span><em class="property"> <span class="pre">=</span> <span class="pre">128</span></em><a class="headerlink" href="#RNS.Identity.TRUNCATED_HASHLENGTH" title="Permalink to this definition"></a></dt>
<dd><p>Constant specifying the truncated hash length (in bits) used by Reticulum
for addressable hashes and other purposes. Non-configurable.</p>
</dd></dl>
@@ -702,7 +702,7 @@ destinations, reticulum will use ephemeral keys, and offers <strong>Forward Secr
<dl class="py attribute">
<dt class="sig sig-object py" id="RNS.Packet.PLAIN_MDU">
<span class="sig-name descname"><span class="pre">PLAIN_MDU</span></span><em class="property"> <span class="pre">=</span> <span class="pre">476</span></em><a class="headerlink" href="#RNS.Packet.PLAIN_MDU" title="Permalink to this definition"></a></dt>
<span class="sig-name descname"><span class="pre">PLAIN_MDU</span></span><em class="property"> <span class="pre">=</span> <span class="pre">464</span></em><a class="headerlink" href="#RNS.Packet.PLAIN_MDU" title="Permalink to this definition"></a></dt>
<dd><p>The maximum size of the payload data in a single unencrypted packet</p>
</dd></dl>
@@ -1328,8 +1328,8 @@ will announce it.</p>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="understanding.html"
title="previous chapter">Understanding Reticulum</a></p>
<p class="topless"><a href="networks.html"
title="previous chapter">Building Networks</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="examples.html"
title="next chapter">Code Examples</a></p>
@@ -1364,9 +1364,9 @@ will announce it.</p>
<a href="examples.html" title="Code Examples"
>next</a> |</li>
<li class="right" >
<a href="understanding.html" title="Understanding Reticulum"
<a href="networks.html" title="Building Networks"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">API Reference</a></li>
</ul>
</div>
+3 -3
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Search &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Search &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -29,7 +29,7 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Search</a></li>
</ul>
</div>
@@ -85,7 +85,7 @@
<li class="right" style="margin-right: 10px">
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Search</a></li>
</ul>
</div>
File diff suppressed because one or more lines are too long
+4 -6
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Support Reticulum &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Support Reticulum &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -27,7 +27,7 @@
<li class="right" >
<a href="examples.html" title="Code Examples"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Support Reticulum</a></li>
</ul>
</div>
@@ -45,9 +45,7 @@ systems by donating, providing feedback and contributing code and learning resou
<h2>Donations<a class="headerlink" href="#donations" title="Permalink to this headline"></a></h2>
<p>Donations are gratefully accepted via the following channels:</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>Monero:
84FpY1QbxHcgdseePYNmhTHcrgMX4nFf
BYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD1
9b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
Ethereum:
0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a
@@ -127,7 +125,7 @@ report issues, suggest functionality and contribute code to Reticulum.</p>
<li class="right" >
<a href="examples.html" title="Code Examples"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Support Reticulum</a></li>
</ul>
</div>
+42 -42
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Understanding Reticulum &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Understanding Reticulum &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -16,8 +16,8 @@
<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="Communications Hardware" href="hardware.html" />
<link rel="next" title="Communications Hardware" href="hardware.html" />
<link rel="prev" title="Using Reticulum on Your System" href="using.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
<h3>Navigation</h3>
@@ -26,12 +26,12 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="reference.html" title="API Reference"
<a href="hardware.html" title="Communications Hardware"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="hardware.html" title="Communications Hardware"
<a href="using.html" title="Using Reticulum on Your System"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
</ul>
</div>
@@ -165,26 +165,26 @@ to be transported over multiple hops in a complex network to reach the recipient
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 10 byte hash, derived from truncating a full
<p>All destinations in Reticulum are _represented_ as a 16 byte hash. This hash is derived from truncating a full
SHA-256 hash of identifying characteristics of the destination. To users, the destination addresses
will be displayed as 10 bytes in hexadecimal representation, as in the following example: <code class="docutils literal notranslate"><span class="pre">&lt;80e29bf7cccaf31431b3&gt;</span></code>.</p>
<p>The truncation size of 10 bytes (80 bits) for destinations has been choosen as a reasonable tradeoff between address space
will be displayed as 16 hexadecimal bytes, like this example: <code class="docutils literal notranslate"><span class="pre">&lt;13425ec15b621c1d928589718000d814&gt;</span></code>.</p>
<p>The truncation size of 16 bytes (128 bits) for destinations has been choosen as a reasonable tradeoff
between address space
and packet overhead. The address space accomodated by this size can support many billions of
simultaneously active devices on the same network, while keeping packet overhead low, which is
essential on low-bandwidth networks. In the very unlikely case that this address space nears
congestion, a one-line code change can upgrade the Reticulum address space all the way up to 256
bits, ensuring the Reticulum address space could potentially support galactic-scale networks.
This is obviusly complete and ridiculous over-allocation, and as such, the current 80 bits should
This is obviusly complete and ridiculous over-allocation, and as such, the current 128 bits should
be sufficient, even far into the future.</p>
<p>By default Reticulum encrypts all data using elliptic curve cryptography. Any packet sent to a
destination is encrypted with a derived ephemeral key. Reticulum can also set up an encrypted
channel to a destination with <em>Forward Secrecy</em> and <em>Initiator Anonymity</em> using a elliptic
curve cryptography and ephemeral keys derived from a Diffie Hellman exchange on Curve25519. In
Reticulum terminology, this is called a <em>Link</em>. The multi-hop transport, coordination, verification
channel to a destination, called a <em>Link</em>. Both data sent over Links and single packets offer
<em>Forward Secrecy</em> and <em>Initiator Anonymity</em>, by using an Elliptic Curve Diffie Hellman key exchange
on Curve25519 to derive ephemeral keys. The multi-hop transport, coordination, verification
and reliability layers are fully autonomous and also based on elliptic curve cryptography.</p>
<p>Reticulum also offers symmetric key encryption for group-oriented communications, as well as
unencrypted packets for broadcast purposes, or situations where you need the communication to be in
plain text.</p>
unencrypted packets for local broadcast purposes.</p>
<p>Reticulum can connect to a variety of interfaces such as radio modems, data radios and serial ports,
and offers the possibility to easily tunnel Reticulum traffic over IP links such as the Internet or
private IP networks.</p>
@@ -234,7 +234,7 @@ out requests and responses, large data transfers and more.</p>
<div class="section" id="destination-naming">
<span id="understanding-destinationnaming"></span><h4>Destination Naming<a class="headerlink" href="#destination-naming" title="Permalink to this headline"></a></h4>
<p>Destinations are created and named in an easy to understand dotted notation of <em>aspects</em>, and
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 80 bits. The
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 128 bits. The
top level aspect should always be a unique identifier for the application using the destination.
The next levels of aspects can be defined in any way by the creator of the application.</p>
<p>Aspects can be as long and as plentiful as required, and a resulting long destination name will not
@@ -245,7 +245,7 @@ application name, a device type and measurement type, like this:</p>
aspects : remotesensor, temperature
full name : environmentlogger.remotesensor.temperature
hash : fa7ddfab5213f916dea
hash : 4faf1b2e0a077e6a9d92fa051f256038
</pre></div>
</div>
<p>For the <em>single</em> destination, Reticulum will automatically append the associated public key as a
@@ -546,10 +546,10 @@ At the same time we establish an efficient encrypted channel. The setup of this
terms of bandwidth, so it can be used just for a short exchange, and then recreated as needed, which will
also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is
more suitable to the application. The procedure also inserts the <em>link id</em> , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this <em>link id</em>.</p>
<p>The combined bandwidth cost of setting up a link is 3 packets totalling 237 bytes (more info in the
<p>The combined bandwidth cost of setting up a link is 3 packets totalling 265 bytes (more info in the
<a class="reference internal" href="#understanding-packetformat"><span class="std std-ref">Binary Packet Format</span></a> section). The amount of bandwidth used on keeping
a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.</p>
a link open is practically negligible, at 0.45 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 96% channel capacity for actual data.</p>
<div class="section" id="link-establishment-in-detail">
<h4>Link Establishment in Detail<a class="headerlink" href="#link-establishment-in-detail" title="Permalink to this headline"></a></h4>
<p>After exploring the basics of the announce mechanism, finding a path through the network, and an overview
@@ -737,7 +737,7 @@ pass onto the network.</p>
A Reticulum packet is composed of the following fields:
[HEADER 2 bytes] [ADDRESSES 10/20 bytes] [CONTEXT 1 byte] [DATA 0-477 bytes]
[HEADER 2 bytes] [ADDRESSES 16/32 bytes] [CONTEXT 1 byte] [DATA 0-465 bytes]
* The HEADER field is 2 bytes long.
* Byte 1: [IFAC Flag], [Header Type], [Propagation Type], [Destination Type] and [Packet Type]
@@ -749,15 +749,15 @@ A Reticulum packet is composed of the following fields:
capabilities and configuration.
* The ADDRESSES field contains either 1 or 2 addresses.
* Each address is 10 bytes long.
* Each address is 16 bytes long.
* The Header Type flag in the HEADER field determines
whether the ADDRESSES field contains 1 or 2 addresses.
* Addresses are Reticulum hashes truncated to 10 bytes.
* Addresses are SHA-256 hashes truncated to 16 bytes.
* The CONTEXT field is 1 byte.
* It is used by Reticulum to determine packet context.
* The DATA field is between 0 and 477 bytes.
* The DATA field is between 0 and 465 bytes.
* It contains the packets data payload.
IFAC Flag
@@ -768,8 +768,8 @@ authenticated 1 Interface authentication is included in packet
Header Types
-----------------
type 1 0 Two byte header, one 10 byte address field
type 2 1 Two byte header, two 10 byte address fields
type 1 0 Two byte header, one 16 byte address field
type 2 1 Two byte header, two 16 byte address fields
Propagation Types
@@ -801,7 +801,7 @@ proof 11
HEADER FIELD DESTINATION FIELDS CONTEXT FIELD DATA FIELD
_______|_______ ________________|________________ ________|______ __|_
| | | | | | | |
01010000 00000100 [HASH1, 10 bytes] [HASH2, 10 bytes] [CONTEXT, 1 byte] [DATA]
01010000 00000100 [HASH1, 16 bytes] [HASH2, 16 bytes] [CONTEXT, 1 byte] [DATA]
|| | | | |
|| | | | +-- Hops = 4
|| | | +------- Packet Type = DATA
@@ -816,7 +816,7 @@ proof 11
HEADER FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
_______|_______ _______|_______ ________|______ __|_
| | | | | | | |
00000000 00000111 [HASH1, 10 bytes] [CONTEXT, 1 byte] [DATA]
00000000 00000111 [HASH1, 16 bytes] [CONTEXT, 1 byte] [DATA]
|| | | | |
|| | | | +-- Hops = 0
|| | | +------- Packet Type = DATA
@@ -831,7 +831,7 @@ proof 11
HEADER FIELD IFAC FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
_______|_______ ______|______ _______|_______ ________|______ __|_
| | | | | | | | | |
10000000 00000111 [IFAC, N bytes] [HASH1, 10 bytes] [CONTEXT, 1 byte] [DATA]
10000000 00000111 [IFAC, N bytes] [HASH1, 16 bytes] [CONTEXT, 1 byte] [DATA]
|| | | | |
|| | | | +-- Hops = 0
|| | | +------- Packet Type = DATA
@@ -849,12 +849,12 @@ packet types. The size listed are the complete on-
wire size counting all fields including headers,
but excluding any interface access codes.
- Path Request : 33 bytes
- Announce : 151 bytes
- Link Request : 77 bytes
- Link Proof : 77 bytes
- Link RTT packet : 83 bytes
- Link keepalive : 14 bytes
- Path Request : 51 bytes
- Announce : 157 bytes
- Link Request : 83 bytes
- Link Proof : 83 bytes
- Link RTT packet : 99 bytes
- Link keepalive : 20 bytes
</pre></div>
</div>
</div>
@@ -956,11 +956,11 @@ those risks are acceptable to you.</p>
</ul>
<h4>Previous topic</h4>
<p class="topless"><a href="hardware.html"
title="previous chapter">Communications Hardware</a></p>
<p class="topless"><a href="using.html"
title="previous chapter">Using Reticulum on Your System</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="reference.html"
title="next chapter">API Reference</a></p>
<p class="topless"><a href="hardware.html"
title="next chapter">Communications Hardware</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
@@ -989,12 +989,12 @@ those risks are acceptable to you.</p>
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="reference.html" title="API Reference"
<a href="hardware.html" title="Communications Hardware"
>next</a> |</li>
<li class="right" >
<a href="hardware.html" title="Communications Hardware"
<a href="using.html" title="Using Reticulum on Your System"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
</ul>
</div>
+21 -21
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Using Reticulum on Your System &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>Using Reticulum on Your System &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -16,7 +16,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="next" title="Understanding Reticulum" href="understanding.html" />
<link rel="prev" title="Getting Started Fast" href="gettingstartedfast.html" />
</head><body>
<div class="related" role="navigation" aria-label="related navigation">
@@ -26,12 +26,12 @@
<a href="genindex.html" title="General Index"
accesskey="I">index</a></li>
<li class="right" >
<a href="networks.html" title="Building Networks"
<a href="understanding.html" title="Understanding Reticulum"
accesskey="N">next</a> |</li>
<li class="right" >
<a href="gettingstartedfast.html" title="Getting Started Fast"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Using Reticulum on Your System</a></li>
</ul>
</div>
@@ -243,7 +243,7 @@ RNodeInterface[RNode UHF]
Traffic : 8.49 KB↑
9.23 KB↓
Reticulum Transport Instance &lt;5245a8efe1788c6a70e1&gt; running
Reticulum Transport Instance &lt;5245a8efe1788c6a1cd36144a270e13b&gt; running
</pre></div>
</div>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>usage: rnstatus [-h] [--config CONFIG] [--version] [-a] [-v]
@@ -264,10 +264,10 @@ optional arguments:
<p>With the <code class="docutils literal notranslate"><span class="pre">rnpath</span></code> utility, you can look up and view paths for
destinations on the Reticulum network.</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span># Run rnpath
rnpath eca6f4e4dc26ae329e61
rnpath c89b4da064bf66d280f0e4d8abfd9806
# Example output
Path found, destination &lt;eca6f4e4dc26ae329e61&gt; is 4 hops away via &lt;56b115c30cd386cad69c&gt; on TCPInterface[Testnet/frankfurt.rns.unsigned.io:4965]
Path found, destination &lt;c89b4da064bf66d280f0e4d8abfd9806&gt; is 4 hops away via &lt;f53a1c4278e0726bb73fcc623d6ce763&gt; on TCPInterface[Testnet/frankfurt.connect.reticulu.network:4965]
</pre></div>
</div>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>usage: rnpath [-h] [--config CONFIG] [--version] [-t] [-r] [-d] [-D] [-w seconds] [-v] [destination]
@@ -297,11 +297,11 @@ to the <code class="docutils literal notranslate"><span class="pre">ping</span><
specified destination is configured to send proofs for received packets. Many
destinations will not have this option enabled, and will not be probable.</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span># Run rnprobe
rnprobe example_utilities.echo.request 9382f334de63217a4278
rnprobe example_utilities.echo.request 2d03725b327348980d570f739a3a5708
# Example output
Sent 16 byte probe to &lt;9382f334de63217a4278&gt;
Valid reply received from &lt;9382f334de63217a4278&gt;
Sent 16 byte probe to &lt;2d03725b327348980d570f739a3a5708&gt;
Valid reply received from &lt;2d03725b327348980d570f739a3a5708&gt;
Round-trip time is 38.469 milliseconds over 2 hops
</pre></div>
</div>
@@ -327,10 +327,10 @@ optional arguments:
files through Reticulum.</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span># Run rncp on the receiving system, specifying which identities
# are allowed to send files
rncp --receive -a 940ea3f9e1037d38758f -a e28d5aee4317c24a9041
rncp --receive -a 1726dbad538775b5bf9b0ea25a4079c8 -a c50cc4e4f7838b6c31f60ab9032cbc62
# From another system, copy a file to the receiving system
rncp ~/path/to/file.tgz 256320d405d6d525d1e9
rncp ~/path/to/file.tgz 73cbd378bb0286ed11a707c13447bb1e
</pre></div>
</div>
<p>You can specify as many allowed senders as needed, or complete disable authentication.</p>
@@ -365,22 +365,22 @@ 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 8111c4ff2968ab0c1286 -a 590256654482b4ba4038
rncp --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
# From another system, run a command
rnx ad9a4c9da60089d41c29 &quot;cat /proc/cpuinfo&quot;
rnx 7a55144adf826958a9529a3bcf08b149 &quot;cat /proc/cpuinfo&quot;
# Or enter the interactive mode pseudo-shell
rnx ad9a4c9da60089d41c29 -x
rnx 7a55144adf826958a9529a3bcf08b149 -x
# The default identity file is stored in
# ~/.reticulum/identities/rnx, but you can use
# another one, which will be created if it does
# not already exist
rnx ad9a4c9da60089d41c29 -i /path/to/identity
rnx 7a55144adf826958a9529a3bcf08b149 -i /path/to/identity -x
</pre></div>
</div>
<p>You can specify as many allowed senders as needed, or complete disable authentication.</p>
<p>You can specify as many allowed senders as needed, or completely disable authentication.</p>
<div class="highlight-text notranslate"><div class="highlight"><pre><span></span>usage: rnx [-h] [--config path] [-v] [-q] [-p] [-l] [-i identity] [-x] [-b] [-a allowed_hash] [-n] [-N] [-d] [-m] [-w seconds] [-W seconds] [--stdin STDIN] [--stdout STDOUT] [--stderr STDERR] [--version]
[destination] [command]
@@ -528,8 +528,8 @@ WantedBy=multi-user.target
<p class="topless"><a href="gettingstartedfast.html"
title="previous chapter">Getting Started Fast</a></p>
<h4>Next topic</h4>
<p class="topless"><a href="networks.html"
title="next chapter">Building Networks</a></p>
<p class="topless"><a href="understanding.html"
title="next chapter">Understanding Reticulum</a></p>
<div role="note" aria-label="source link">
<h3>This Page</h3>
<ul class="this-page-menu">
@@ -558,12 +558,12 @@ WantedBy=multi-user.target
<a href="genindex.html" title="General Index"
>index</a></li>
<li class="right" >
<a href="networks.html" title="Building Networks"
<a href="understanding.html" title="Understanding Reticulum"
>next</a> |</li>
<li class="right" >
<a href="gettingstartedfast.html" title="Getting Started Fast"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">Using Reticulum on Your System</a></li>
</ul>
</div>
+6 -6
View File
@@ -5,7 +5,7 @@
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>What is Reticulum? &#8212; Reticulum Network Stack 0.3.8 beta documentation</title>
<title>What is Reticulum? &#8212; Reticulum Network Stack 0.3.9 beta documentation</title>
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
@@ -31,7 +31,7 @@
<li class="right" >
<a href="index.html" title="Reticulum Network Stack Manual"
accesskey="P">previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
</ul>
</div>
@@ -72,11 +72,11 @@
<li><p>An intuitive and developer-friendly API</p></li>
<li><p>Efficient link establishment</p>
<ul>
<li><p>Total bandwidth cost of setting up a link is only 3 packets, totalling 237 bytes</p></li>
<li><p>Low cost of keeping links open at only 0.62 bits per second</p></li>
<li><p>Total bandwidth cost of setting up a link is only 3 packets, totalling 265 bytes</p></li>
<li><p>Low cost of keeping links open at only 0.44 bits per second</p></li>
</ul>
</li>
<li><p>Reliable and efficient transfer of arbritrary amounts of data</p>
<li><p>Reliable and efficient transfer of arbitrary amounts of data</p>
<ul>
<li><p>Reticulum can handle a few bytes of data or files of many gigabytes</p></li>
<li><p>Sequencing, transfer coordination and checksumming is automatic</p></li>
@@ -211,7 +211,7 @@ network, and vice versa.</p>
<li class="right" >
<a href="index.html" title="Reticulum Network Stack Manual"
>previous</a> |</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.8 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.3.9 beta documentation</a> &#187;</li>
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
</ul>
</div>
+1 -1
View File
@@ -22,7 +22,7 @@ copyright = '2022, Mark Qvist'
author = 'Mark Qvist'
# The full version, including alpha/beta/rc tags
release = '0.3.8 beta'
release = '0.3.9 beta'
# -- General configuration ---------------------------------------------------
+14 -9
View File
@@ -161,20 +161,25 @@ by adding one of the following interfaces to your ``.reticulum/config`` file:
.. code::
# For connecting over TCP/IP:
[[RNS Testnet Frankfurt]]
# TCP/IP interface to the Dublin hub
[[RNS Testnet Dublin]]
type = TCPClientInterface
interface_enabled = yes
outgoing = True
target_host = frankfurt.rns.unsigned.io
enabled = yes
target_host = dublin.connect.reticulum.network
target_port = 4965
# TCP/IP interface to the Frankfurt hub
[[RNS Testnet Dublin]]
type = TCPClientInterface
enabled = yes
target_host = frankfurt.connect.reticulum.network
target_port = 5377
# For connecting over I2P:
[[RNS Testnet I2P Node A]]
# Interface to I2P hub A
[[RNS Testnet I2P Hub A]]
type = I2PInterface
interface_enabled = yes
peers = ykzlw5ujbaqc2xkec4cpvgyxj257wcrmmgkuxqmqcur7cq3w3lha.b32.i2p
enabled = yes
peers = uxg5kubabakh3jtnvsipingbr5574dle7bubvip7llfvwx2tgrua.b32.i2p
Many other Reticulum instances are connecting to this testnet, and you can also join it
via other entry points if you know them. There is absolutely no control over the network
+1 -1
View File
@@ -681,7 +681,7 @@ the default mode.
other nodes in the network. As an example, if a vehicle is
equipped with an external LoRa interface, and an internal,
WiFi-based interface, that serves devices that are moving
_with_ the vehicle, the external LoRa interface should be
*with* the vehicle, the external LoRa interface should be
configured as ``roaming``, and the internal interface can
be left in the default mode. With transport enabled, such
a setup will allow all internal devices to reach each other,
+1 -3
View File
@@ -14,9 +14,7 @@ Donations are gratefully accepted via the following channels:
.. code:: text
Monero:
84FpY1QbxHcgdseePYNmhTHcrgMX4nFf
BYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD1
9b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
Ethereum:
0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a
+29 -29
View File
@@ -117,29 +117,29 @@ Reticulum uses the singular concept of *destinations*. Any application using Ret
networking stack will need to create one or more destinations to receive data, and know the
destinations it needs to send data to.
All destinations in Reticulum are represented as a 10 byte hash, derived from truncating a full
All destinations in Reticulum are _represented_ as a 16 byte hash. This hash is derived from truncating a full
SHA-256 hash of identifying characteristics of the destination. To users, the destination addresses
will be displayed as 10 bytes in hexadecimal representation, as in the following example: ``<80e29bf7cccaf31431b3>``.
will be displayed as 16 hexadecimal bytes, like this example: ``<13425ec15b621c1d928589718000d814>``.
The truncation size of 10 bytes (80 bits) for destinations has been choosen as a reasonable tradeoff between address space
The truncation size of 16 bytes (128 bits) for destinations has been choosen as a reasonable tradeoff
between address space
and packet overhead. The address space accomodated by this size can support many billions of
simultaneously active devices on the same network, while keeping packet overhead low, which is
essential on low-bandwidth networks. In the very unlikely case that this address space nears
congestion, a one-line code change can upgrade the Reticulum address space all the way up to 256
bits, ensuring the Reticulum address space could potentially support galactic-scale networks.
This is obviusly complete and ridiculous over-allocation, and as such, the current 80 bits should
This is obviusly complete and ridiculous over-allocation, and as such, the current 128 bits should
be sufficient, even far into the future.
By default Reticulum encrypts all data using elliptic curve cryptography. Any packet sent to a
destination is encrypted with a derived ephemeral key. Reticulum can also set up an encrypted
channel to a destination with *Forward Secrecy* and *Initiator Anonymity* using a elliptic
curve cryptography and ephemeral keys derived from a Diffie Hellman exchange on Curve25519. In
Reticulum terminology, this is called a *Link*. The multi-hop transport, coordination, verification
channel to a destination, called a *Link*. Both data sent over Links and single packets offer
*Forward Secrecy* and *Initiator Anonymity*, by using an Elliptic Curve Diffie Hellman key exchange
on Curve25519 to derive ephemeral keys. The multi-hop transport, coordination, verification
and reliability layers are fully autonomous and also based on elliptic curve cryptography.
Reticulum also offers symmetric key encryption for group-oriented communications, as well as
unencrypted packets for broadcast purposes, or situations where you need the communication to be in
plain text.
unencrypted packets for local broadcast purposes.
Reticulum can connect to a variety of interfaces such as radio modems, data radios and serial ports,
and offers the possibility to easily tunnel Reticulum traffic over IP links such as the Internet or
@@ -186,7 +186,7 @@ Destination Naming
^^^^^^^^^^^^^^^^^^
Destinations are created and named in an easy to understand dotted notation of *aspects*, and
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 80 bits. The
represented on the network as a hash of this value. The hash is a SHA-256 truncated to 128 bits. The
top level aspect should always be a unique identifier for the application using the destination.
The next levels of aspects can be defined in any way by the creator of the application.
@@ -202,7 +202,7 @@ application name, a device type and measurement type, like this:
aspects : remotesensor, temperature
full name : environmentlogger.remotesensor.temperature
hash : fa7ddfab5213f916dea
hash : 4faf1b2e0a077e6a9d92fa051f256038
For the *single* destination, Reticulum will automatically append the associated public key as a
destination aspect before hashing. This is done to ensure only the correct destination is reached,
@@ -493,10 +493,10 @@ terms of bandwidth, so it can be used just for a short exchange, and then recrea
also rotate encryption keys. The link can also be kept alive for longer periods of time, if this is
more suitable to the application. The procedure also inserts the *link id* , a hash calculated from the link request packet, into the memory of forwarding nodes, which means that the communicating nodes can thereafter reach each other simply by referring to this *link id*.
The combined bandwidth cost of setting up a link is 3 packets totalling 237 bytes (more info in the
The combined bandwidth cost of setting up a link is 3 packets totalling 265 bytes (more info in the
:ref:`Binary Packet Format<understanding-packetformat>` section). The amount of bandwidth used on keeping
a link open is practically negligible, at 0.62 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 95% channel capacity for actual data.
a link open is practically negligible, at 0.45 bits per second. Even on a slow 1200 bits per second packet
radio channel, 100 concurrent links will still leave 96% channel capacity for actual data.
Link Establishment in Detail
@@ -683,7 +683,7 @@ Wire Format
A Reticulum packet is composed of the following fields:
[HEADER 2 bytes] [ADDRESSES 10/20 bytes] [CONTEXT 1 byte] [DATA 0-477 bytes]
[HEADER 2 bytes] [ADDRESSES 16/32 bytes] [CONTEXT 1 byte] [DATA 0-465 bytes]
* The HEADER field is 2 bytes long.
* Byte 1: [IFAC Flag], [Header Type], [Propagation Type], [Destination Type] and [Packet Type]
@@ -695,15 +695,15 @@ Wire Format
capabilities and configuration.
* The ADDRESSES field contains either 1 or 2 addresses.
* Each address is 10 bytes long.
* Each address is 16 bytes long.
* The Header Type flag in the HEADER field determines
whether the ADDRESSES field contains 1 or 2 addresses.
* Addresses are Reticulum hashes truncated to 10 bytes.
* Addresses are SHA-256 hashes truncated to 16 bytes.
* The CONTEXT field is 1 byte.
* It is used by Reticulum to determine packet context.
* The DATA field is between 0 and 477 bytes.
* The DATA field is between 0 and 465 bytes.
* It contains the packets data payload.
IFAC Flag
@@ -714,8 +714,8 @@ Wire Format
Header Types
-----------------
type 1 0 Two byte header, one 10 byte address field
type 2 1 Two byte header, two 10 byte address fields
type 1 0 Two byte header, one 16 byte address field
type 2 1 Two byte header, two 16 byte address fields
Propagation Types
@@ -747,7 +747,7 @@ Wire Format
HEADER FIELD DESTINATION FIELDS CONTEXT FIELD DATA FIELD
_______|_______ ________________|________________ ________|______ __|_
| | | | | | | |
01010000 00000100 [HASH1, 10 bytes] [HASH2, 10 bytes] [CONTEXT, 1 byte] [DATA]
01010000 00000100 [HASH1, 16 bytes] [HASH2, 16 bytes] [CONTEXT, 1 byte] [DATA]
|| | | | |
|| | | | +-- Hops = 4
|| | | +------- Packet Type = DATA
@@ -762,7 +762,7 @@ Wire Format
HEADER FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
_______|_______ _______|_______ ________|______ __|_
| | | | | | | |
00000000 00000111 [HASH1, 10 bytes] [CONTEXT, 1 byte] [DATA]
00000000 00000111 [HASH1, 16 bytes] [CONTEXT, 1 byte] [DATA]
|| | | | |
|| | | | +-- Hops = 0
|| | | +------- Packet Type = DATA
@@ -777,7 +777,7 @@ Wire Format
HEADER FIELD IFAC FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD
_______|_______ ______|______ _______|_______ ________|______ __|_
| | | | | | | | | |
10000000 00000111 [IFAC, N bytes] [HASH1, 10 bytes] [CONTEXT, 1 byte] [DATA]
10000000 00000111 [IFAC, N bytes] [HASH1, 16 bytes] [CONTEXT, 1 byte] [DATA]
|| | | | |
|| | | | +-- Hops = 0
|| | | +------- Packet Type = DATA
@@ -795,12 +795,12 @@ Wire Format
wire size counting all fields including headers,
but excluding any interface access codes.
- Path Request : 33 bytes
- Announce : 151 bytes
- Link Request : 77 bytes
- Link Proof : 77 bytes
- Link RTT packet : 83 bytes
- Link keepalive : 14 bytes
- Path Request : 51 bytes
- Announce : 157 bytes
- Link Request : 83 bytes
- Link Proof : 83 bytes
- Link RTT packet : 99 bytes
- Link keepalive : 20 bytes
.. _understanding-announcepropagation:
+13 -13
View File
@@ -223,7 +223,7 @@ interfaces, similar to the ``ifconfig`` program.
Traffic : 8.49 KB↑
9.23 KB↓
Reticulum Transport Instance <5245a8efe1788c6a70e1> running
Reticulum Transport Instance <5245a8efe1788c6a1cd36144a270e13b> running
.. code:: text
@@ -248,10 +248,10 @@ destinations on the Reticulum network.
.. code:: text
# Run rnpath
rnpath eca6f4e4dc26ae329e61
rnpath c89b4da064bf66d280f0e4d8abfd9806
# Example output
Path found, destination <eca6f4e4dc26ae329e61> is 4 hops away via <56b115c30cd386cad69c> on TCPInterface[Testnet/frankfurt.rns.unsigned.io:4965]
Path found, destination <c89b4da064bf66d280f0e4d8abfd9806> is 4 hops away via <f53a1c4278e0726bb73fcc623d6ce763> on TCPInterface[Testnet/frankfurt.connect.reticulu.network:4965]
.. code:: text
@@ -285,11 +285,11 @@ destinations will not have this option enabled, and will not be probable.
.. code:: text
# Run rnprobe
rnprobe example_utilities.echo.request 9382f334de63217a4278
rnprobe example_utilities.echo.request 2d03725b327348980d570f739a3a5708
# Example output
Sent 16 byte probe to <9382f334de63217a4278>
Valid reply received from <9382f334de63217a4278>
Sent 16 byte probe to <2d03725b327348980d570f739a3a5708>
Valid reply received from <2d03725b327348980d570f739a3a5708>
Round-trip time is 38.469 milliseconds over 2 hops
.. code:: text
@@ -319,10 +319,10 @@ files through Reticulum.
# Run rncp on the receiving system, specifying which identities
# are allowed to send files
rncp --receive -a 940ea3f9e1037d38758f -a e28d5aee4317c24a9041
rncp --receive -a 1726dbad538775b5bf9b0ea25a4079c8 -a c50cc4e4f7838b6c31f60ab9032cbc62
# From another system, copy a file to the receiving system
rncp ~/path/to/file.tgz 256320d405d6d525d1e9
rncp ~/path/to/file.tgz 73cbd378bb0286ed11a707c13447bb1e
You can specify as many allowed senders as needed, or complete disable authentication.
@@ -362,21 +362,21 @@ output.
# Run rnx on the listening system, specifying which identities
# are allowed to execute commands
rncp --listen -a 8111c4ff2968ab0c1286 -a 590256654482b4ba4038
rncp --listen -a 941bed5e228775e5a8079fc38b1ccf3f -a 1b03013c25f1c2ca068a4f080b844a10
# From another system, run a command
rnx ad9a4c9da60089d41c29 "cat /proc/cpuinfo"
rnx 7a55144adf826958a9529a3bcf08b149 "cat /proc/cpuinfo"
# Or enter the interactive mode pseudo-shell
rnx ad9a4c9da60089d41c29 -x
rnx 7a55144adf826958a9529a3bcf08b149 -x
# The default identity file is stored in
# ~/.reticulum/identities/rnx, but you can use
# another one, which will be created if it does
# not already exist
rnx ad9a4c9da60089d41c29 -i /path/to/identity
rnx 7a55144adf826958a9529a3bcf08b149 -i /path/to/identity -x
You can specify as many allowed senders as needed, or complete disable authentication.
You can specify as many allowed senders as needed, or completely disable authentication.
.. code:: text
+3 -3
View File
@@ -46,11 +46,11 @@ What does Reticulum Offer?
* Efficient link establishment
* Total bandwidth cost of setting up a link is only 3 packets, totalling 237 bytes
* Total bandwidth cost of setting up a link is only 3 packets, totalling 265 bytes
* Low cost of keeping links open at only 0.62 bits per second
* Low cost of keeping links open at only 0.44 bits per second
* Reliable and efficient transfer of arbritrary amounts of data
* Reliable and efficient transfer of arbitrary amounts of data
* Reticulum can handle a few bytes of data or files of many gigabytes
+1 -1
View File
@@ -30,7 +30,7 @@ setuptools.setup(
description="Self-configuring, encrypted and resilient mesh networking stack for LoRa, packet radio, WiFi and everything in between",
long_description=long_description,
long_description_content_type="text/markdown",
url="https://github.com/markqvist/reticulum",
url="https://reticulum.network/",
packages=setuptools.find_packages(),
classifiers=[
"Programming Language :: Python :: 3",
+6 -6
View File
@@ -8,14 +8,14 @@ signed_message = "e51a008b8b8ba855993d8892a40daad84a6fb69a7138e1b5f69b427fe03449
sig_from_key_0 = "3020ef58f861591826a61c3d2d4a25b949cdb3094085ba6b1177a6f2a05f3cdd24d1095d6fdd078f0b2826e80b261c93c1ff97fbfd4857f25706d57dd073590c"
encrypted_message = "71884a271ead43558fcf1e331c5aebcd43498f16da16f8056b0893ce6b15d521eaa4f31639cd34da1b57995944076c4f14f300f2d2612111d21a3429a9966ac1da68545c00c7887d8b26f6c1ab9defa020b9519849ca41b7904199882802b6542771df85144a79890289d3c02daef6c26652c5ce9de231a2"
fixed_token = "d8d92fb6c576e906b04d65ca5fee1465ba5abb3a4c8dbcdf0496722824ba4605800000000062a113183257a03a695091e1696b3f331f1dcedc0ffbb044c70c0b881bfddbc0831374a95743be3f42160d5b324bcd521abc5607eec9c54bbda576b1bd76281c43010e932cc4b01b6391b0ff77d0c34b8359b01095e612d7be1c6fd318c21d7dd24ddb1a008a6f5a8513d57881974d4e8799f4d2c4c813abba860969721ceaa477e499e64e725a6fd082df4d2895ca363e92c66eb1bbce4248ddd86c95b50644b365318b9b757d2f535ed235cf7ae2b37e69cf4d"
fixed_token = "54d6ba347f3f2fe74fa52d6844a9090c049a6f437d7d151b9bd7db3e6785dd40286c451babda82660cbb4827517365b740675adf60d4b82778d7f7815a0e9818f2f2d3f15c0365e9d4f08df4f8261e5549c8c398e92bc66750fcd4ce7ea150f8a8761936341129e89afd22eaa57c303ccbe045d0b2fc7b8637946e16627419ef1fea0a0fef974c418a98af046d61e8e064f42c4948b0c81701106583c8f224329c0b475cb2168dc2e3fbf649edb79c58b7c839a509e146ec8d26589cb990c76c756fdefd0110410a6ab84fa3a722db74"
fixed_keys = [
("f8953ffaf607627e615603ff1530c82c434cf87c07179dd7689ea776f30b964cfb7ba6164af00c5111a45e69e57d885e1285f8dbfe3a21e95ae17cf676b0f8b7", "650b5d76b6bec0390d1f"),
("d85d036245436a3c33d3228affae06721f8203bc364ee0ee7556368ac62add650ebf8f926abf628da9d92baaa12db89bd6516ee92ec29765f3afafcb8622d697", "1469e89450c361b253ae"),
("8893e2bfd30fc08455997caf7abb7a6341716768dbbf9a91cc1455bd7eeaf74cdc10ec72a4d4179696040bac620ee97ebc861e2443e5270537ae766d91b58181", "e5fe93ee4acba095b3b9"),
("b82c7a4f047561d974de7e38538281d7f005d3663615f30d9663bad35a716063c931672cd452175d55bcdd70bb7aa35a9706872a97963dc52029938ea7341b39", "1333b911fa8ebb167269"),
("08bb35f92b06a0832991165a0d9b4fd91af7b7765ce4572aa6222070b11b767092b61b0fd18b3a59cae6deb9db6d4bfb1c7fcfe076cfd66eea7ddd5f877543b9", "d13712efc45ef87674fb"),
("f8953ffaf607627e615603ff1530c82c434cf87c07179dd7689ea776f30b964cfb7ba6164af00c5111a45e69e57d885e1285f8dbfe3a21e95ae17cf676b0f8b7", "650b5d76b6bec0390d1f8cfca5bd33f9"),
("d85d036245436a3c33d3228affae06721f8203bc364ee0ee7556368ac62add650ebf8f926abf628da9d92baaa12db89bd6516ee92ec29765f3afafcb8622d697", "1469e89450c361b253aefb0c606b6111"),
("8893e2bfd30fc08455997caf7abb7a6341716768dbbf9a91cc1455bd7eeaf74cdc10ec72a4d4179696040bac620ee97ebc861e2443e5270537ae766d91b58181", "e5fe93ee4acba095b3b9b6541515ed3e"),
("b82c7a4f047561d974de7e38538281d7f005d3663615f30d9663bad35a716063c931672cd452175d55bcdd70bb7aa35a9706872a97963dc52029938ea7341b39", "1333b911fa8ebb16726996adbe3c6262"),
("08bb35f92b06a0832991165a0d9b4fd91af7b7765ce4572aa6222070b11b767092b61b0fd18b3a59cae6deb9db6d4bfb1c7fcfe076cfd66eea7ddd5f877543b9", "d13712efc45ef87674fb5ac26c37c912"),
]
class TestIdentity(unittest.TestCase):
+14 -11
View File
@@ -10,11 +10,11 @@ import os
APP_NAME = "rns_unit_tests"
fixed_keys = [
("f8953ffaf607627e615603ff1530c82c434cf87c07179dd7689ea776f30b964cfb7ba6164af00c5111a45e69e57d885e1285f8dbfe3a21e95ae17cf676b0f8b7", "650b5d76b6bec0390d1f"),
("d85d036245436a3c33d3228affae06721f8203bc364ee0ee7556368ac62add650ebf8f926abf628da9d92baaa12db89bd6516ee92ec29765f3afafcb8622d697", "1469e89450c361b253ae"),
("8893e2bfd30fc08455997caf7abb7a6341716768dbbf9a91cc1455bd7eeaf74cdc10ec72a4d4179696040bac620ee97ebc861e2443e5270537ae766d91b58181", "e5fe93ee4acba095b3b9"),
("b82c7a4f047561d974de7e38538281d7f005d3663615f30d9663bad35a716063c931672cd452175d55bcdd70bb7aa35a9706872a97963dc52029938ea7341b39", "1333b911fa8ebb167269"),
("08bb35f92b06a0832991165a0d9b4fd91af7b7765ce4572aa6222070b11b767092b61b0fd18b3a59cae6deb9db6d4bfb1c7fcfe076cfd66eea7ddd5f877543b9", "d13712efc45ef87674fb"),
("f8953ffaf607627e615603ff1530c82c434cf87c07179dd7689ea776f30b964cfb7ba6164af00c5111a45e69e57d885e1285f8dbfe3a21e95ae17cf676b0f8b7", "650b5d76b6bec0390d1f8cfca5bd33f9"),
("d85d036245436a3c33d3228affae06721f8203bc364ee0ee7556368ac62add650ebf8f926abf628da9d92baaa12db89bd6516ee92ec29765f3afafcb8622d697", "1469e89450c361b253aefb0c606b6111"),
("8893e2bfd30fc08455997caf7abb7a6341716768dbbf9a91cc1455bd7eeaf74cdc10ec72a4d4179696040bac620ee97ebc861e2443e5270537ae766d91b58181", "e5fe93ee4acba095b3b9b6541515ed3e"),
("b82c7a4f047561d974de7e38538281d7f005d3663615f30d9663bad35a716063c931672cd452175d55bcdd70bb7aa35a9706872a97963dc52029938ea7341b39", "1333b911fa8ebb16726996adbe3c6262"),
("08bb35f92b06a0832991165a0d9b4fd91af7b7765ce4572aa6222070b11b767092b61b0fd18b3a59cae6deb9db6d4bfb1c7fcfe076cfd66eea7ddd5f877543b9", "d13712efc45ef87674fb5ac26c37c912"),
]
def targets_job(caller):
@@ -63,7 +63,8 @@ class TestLink(unittest.TestCase):
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("be0c90339fce3db5b4e5"))
self.assertEqual(dest.hash, bytes.fromhex("6bbe8b43a9842b77867ad99fd090fff3"))
l1 = RNS.Link(dest)
time.sleep(0.5)
@@ -82,7 +83,8 @@ class TestLink(unittest.TestCase):
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("be0c90339fce3db5b4e5"))
self.assertEqual(dest.hash, bytes.fromhex("6bbe8b43a9842b77867ad99fd090fff3"))
l1 = RNS.Link(dest)
time.sleep(0.5)
@@ -148,7 +150,8 @@ class TestLink(unittest.TestCase):
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("be0c90339fce3db5b4e5"))
self.assertEqual(dest.hash, bytes.fromhex("6bbe8b43a9842b77867ad99fd090fff3"))
l1 = RNS.Link(dest)
time.sleep(0.5)
@@ -182,7 +185,7 @@ class TestLink(unittest.TestCase):
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("be0c90339fce3db5b4e5"))
self.assertEqual(dest.hash, bytes.fromhex("6bbe8b43a9842b77867ad99fd090fff3"))
l1 = RNS.Link(dest)
time.sleep(0.5)
@@ -221,7 +224,7 @@ class TestLink(unittest.TestCase):
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("be0c90339fce3db5b4e5"))
self.assertEqual(dest.hash, bytes.fromhex("6bbe8b43a9842b77867ad99fd090fff3"))
l1 = RNS.Link(dest)
time.sleep(0.5)
@@ -259,7 +262,7 @@ class TestLink(unittest.TestCase):
self.assertEqual(id1.hash, bytes.fromhex(fixed_keys[0][1]))
dest = RNS.Destination(id1, RNS.Destination.OUT, RNS.Destination.SINGLE, APP_NAME, "link", "establish")
self.assertEqual(dest.hash, bytes.fromhex("be0c90339fce3db5b4e5"))
self.assertEqual(dest.hash, bytes.fromhex("6bbe8b43a9842b77867ad99fd090fff3"))
l1 = RNS.Link(dest)
time.sleep(0.5)