mirror of
https://github.com/markqvist/Reticulum.git
synced 2026-07-16 21:38:11 -07:00
Compare commits
32 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 58f43b163e | |||
| 448ea8ceb5 | |||
| f7e8fc4719 | |||
| 1d6c877b4c | |||
| c3dcd9366d | |||
| 8d01586a5a | |||
| 3e5f613f66 | |||
| 614a139cd4 | |||
| 1cf6570c2d | |||
| d207cbcd9c | |||
| 18b20f2d8d | |||
| c37533d2c7 | |||
| fd13e20165 | |||
| 66ce58f0f4 | |||
| e8ee26f78d | |||
| c0fb419fe1 | |||
| 4ef369cdd8 | |||
| a2f18b1daf | |||
| 2e411fa1de | |||
| 549dc40be6 | |||
| 1a99597f4d | |||
| b21e0bee20 | |||
| be8389a906 | |||
| 4ca00c6973 | |||
| 95f81cab7f | |||
| 60917f0eea | |||
| de800f0ea7 | |||
| 5dad76879c | |||
| 75c3180933 | |||
| 4c6ba97dca | |||
| cd6427cc9d | |||
| 1749393732 |
+49
-2
@@ -22,6 +22,8 @@ APP_NAME = "example_utilities"
|
|||||||
# This initialisation is executed when the users chooses
|
# This initialisation is executed when the users chooses
|
||||||
# to run as a server
|
# to run as a server
|
||||||
def server(configpath):
|
def server(configpath):
|
||||||
|
global reticulum
|
||||||
|
|
||||||
# We must first initialise Reticulum
|
# We must first initialise Reticulum
|
||||||
reticulum = RNS.Reticulum(configpath)
|
reticulum = RNS.Reticulum(configpath)
|
||||||
|
|
||||||
@@ -78,11 +80,32 @@ def announceLoop(destination):
|
|||||||
|
|
||||||
|
|
||||||
def server_callback(message, packet):
|
def server_callback(message, packet):
|
||||||
|
global reticulum
|
||||||
|
|
||||||
# Tell the user that we received an echo request, and
|
# Tell the user that we received an echo request, and
|
||||||
# that we are going to send a reply to the requester.
|
# that we are going to send a reply to the requester.
|
||||||
# Sending the proof is handled automatically, since we
|
# Sending the proof is handled automatically, since we
|
||||||
# set up the destination to prove all incoming packets.
|
# set up the destination to prove all incoming packets.
|
||||||
RNS.log("Received packet from echo client, proof sent")
|
|
||||||
|
reception_stats = ""
|
||||||
|
if reticulum.is_connected_to_shared_instance:
|
||||||
|
reception_rssi = reticulum.get_packet_rssi(packet.packet_hash)
|
||||||
|
reception_snr = reticulum.get_packet_snr(packet.packet_hash)
|
||||||
|
|
||||||
|
if reception_rssi != None:
|
||||||
|
reception_stats += " [RSSI "+str(reception_rssi)+" dBm]"
|
||||||
|
|
||||||
|
if reception_snr != None:
|
||||||
|
reception_stats += " [SNR "+str(reception_snr)+" dBm]"
|
||||||
|
|
||||||
|
else:
|
||||||
|
if packet.rssi != None:
|
||||||
|
reception_stats += " [RSSI "+str(packet.rssi)+" dBm]"
|
||||||
|
|
||||||
|
if packet.snr != None:
|
||||||
|
reception_stats += " [SNR "+str(packet.snr)+" dB]"
|
||||||
|
|
||||||
|
RNS.log("Received packet from echo client, proof sent"+reception_stats)
|
||||||
|
|
||||||
|
|
||||||
##########################################################
|
##########################################################
|
||||||
@@ -92,6 +115,8 @@ def server_callback(message, packet):
|
|||||||
# This initialisation is executed when the users chooses
|
# This initialisation is executed when the users chooses
|
||||||
# to run as a client
|
# to run as a client
|
||||||
def client(destination_hexhash, configpath, timeout=None):
|
def client(destination_hexhash, configpath, timeout=None):
|
||||||
|
global reticulum
|
||||||
|
|
||||||
# We need a binary representation of the destination
|
# We need a binary representation of the destination
|
||||||
# hash that was entered on the command line
|
# hash that was entered on the command line
|
||||||
try:
|
try:
|
||||||
@@ -188,6 +213,8 @@ def client(destination_hexhash, configpath, timeout=None):
|
|||||||
# This function is called when our reply destination
|
# This function is called when our reply destination
|
||||||
# receives a proof packet.
|
# receives a proof packet.
|
||||||
def packet_delivered(receipt):
|
def packet_delivered(receipt):
|
||||||
|
global reticulum
|
||||||
|
|
||||||
if receipt.status == RNS.PacketReceipt.DELIVERED:
|
if receipt.status == RNS.PacketReceipt.DELIVERED:
|
||||||
rtt = receipt.get_rtt()
|
rtt = receipt.get_rtt()
|
||||||
if (rtt >= 1):
|
if (rtt >= 1):
|
||||||
@@ -197,10 +224,30 @@ def packet_delivered(receipt):
|
|||||||
rtt = round(rtt*1000, 3)
|
rtt = round(rtt*1000, 3)
|
||||||
rttstring = str(rtt)+" milliseconds"
|
rttstring = str(rtt)+" milliseconds"
|
||||||
|
|
||||||
|
reception_stats = ""
|
||||||
|
if reticulum.is_connected_to_shared_instance:
|
||||||
|
reception_rssi = reticulum.get_packet_rssi(receipt.proof_packet.packet_hash)
|
||||||
|
reception_snr = reticulum.get_packet_snr(receipt.proof_packet.packet_hash)
|
||||||
|
|
||||||
|
if reception_rssi != None:
|
||||||
|
reception_stats += " [RSSI "+str(reception_rssi)+" dBm]"
|
||||||
|
|
||||||
|
if reception_snr != None:
|
||||||
|
reception_stats += " [SNR "+str(reception_snr)+" dB]"
|
||||||
|
|
||||||
|
else:
|
||||||
|
if receipt.proof_packet != None:
|
||||||
|
if receipt.proof_packet.rssi != None:
|
||||||
|
reception_stats += " [RSSI "+str(receipt.proof_packet.rssi)+" dBm]"
|
||||||
|
|
||||||
|
if receipt.proof_packet.snr != None:
|
||||||
|
reception_stats += " [SNR "+str(receipt.proof_packet.snr)+" dB]"
|
||||||
|
|
||||||
RNS.log(
|
RNS.log(
|
||||||
"Valid reply received from "+
|
"Valid reply received from "+
|
||||||
RNS.prettyhexrep(receipt.destination.hash)+
|
RNS.prettyhexrep(receipt.destination.hash)+
|
||||||
", round-trip time is "+rttstring
|
", round-trip time is "+rttstring+
|
||||||
|
reception_stats
|
||||||
)
|
)
|
||||||
|
|
||||||
# This function is called if a packet times out.
|
# This function is called if a packet times out.
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ For more info, see [unsigned.io/projects/reticulum](https://unsigned.io/projects
|
|||||||
## Notable Features
|
## Notable Features
|
||||||
- Coordination-less globally unique adressing and identification
|
- Coordination-less globally unique adressing and identification
|
||||||
- Fully self-configuring multi-hop routing
|
- 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
|
- 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 ephemereal 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
|
- Reticulum uses the [Fernet](https://github.com/fernet/spec/blob/master/Spec.md) specification for on-the-wire / over-the-air encryption
|
||||||
@@ -37,8 +38,14 @@ For more info, see [unsigned.io/projects/reticulum](https://unsigned.io/projects
|
|||||||
- Total bandwidth cost of setting up a link is 3 packets totalling 237 bytes
|
- Total bandwidth cost of setting up a link is 3 packets totalling 237 bytes
|
||||||
- Low cost of keeping links open at only 0.62 bits per second
|
- Low cost of keeping links open at only 0.62 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.
|
||||||
|
|
||||||
|
- For an off-grid, encrypted and resilient mesh communications platform, see [Nomad Network](https://github.com/markqvist/NomadNet)
|
||||||
|
- For a distributed, delay and disruption tolerant message transfer protocol built on Reticulum, see [LXMF](https://github.com/markqvist/lxmf)
|
||||||
|
|
||||||
## Where can Reticulum be used?
|
## Where can Reticulum be used?
|
||||||
Over practically any medium that can support at least a half-duplex channel with 1.000 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, ad-hoc WiFi, free-space optical links and similar systems are all examples of the types of interfaces Reticulum was designed for.
|
||||||
|
|
||||||
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://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.
|
||||||
|
|
||||||
@@ -63,16 +70,16 @@ Reticulum implements a range of generalised interface types that covers most of
|
|||||||
|
|
||||||
|
|
||||||
## Feature Roadmap
|
## Feature Roadmap
|
||||||
|
- Stream mode for links
|
||||||
- More interface types for even broader compatibility
|
- More interface types for even broader compatibility
|
||||||
- ESP32 devices (ESP-Now, Bluetooth, etc.)
|
- ESP32 devices (ESP-Now, Bluetooth, etc.)
|
||||||
|
- More LoRa transceivers
|
||||||
- AT-compatible modems
|
- AT-compatible modems
|
||||||
- CAN-bus
|
- CAN-bus
|
||||||
- ZeroMQ
|
- ZeroMQ
|
||||||
- MQTT
|
- MQTT
|
||||||
- SPI
|
- SPI
|
||||||
- i²c
|
- i²c
|
||||||
- A delay and disruption tolerant message transfer protocol built on Reticulum, see [LXMF](https://github.com/markqvist/lxmf)
|
|
||||||
- A few useful-in-the-real-world apps built with Reticulum, see [Nomad Network](https://github.com/markqvist/NomadNet)
|
|
||||||
|
|
||||||
## Dependencies:
|
## Dependencies:
|
||||||
- Python 3
|
- Python 3
|
||||||
@@ -93,5 +100,12 @@ The default config file contains examples for using Reticulum with LoRa transcei
|
|||||||
|
|
||||||
You can use the examples in the config file to expand communication over other mediums such as packet radio or LoRa, or over fast IP links using the UDP interface. I'll add in-depth tutorials and explanations on these topics later. For now, the included examples will hopefully be enough to get started.
|
You can use the examples in the config file to expand communication over other mediums such as packet radio or LoRa, or over fast IP links using the UDP interface. I'll add in-depth tutorials and explanations on these topics later. For now, the included examples will hopefully be enough to get started.
|
||||||
|
|
||||||
|
## Support Reticulum
|
||||||
|
You can help support the continued development of open, free and private communications systems by donating via one of the following channels:
|
||||||
|
|
||||||
|
- Ethereum: 0x81F7B979fEa6134bA9FD5c701b3501A2e61E897a
|
||||||
|
- Bitcoin: 3CPmacGm34qYvR6XWLVEJmi2aNe3PZqUuq
|
||||||
|
- Ko-Fi: https://ko-fi.com/markqvist
|
||||||
|
|
||||||
## Caveat Emptor
|
## Caveat Emptor
|
||||||
Reticulum is experimental software, and should be considered as such. While it has been built with cryptography best-practices very foremost in mind, it _has not_ been externally security audited, and there could very well be privacy-breaking bugs. If you want to help out, or help sponsor an audit, please do get in touch.
|
Reticulum is experimental software, and should be considered as such. While it has been built with cryptography best-practices very foremost in mind, it _has not_ been externally security audited, and there could very well be privacy-breaking bugs. If you want to help out, or help sponsor an audit, please do get in touch.
|
||||||
+7
-2
@@ -1,5 +1,6 @@
|
|||||||
import base64
|
import base64
|
||||||
import math
|
import math
|
||||||
|
import time
|
||||||
import RNS
|
import RNS
|
||||||
|
|
||||||
from cryptography.fernet import Fernet
|
from cryptography.fernet import Fernet
|
||||||
@@ -146,7 +147,7 @@ class Destination:
|
|||||||
:param path_response: Internal flag used by :ref:`RNS.Transport<api-transport>`. Ignore.
|
:param path_response: Internal flag used by :ref:`RNS.Transport<api-transport>`. Ignore.
|
||||||
"""
|
"""
|
||||||
destination_hash = self.hash
|
destination_hash = self.hash
|
||||||
random_hash = RNS.Identity.get_random_hash()
|
random_hash = RNS.Identity.get_random_hash()[0:5]+int(time.time()).to_bytes(5, "big")
|
||||||
|
|
||||||
if app_data == None and self.default_app_data != None:
|
if app_data == None and self.default_app_data != None:
|
||||||
if isinstance(self.default_app_data, bytes):
|
if isinstance(self.default_app_data, bytes):
|
||||||
@@ -262,7 +263,11 @@ class Destination:
|
|||||||
if plaintext != None:
|
if plaintext != None:
|
||||||
if packet.packet_type == RNS.Packet.DATA:
|
if packet.packet_type == RNS.Packet.DATA:
|
||||||
if self.callbacks.packet != None:
|
if self.callbacks.packet != None:
|
||||||
self.callbacks.packet(plaintext, packet)
|
try:
|
||||||
|
self.callbacks.packet(plaintext, packet)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing receive callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
|
|
||||||
def incoming_link_request(self, data, packet):
|
def incoming_link_request(self, data, packet):
|
||||||
link = RNS.Link.validate_request(self, data, packet)
|
link = RNS.Link.validate_request(self, data, packet)
|
||||||
|
|||||||
+22
-6
@@ -90,11 +90,27 @@ class Identity:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def save_known_destinations():
|
def save_known_destinations():
|
||||||
RNS.log("Saving known destinations to storage...", RNS.LOG_VERBOSE)
|
try:
|
||||||
file = open(RNS.Reticulum.storagepath+"/known_destinations","wb")
|
storage_known_destinations = {}
|
||||||
umsgpack.dump(Identity.known_destinations, file)
|
if os.path.isfile(RNS.Reticulum.storagepath+"/known_destinations"):
|
||||||
file.close()
|
try:
|
||||||
RNS.log("Done saving known destinations to storage", RNS.LOG_VERBOSE)
|
file = open(RNS.Reticulum.storagepath+"/known_destinations","rb")
|
||||||
|
storage_known_destinations = umsgpack.load(file)
|
||||||
|
file.close()
|
||||||
|
except:
|
||||||
|
pass
|
||||||
|
|
||||||
|
for destination_hash in storage_known_destinations:
|
||||||
|
if not destination_hash in Identity.known_destinations:
|
||||||
|
Identity.known_destinations[destination_hash] = storage_known_destinations[destination_hash]
|
||||||
|
|
||||||
|
RNS.log("Saving known destinations to storage...", RNS.LOG_VERBOSE)
|
||||||
|
file = open(RNS.Reticulum.storagepath+"/known_destinations","wb")
|
||||||
|
umsgpack.dump(Identity.known_destinations, file)
|
||||||
|
file.close()
|
||||||
|
RNS.log("Done saving known destinations to storage", RNS.LOG_VERBOSE)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while saving known destinations to disk, the contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def load_known_destinations():
|
def load_known_destinations():
|
||||||
@@ -107,7 +123,7 @@ class Identity:
|
|||||||
except:
|
except:
|
||||||
RNS.log("Error loading known destinations from disk, file will be recreated on exit", RNS.LOG_ERROR)
|
RNS.log("Error loading known destinations from disk, file will be recreated on exit", RNS.LOG_ERROR)
|
||||||
else:
|
else:
|
||||||
RNS.log("Destinations file does not exist, so no known destinations loaded", RNS.LOG_VERBOSE)
|
RNS.log("Destinations file does not exist, no known destinations loaded", RNS.LOG_VERBOSE)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def full_hash(data):
|
def full_hash(data):
|
||||||
|
|||||||
@@ -283,6 +283,8 @@ class RNodeInterface(Interface):
|
|||||||
def processIncoming(self, data):
|
def processIncoming(self, data):
|
||||||
self.rxb += len(data)
|
self.rxb += len(data)
|
||||||
self.owner.inbound(data, self)
|
self.owner.inbound(data, self)
|
||||||
|
self.r_stat_rssi = None
|
||||||
|
self.r_stat_snr = None
|
||||||
|
|
||||||
|
|
||||||
def processOutgoing(self,data):
|
def processOutgoing(self,data):
|
||||||
|
|||||||
@@ -275,7 +275,8 @@ class TCPClientInterface(Interface):
|
|||||||
self.parent_interface.clients -= 1
|
self.parent_interface.clients -= 1
|
||||||
|
|
||||||
if self in RNS.Transport.interfaces:
|
if self in RNS.Transport.interfaces:
|
||||||
RNS.Transport.interfaces.remove(self)
|
if not self.initiator:
|
||||||
|
RNS.Transport.interfaces.remove(self)
|
||||||
|
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
+41
-13
@@ -182,7 +182,7 @@ class Link:
|
|||||||
self.start_watchdog()
|
self.start_watchdog()
|
||||||
self.packet.send()
|
self.packet.send()
|
||||||
self.had_outbound()
|
self.had_outbound()
|
||||||
RNS.log("Link request "+RNS.prettyhexrep(self.link_id)+" sent to "+str(self.destination), RNS.LOG_VERBOSE)
|
RNS.log("Link request "+RNS.prettyhexrep(self.link_id)+" sent to "+str(self.destination), RNS.LOG_DEBUG)
|
||||||
|
|
||||||
|
|
||||||
def load_peer(self, peer_pub_bytes, peer_sig_pub_bytes):
|
def load_peer(self, peer_pub_bytes, peer_sig_pub_bytes):
|
||||||
@@ -425,7 +425,11 @@ class Link:
|
|||||||
self.destination.links.remove(self)
|
self.destination.links.remove(self)
|
||||||
|
|
||||||
if self.callbacks.link_closed != None:
|
if self.callbacks.link_closed != None:
|
||||||
self.callbacks.link_closed(self)
|
try:
|
||||||
|
self.callbacks.link_closed(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing link closed callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
|
|
||||||
def start_watchdog(self):
|
def start_watchdog(self):
|
||||||
thread = threading.Thread(target=self.__watchdog_job)
|
thread = threading.Thread(target=self.__watchdog_job)
|
||||||
@@ -455,7 +459,7 @@ class Link:
|
|||||||
sleep_time = next_check - time.time()
|
sleep_time = next_check - time.time()
|
||||||
if time.time() >= self.request_time + self.establishment_timeout:
|
if time.time() >= self.request_time + self.establishment_timeout:
|
||||||
if self.initiator:
|
if self.initiator:
|
||||||
RNS.log("Timeout waiting link request proof", RNS.LOG_DEBUG)
|
RNS.log("Timeout waiting for link request proof", RNS.LOG_DEBUG)
|
||||||
else:
|
else:
|
||||||
RNS.log("Timeout waiting for RTT packet from link initiator", RNS.LOG_DEBUG)
|
RNS.log("Timeout waiting for RTT packet from link initiator", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
@@ -527,7 +531,7 @@ class Link:
|
|||||||
else:
|
else:
|
||||||
response_resource = RNS.Resource(packed_response, self, request_id = request_id, is_response = True)
|
response_resource = RNS.Resource(packed_response, self, request_id = request_id, is_response = True)
|
||||||
else:
|
else:
|
||||||
identity_string = RNS.prettyhexrep(self.get_remote_identity()) if self.get_remote_identity() != None else "<Unknown>"
|
identity_string = str(self.get_remote_identity()) if self.get_remote_identity() != None else "<Unknown>"
|
||||||
RNS.log("Request "+RNS.prettyhexrep(request_id)+" from "+identity_string+" not allowed for: "+str(path), RNS.LOG_DEBUG)
|
RNS.log("Request "+RNS.prettyhexrep(request_id)+" from "+identity_string+" not allowed for: "+str(path), RNS.LOG_DEBUG)
|
||||||
|
|
||||||
def handle_response(self, request_id, response_data, response_size, response_transfer_size):
|
def handle_response(self, request_id, response_data, response_size, response_transfer_size):
|
||||||
@@ -598,7 +602,10 @@ class Link:
|
|||||||
|
|
||||||
elif self.destination.proof_strategy == RNS.Destination.PROVE_APP:
|
elif self.destination.proof_strategy == RNS.Destination.PROVE_APP:
|
||||||
if self.destination.callbacks.proof_requested:
|
if self.destination.callbacks.proof_requested:
|
||||||
self.destination.callbacks.proof_requested(packet)
|
try:
|
||||||
|
self.destination.callbacks.proof_requested(packet)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing proof request callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
elif packet.context == RNS.Packet.LINKIDENTIFY:
|
elif packet.context == RNS.Packet.LINKIDENTIFY:
|
||||||
plaintext = self.decrypt(packet.data)
|
plaintext = self.decrypt(packet.data)
|
||||||
@@ -613,7 +620,10 @@ class Link:
|
|||||||
if identity.validate(signature, signed_data):
|
if identity.validate(signature, signed_data):
|
||||||
self.__remote_identity = identity
|
self.__remote_identity = identity
|
||||||
if self.callbacks.remote_identified != None:
|
if self.callbacks.remote_identified != None:
|
||||||
self.callbacks.remote_identified(self.__remote_identity)
|
try:
|
||||||
|
self.callbacks.remote_identified(self.__remote_identity)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing remote identified callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
elif packet.context == RNS.Packet.REQUEST:
|
elif packet.context == RNS.Packet.REQUEST:
|
||||||
try:
|
try:
|
||||||
@@ -659,8 +669,11 @@ class Link:
|
|||||||
pass
|
pass
|
||||||
elif self.resource_strategy == Link.ACCEPT_APP:
|
elif self.resource_strategy == Link.ACCEPT_APP:
|
||||||
if self.callbacks.resource != None:
|
if self.callbacks.resource != None:
|
||||||
if self.callbacks.resource(resource):
|
try:
|
||||||
RNS.Resource.accept(packet, self.callbacks.resource_concluded)
|
if self.callbacks.resource(resource):
|
||||||
|
RNS.Resource.accept(packet, self.callbacks.resource_concluded)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing resource accept callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
elif self.resource_strategy == Link.ACCEPT_ALL:
|
elif self.resource_strategy == Link.ACCEPT_ALL:
|
||||||
RNS.Resource.accept(packet, self.callbacks.resource_concluded)
|
RNS.Resource.accept(packet, self.callbacks.resource_concluded)
|
||||||
|
|
||||||
@@ -933,7 +946,10 @@ class RequestReceipt():
|
|||||||
self.link.pending_requests.remove(self)
|
self.link.pending_requests.remove(self)
|
||||||
|
|
||||||
if self.callbacks.failed != None:
|
if self.callbacks.failed != None:
|
||||||
self.callbacks.failed(self)
|
try:
|
||||||
|
self.callbacks.failed(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing request failed callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
|
|
||||||
def __response_timeout_job(self):
|
def __response_timeout_job(self):
|
||||||
@@ -951,7 +967,10 @@ class RequestReceipt():
|
|||||||
self.link.pending_requests.remove(self)
|
self.link.pending_requests.remove(self)
|
||||||
|
|
||||||
if self.callbacks.failed != None:
|
if self.callbacks.failed != None:
|
||||||
self.callbacks.failed(self)
|
try:
|
||||||
|
self.callbacks.failed(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing request timed out callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
|
|
||||||
def response_resource_progress(self, resource):
|
def response_resource_progress(self, resource):
|
||||||
@@ -967,7 +986,10 @@ class RequestReceipt():
|
|||||||
self.progress = resource.get_progress()
|
self.progress = resource.get_progress()
|
||||||
|
|
||||||
if self.callbacks.progress != None:
|
if self.callbacks.progress != None:
|
||||||
self.callbacks.progress(self)
|
try:
|
||||||
|
self.callbacks.progress(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing response progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
else:
|
else:
|
||||||
resource.cancel()
|
resource.cancel()
|
||||||
|
|
||||||
@@ -987,10 +1009,16 @@ class RequestReceipt():
|
|||||||
self.packet_receipt.callbacks.delivery(self.packet_receipt)
|
self.packet_receipt.callbacks.delivery(self.packet_receipt)
|
||||||
|
|
||||||
if self.callbacks.progress != None:
|
if self.callbacks.progress != None:
|
||||||
self.callbacks.progress(self)
|
try:
|
||||||
|
self.callbacks.progress(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing response progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
if self.callbacks.response != None:
|
if self.callbacks.response != None:
|
||||||
self.callbacks.response(self)
|
try:
|
||||||
|
self.callbacks.response(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing response received callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
def get_request_id(self):
|
def get_request_id(self):
|
||||||
"""
|
"""
|
||||||
|
|||||||
+23
-6
@@ -113,6 +113,8 @@ class Packet:
|
|||||||
|
|
||||||
self.attached_interface = attached_interface
|
self.attached_interface = attached_interface
|
||||||
self.receiving_interface = None
|
self.receiving_interface = None
|
||||||
|
self.rssi = None
|
||||||
|
self.snr = None
|
||||||
|
|
||||||
def get_packed_flags(self):
|
def get_packed_flags(self):
|
||||||
if self.context == Packet.LRPROOF:
|
if self.context == Packet.LRPROOF:
|
||||||
@@ -328,6 +330,7 @@ class PacketReceipt:
|
|||||||
self.destination = packet.destination
|
self.destination = packet.destination
|
||||||
self.callbacks = PacketReceiptCallbacks()
|
self.callbacks = PacketReceiptCallbacks()
|
||||||
self.concluded_at = None
|
self.concluded_at = None
|
||||||
|
self.proof_packet = None
|
||||||
|
|
||||||
if packet.destination.type == RNS.Destination.LINK:
|
if packet.destination.type == RNS.Destination.LINK:
|
||||||
self.timeout = packet.destination.rtt * packet.destination.traffic_timeout_factor
|
self.timeout = packet.destination.rtt * packet.destination.traffic_timeout_factor
|
||||||
@@ -344,12 +347,12 @@ class PacketReceipt:
|
|||||||
# Validate a proof packet
|
# Validate a proof packet
|
||||||
def validate_proof_packet(self, proof_packet):
|
def validate_proof_packet(self, proof_packet):
|
||||||
if hasattr(proof_packet, "link") and proof_packet.link:
|
if hasattr(proof_packet, "link") and proof_packet.link:
|
||||||
return self.validate_link_proof(proof_packet.data, proof_packet.link)
|
return self.validate_link_proof(proof_packet.data, proof_packet.link, proof_packet)
|
||||||
else:
|
else:
|
||||||
return self.validate_proof(proof_packet.data)
|
return self.validate_proof(proof_packet.data, proof_packet)
|
||||||
|
|
||||||
# Validate a raw proof for a link
|
# Validate a raw proof for a link
|
||||||
def validate_link_proof(self, proof, link):
|
def validate_link_proof(self, proof, link, proof_packet=None):
|
||||||
# TODO: Hardcoded as explicit proofs for now
|
# TODO: Hardcoded as explicit proofs for now
|
||||||
if True or len(proof) == PacketReceipt.EXPL_LENGTH:
|
if True or len(proof) == PacketReceipt.EXPL_LENGTH:
|
||||||
# This is an explicit proof
|
# This is an explicit proof
|
||||||
@@ -361,6 +364,8 @@ class PacketReceipt:
|
|||||||
self.status = PacketReceipt.DELIVERED
|
self.status = PacketReceipt.DELIVERED
|
||||||
self.proved = True
|
self.proved = True
|
||||||
self.concluded_at = time.time()
|
self.concluded_at = time.time()
|
||||||
|
self.proof_packet = proof_packet
|
||||||
|
|
||||||
if self.callbacks.delivery != None:
|
if self.callbacks.delivery != None:
|
||||||
self.callbacks.delivery(self)
|
self.callbacks.delivery(self)
|
||||||
return True
|
return True
|
||||||
@@ -388,7 +393,7 @@ class PacketReceipt:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
# Validate a raw proof
|
# Validate a raw proof
|
||||||
def validate_proof(self, proof):
|
def validate_proof(self, proof, proof_packet=None):
|
||||||
if len(proof) == PacketReceipt.EXPL_LENGTH:
|
if len(proof) == PacketReceipt.EXPL_LENGTH:
|
||||||
# This is an explicit proof
|
# This is an explicit proof
|
||||||
proof_hash = proof[:RNS.Identity.HASHLENGTH//8]
|
proof_hash = proof[:RNS.Identity.HASHLENGTH//8]
|
||||||
@@ -399,8 +404,14 @@ class PacketReceipt:
|
|||||||
self.status = PacketReceipt.DELIVERED
|
self.status = PacketReceipt.DELIVERED
|
||||||
self.proved = True
|
self.proved = True
|
||||||
self.concluded_at = time.time()
|
self.concluded_at = time.time()
|
||||||
|
self.proof_packet = proof_packet
|
||||||
|
|
||||||
if self.callbacks.delivery != None:
|
if self.callbacks.delivery != None:
|
||||||
self.callbacks.delivery(self)
|
try:
|
||||||
|
self.callbacks.delivery(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing proof validated callback. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
@@ -417,8 +428,14 @@ class PacketReceipt:
|
|||||||
self.status = PacketReceipt.DELIVERED
|
self.status = PacketReceipt.DELIVERED
|
||||||
self.proved = True
|
self.proved = True
|
||||||
self.concluded_at = time.time()
|
self.concluded_at = time.time()
|
||||||
|
self.proof_packet = proof_packet
|
||||||
|
|
||||||
if self.callbacks.delivery != None:
|
if self.callbacks.delivery != None:
|
||||||
self.callbacks.delivery(self)
|
try:
|
||||||
|
self.callbacks.delivery(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing proof validated callback. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|||||||
+26
-10
@@ -123,7 +123,10 @@ class Resource:
|
|||||||
|
|
||||||
RNS.log("Accepting resource advertisement for "+RNS.prettyhexrep(resource.hash), RNS.LOG_DEBUG)
|
RNS.log("Accepting resource advertisement for "+RNS.prettyhexrep(resource.hash), RNS.LOG_DEBUG)
|
||||||
if resource.link.callbacks.resource_started != None:
|
if resource.link.callbacks.resource_started != None:
|
||||||
resource.link.callbacks.resource_started(resource)
|
try:
|
||||||
|
resource.link.callbacks.resource_started(resource)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing resource started callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
resource.hashmap_update(0, resource.hashmap_raw)
|
resource.hashmap_update(0, resource.hashmap_raw)
|
||||||
|
|
||||||
@@ -506,7 +509,10 @@ class Resource:
|
|||||||
if self.segment_index == self.total_segments:
|
if self.segment_index == self.total_segments:
|
||||||
if self.callback != None:
|
if self.callback != None:
|
||||||
self.data = open(self.storagepath, "rb")
|
self.data = open(self.storagepath, "rb")
|
||||||
self.callback(self)
|
try:
|
||||||
|
self.callback(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing resource assembled callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.data.close()
|
self.data.close()
|
||||||
@@ -540,7 +546,10 @@ class Resource:
|
|||||||
# If all segments were processed, we'll
|
# If all segments were processed, we'll
|
||||||
# signal that the resource sending concluded
|
# signal that the resource sending concluded
|
||||||
if self.callback != None:
|
if self.callback != None:
|
||||||
self.callback(self)
|
try:
|
||||||
|
self.callback(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing resource concluded callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
else:
|
else:
|
||||||
# Otherwise we'll recursively create the
|
# Otherwise we'll recursively create the
|
||||||
# next segment of the resource
|
# next segment of the resource
|
||||||
@@ -596,7 +605,10 @@ class Resource:
|
|||||||
cp += 1
|
cp += 1
|
||||||
|
|
||||||
if self.__progress_callback != None:
|
if self.__progress_callback != None:
|
||||||
self.__progress_callback(self)
|
try:
|
||||||
|
self.__progress_callback(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
# TODO: Remove debug info
|
# TODO: Remove debug info
|
||||||
# RNS.log("outstanding_parts "+str(self.outstanding_parts))
|
# RNS.log("outstanding_parts "+str(self.outstanding_parts))
|
||||||
@@ -607,8 +619,6 @@ class Resource:
|
|||||||
|
|
||||||
self.receiving_part = False
|
self.receiving_part = False
|
||||||
|
|
||||||
# TODO: Remove
|
|
||||||
#if self.outstanding_parts == 0 and self.received_count == self.total_parts:
|
|
||||||
if self.received_count == self.total_parts:
|
if self.received_count == self.total_parts:
|
||||||
self.assemble()
|
self.assemble()
|
||||||
elif self.outstanding_parts == 0:
|
elif self.outstanding_parts == 0:
|
||||||
@@ -754,7 +764,10 @@ class Resource:
|
|||||||
self.status = Resource.AWAITING_PROOF
|
self.status = Resource.AWAITING_PROOF
|
||||||
|
|
||||||
if self.__progress_callback != None:
|
if self.__progress_callback != None:
|
||||||
self.__progress_callback(self)
|
try:
|
||||||
|
self.__progress_callback(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing progress callback from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
def cancel(self):
|
def cancel(self):
|
||||||
"""
|
"""
|
||||||
@@ -774,8 +787,11 @@ class Resource:
|
|||||||
self.link.cancel_incoming_resource(self)
|
self.link.cancel_incoming_resource(self)
|
||||||
|
|
||||||
if self.callback != None:
|
if self.callback != None:
|
||||||
self.link.resource_concluded(self)
|
try:
|
||||||
self.callback(self)
|
self.link.resource_concluded(self)
|
||||||
|
self.callback(self)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing callbacks on resource cancel from "+str(self)+". The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
def set_callback(self, callback):
|
def set_callback(self, callback):
|
||||||
self.callback = callback
|
self.callback = callback
|
||||||
@@ -804,7 +820,7 @@ class Resource:
|
|||||||
return progress
|
return progress
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
return RNS.prettyhexrep(self.hash)+str(self.link)
|
return "<"+RNS.hexrep(self.hash)+"/"+RNS.hexrep(self.link.link_id)+">"
|
||||||
|
|
||||||
|
|
||||||
class ResourceAdvertisement:
|
class ResourceAdvertisement:
|
||||||
|
|||||||
@@ -193,6 +193,7 @@ class Reticulum:
|
|||||||
self.is_shared_instance = False
|
self.is_shared_instance = False
|
||||||
self.is_standalone_instance = False
|
self.is_standalone_instance = False
|
||||||
self.is_connected_to_shared_instance = True
|
self.is_connected_to_shared_instance = True
|
||||||
|
Reticulum.__transport_enabled = False
|
||||||
RNS.log("Connected to local shared instance via: "+str(interface), RNS.LOG_DEBUG)
|
RNS.log("Connected to local shared instance via: "+str(interface), RNS.LOG_DEBUG)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log("Local shared instance appears to be running, but it could not be connected", RNS.LOG_ERROR)
|
RNS.log("Local shared instance appears to be running, but it could not be connected", RNS.LOG_ERROR)
|
||||||
@@ -510,6 +511,12 @@ class Reticulum:
|
|||||||
if path == "next_hop":
|
if path == "next_hop":
|
||||||
rpc_connection.send(self.get_next_hop(call["destination_hash"]))
|
rpc_connection.send(self.get_next_hop(call["destination_hash"]))
|
||||||
|
|
||||||
|
if path == "packet_rssi":
|
||||||
|
rpc_connection.send(self.get_packet_rssi(call["packet_hash"]))
|
||||||
|
|
||||||
|
if path == "packet_snr":
|
||||||
|
rpc_connection.send(self.get_packet_snr(call["packet_hash"]))
|
||||||
|
|
||||||
rpc_connection.close()
|
rpc_connection.close()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
RNS.log("An error ocurred while handling RPC call from local client: "+str(e), RNS.LOG_ERROR)
|
RNS.log("An error ocurred while handling RPC call from local client: "+str(e), RNS.LOG_ERROR)
|
||||||
@@ -544,6 +551,7 @@ class Reticulum:
|
|||||||
rpc_connection.send({"get": "next_hop_if_name", "destination_hash": destination})
|
rpc_connection.send({"get": "next_hop_if_name", "destination_hash": destination})
|
||||||
response = rpc_connection.recv()
|
response = rpc_connection.recv()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return str(RNS.Transport.next_hop_interface(destination))
|
return str(RNS.Transport.next_hop_interface(destination))
|
||||||
|
|
||||||
@@ -553,9 +561,38 @@ class Reticulum:
|
|||||||
rpc_connection.send({"get": "next_hop", "destination_hash": destination})
|
rpc_connection.send({"get": "next_hop", "destination_hash": destination})
|
||||||
response = rpc_connection.recv()
|
response = rpc_connection.recv()
|
||||||
return response
|
return response
|
||||||
|
|
||||||
else:
|
else:
|
||||||
return RNS.Transport.next_hop(destination)
|
return RNS.Transport.next_hop(destination)
|
||||||
|
|
||||||
|
def get_packet_rssi(self, packet_hash):
|
||||||
|
if self.is_connected_to_shared_instance:
|
||||||
|
rpc_connection = multiprocessing.connection.Client(self.rpc_addr, authkey=self.rpc_key)
|
||||||
|
rpc_connection.send({"get": "packet_rssi", "packet_hash": packet_hash})
|
||||||
|
response = rpc_connection.recv()
|
||||||
|
return response
|
||||||
|
|
||||||
|
else:
|
||||||
|
for entry in RNS.Transport.local_client_rssi_cache:
|
||||||
|
if entry[0] == packet_hash:
|
||||||
|
return entry[1]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
def get_packet_snr(self, packet_hash):
|
||||||
|
if self.is_connected_to_shared_instance:
|
||||||
|
rpc_connection = multiprocessing.connection.Client(self.rpc_addr, authkey=self.rpc_key)
|
||||||
|
rpc_connection.send({"get": "packet_snr", "packet_hash": packet_hash})
|
||||||
|
response = rpc_connection.recv()
|
||||||
|
return response
|
||||||
|
|
||||||
|
else:
|
||||||
|
for entry in RNS.Transport.local_client_snr_cache:
|
||||||
|
if entry[0] == packet_hash:
|
||||||
|
return entry[1]
|
||||||
|
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def should_use_implicit_proof():
|
def should_use_implicit_proof():
|
||||||
|
|||||||
+112
-53
@@ -76,6 +76,10 @@ class Transport:
|
|||||||
# Reticulum instance
|
# Reticulum instance
|
||||||
local_client_interfaces = []
|
local_client_interfaces = []
|
||||||
|
|
||||||
|
local_client_rssi_cache = []
|
||||||
|
local_client_snr_cache = []
|
||||||
|
LOCAL_CLIENT_CACHE_MAXSIZE = 512
|
||||||
|
|
||||||
jobs_locked = False
|
jobs_locked = False
|
||||||
jobs_running = False
|
jobs_running = False
|
||||||
job_interval = 0.250
|
job_interval = 0.250
|
||||||
@@ -583,10 +587,29 @@ class Transport:
|
|||||||
packet.receiving_interface = interface
|
packet.receiving_interface = interface
|
||||||
packet.hops += 1
|
packet.hops += 1
|
||||||
|
|
||||||
if len(Transport.local_client_interfaces) > 0:
|
if interface != None:
|
||||||
|
if hasattr(interface, "r_stat_rssi"):
|
||||||
|
if interface.r_stat_rssi != None:
|
||||||
|
packet.rssi = interface.r_stat_rssi
|
||||||
|
if len(Transport.local_client_interfaces) > 0:
|
||||||
|
Transport.local_client_rssi_cache.append([packet.packet_hash, packet.rssi])
|
||||||
|
|
||||||
|
while len(Transport.local_client_rssi_cache) > Transport.LOCAL_CLIENT_CACHE_MAXSIZE:
|
||||||
|
Transport.local_client_rssi_cache.pop()
|
||||||
|
|
||||||
|
if hasattr(interface, "r_stat_snr"):
|
||||||
|
if interface.r_stat_rssi != None:
|
||||||
|
packet.snr = interface.r_stat_snr
|
||||||
|
if len(Transport.local_client_interfaces) > 0:
|
||||||
|
Transport.local_client_snr_cache.append([packet.packet_hash, packet.snr])
|
||||||
|
|
||||||
|
while len(Transport.local_client_snr_cache) > Transport.LOCAL_CLIENT_CACHE_MAXSIZE:
|
||||||
|
Transport.local_client_snr_cache.pop()
|
||||||
|
|
||||||
|
if len(Transport.local_client_interfaces) > 0:
|
||||||
if Transport.is_local_client_interface(interface):
|
if Transport.is_local_client_interface(interface):
|
||||||
packet.hops -= 1
|
packet.hops -= 1
|
||||||
|
|
||||||
elif Transport.interface_to_shared_instance(interface):
|
elif Transport.interface_to_shared_instance(interface):
|
||||||
packet.hops -= 1
|
packet.hops -= 1
|
||||||
|
|
||||||
@@ -698,7 +721,7 @@ class Transport:
|
|||||||
# TODO: There should probably be some kind of REJECT
|
# TODO: There should probably be some kind of REJECT
|
||||||
# mechanism here, to signal to the source that their
|
# mechanism here, to signal to the source that their
|
||||||
# expected path failed.
|
# expected path failed.
|
||||||
RNS.log("Got packet in transport, but no known path to final destination. Dropping packet.", RNS.LOG_DEBUG)
|
RNS.log("Got packet in transport, but no known path to final destination "+RNS.prettyhexrep(packet.destination_hash)+". Dropping packet.", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
# Link transport handling. Directs packets according
|
# Link transport handling. Directs packets according
|
||||||
# to entries in the link tables
|
# to entries in the link tables
|
||||||
@@ -775,7 +798,8 @@ class Transport:
|
|||||||
# First, check that the announce is not for a destination
|
# First, check that the announce is not for a destination
|
||||||
# local to this system, and that hops are less than the max
|
# local to this system, and that hops are less than the max
|
||||||
if (not any(packet.destination_hash == d.hash for d in Transport.destinations) and packet.hops < Transport.PATHFINDER_M+1):
|
if (not any(packet.destination_hash == d.hash for d in Transport.destinations) and packet.hops < Transport.PATHFINDER_M+1):
|
||||||
random_blob = packet.data[RNS.Identity.KEYSIZE//8+10:RNS.Identity.KEYSIZE//8+20]
|
random_blob = packet.data[RNS.Identity.KEYSIZE//8:RNS.Identity.KEYSIZE//8+RNS.Reticulum.TRUNCATED_HASHLENGTH//8]
|
||||||
|
announce_emitted = int.from_bytes(random_blob[5:10], "big")
|
||||||
random_blobs = []
|
random_blobs = []
|
||||||
if packet.destination_hash in Transport.destination_table:
|
if packet.destination_hash in Transport.destination_table:
|
||||||
random_blobs = Transport.destination_table[packet.destination_hash][4]
|
random_blobs = Transport.destination_table[packet.destination_hash][4]
|
||||||
@@ -796,8 +820,18 @@ class Transport:
|
|||||||
else:
|
else:
|
||||||
# If an announce arrives with a larger hop
|
# If an announce arrives with a larger hop
|
||||||
# count than we already have in the table,
|
# count than we already have in the table,
|
||||||
# ignore it, unless the path is expired
|
# ignore it, unless the path is expired, or
|
||||||
if (time.time() > Transport.destination_table[packet.destination_hash][3]):
|
# the emission timestamp is more recent.
|
||||||
|
now = time.time()
|
||||||
|
path_expires = Transport.destination_table[packet.destination_hash][3]
|
||||||
|
|
||||||
|
path_announce_emitted = 0
|
||||||
|
for path_random_blob in random_blobs:
|
||||||
|
path_announce_emitted = max(path_announce_emitted, int.from_bytes(path_random_blob[5:10], "big"))
|
||||||
|
if path_announce_emitted >= announce_emitted:
|
||||||
|
break
|
||||||
|
|
||||||
|
if (now >= path_expires):
|
||||||
# We also check that the announce hash is
|
# We also check that the announce hash is
|
||||||
# different from ones we've already heard,
|
# different from ones we've already heard,
|
||||||
# to avoid loops in the network
|
# to avoid loops in the network
|
||||||
@@ -809,7 +843,13 @@ class Transport:
|
|||||||
else:
|
else:
|
||||||
should_add = False
|
should_add = False
|
||||||
else:
|
else:
|
||||||
should_add = False
|
if (announce_emitted > path_announce_emitted):
|
||||||
|
if not random_blob in random_blobs:
|
||||||
|
RNS.log("Replacing destination table entry for "+str(RNS.prettyhexrep(packet.destination_hash))+" with new announce, since it was more recently emitted", RNS.LOG_DEBUG)
|
||||||
|
should_add = True
|
||||||
|
else:
|
||||||
|
should_add = False
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# If this destination is unknown in our table
|
# If this destination is unknown in our table
|
||||||
# we should add it
|
# we should add it
|
||||||
@@ -831,6 +871,7 @@ class Transport:
|
|||||||
# If the announce is from a local client,
|
# If the announce is from a local client,
|
||||||
# we announce it immediately, but only one
|
# we announce it immediately, but only one
|
||||||
# time.
|
# time.
|
||||||
|
|
||||||
if Transport.from_local_client(packet):
|
if Transport.from_local_client(packet):
|
||||||
retransmit_timeout = now
|
retransmit_timeout = now
|
||||||
retries = Transport.PATHFINDER_R
|
retries = Transport.PATHFINDER_R
|
||||||
@@ -858,8 +899,8 @@ class Transport:
|
|||||||
announce_data = packet.data
|
announce_data = packet.data
|
||||||
|
|
||||||
if Transport.from_local_client(packet) and packet.context == RNS.Packet.PATH_RESPONSE:
|
if Transport.from_local_client(packet) and packet.context == RNS.Packet.PATH_RESPONSE:
|
||||||
for interface in Transport.interfaces:
|
for local_interface in Transport.local_client_interfaces:
|
||||||
if packet.receiving_interface != interface:
|
if packet.receiving_interface != local_interface:
|
||||||
new_announce = RNS.Packet(
|
new_announce = RNS.Packet(
|
||||||
announce_destination,
|
announce_destination,
|
||||||
announce_data,
|
announce_data,
|
||||||
@@ -868,7 +909,7 @@ class Transport:
|
|||||||
header_type = RNS.Packet.HEADER_2,
|
header_type = RNS.Packet.HEADER_2,
|
||||||
transport_type = Transport.TRANSPORT,
|
transport_type = Transport.TRANSPORT,
|
||||||
transport_id = Transport.identity.hash,
|
transport_id = Transport.identity.hash,
|
||||||
attached_interface = interface
|
attached_interface = local_interface
|
||||||
)
|
)
|
||||||
|
|
||||||
new_announce.hops = packet.hops
|
new_announce.hops = packet.hops
|
||||||
@@ -876,19 +917,20 @@ class Transport:
|
|||||||
|
|
||||||
else:
|
else:
|
||||||
for local_interface in Transport.local_client_interfaces:
|
for local_interface in Transport.local_client_interfaces:
|
||||||
new_announce = RNS.Packet(
|
if packet.receiving_interface != local_interface:
|
||||||
announce_destination,
|
new_announce = RNS.Packet(
|
||||||
announce_data,
|
announce_destination,
|
||||||
RNS.Packet.ANNOUNCE,
|
announce_data,
|
||||||
context = announce_context,
|
RNS.Packet.ANNOUNCE,
|
||||||
header_type = RNS.Packet.HEADER_2,
|
context = announce_context,
|
||||||
transport_type = Transport.TRANSPORT,
|
header_type = RNS.Packet.HEADER_2,
|
||||||
transport_id = Transport.identity.hash,
|
transport_type = Transport.TRANSPORT,
|
||||||
attached_interface = local_interface
|
transport_id = Transport.identity.hash,
|
||||||
)
|
attached_interface = local_interface
|
||||||
|
)
|
||||||
|
|
||||||
new_announce.hops = packet.hops
|
new_announce.hops = packet.hops
|
||||||
new_announce.send()
|
new_announce.send()
|
||||||
|
|
||||||
destination_table_entry = [now, received_from, announce_hops, expires, random_blobs, packet.receiving_interface, packet]
|
destination_table_entry = [now, received_from, announce_hops, expires, random_blobs, packet.receiving_interface, packet]
|
||||||
Transport.destination_table[packet.destination_hash] = destination_table_entry
|
Transport.destination_table[packet.destination_hash] = destination_table_entry
|
||||||
@@ -906,29 +948,30 @@ class Transport:
|
|||||||
|
|
||||||
# Call externally registered callbacks from apps
|
# Call externally registered callbacks from apps
|
||||||
# wanting to know when an announce arrives
|
# wanting to know when an announce arrives
|
||||||
for handler in Transport.announce_handlers:
|
if packet.context != RNS.Packet.PATH_RESPONSE:
|
||||||
try:
|
for handler in Transport.announce_handlers:
|
||||||
# Check that the announced destination matches
|
try:
|
||||||
# the handlers aspect filter
|
# Check that the announced destination matches
|
||||||
execute_callback = False
|
# the handlers aspect filter
|
||||||
if handler.aspect_filter == None:
|
execute_callback = False
|
||||||
# If the handlers aspect filter is set to
|
if handler.aspect_filter == None:
|
||||||
# None, we execute the callback in all cases
|
# If the handlers aspect filter is set to
|
||||||
execute_callback = True
|
# None, we execute the callback in all cases
|
||||||
else:
|
|
||||||
announce_identity = RNS.Identity.recall(packet.destination_hash)
|
|
||||||
handler_expected_hash = RNS.Destination.hash_from_name_and_identity(handler.aspect_filter, announce_identity)
|
|
||||||
if packet.destination_hash == handler_expected_hash:
|
|
||||||
execute_callback = True
|
execute_callback = True
|
||||||
if execute_callback:
|
else:
|
||||||
handler.received_announce(
|
announce_identity = RNS.Identity.recall(packet.destination_hash)
|
||||||
destination_hash=packet.destination_hash,
|
handler_expected_hash = RNS.Destination.hash_from_name_and_identity(handler.aspect_filter, announce_identity)
|
||||||
announced_identity=announce_identity,
|
if packet.destination_hash == handler_expected_hash:
|
||||||
app_data=RNS.Identity.recall_app_data(packet.destination_hash)
|
execute_callback = True
|
||||||
)
|
if execute_callback:
|
||||||
except Exception as e:
|
handler.received_announce(
|
||||||
RNS.log("Error while processing external announce callback.", RNS.LOG_ERROR)
|
destination_hash=packet.destination_hash,
|
||||||
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
announced_identity=announce_identity,
|
||||||
|
app_data=RNS.Identity.recall_app_data(packet.destination_hash)
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while processing external announce callback.", RNS.LOG_ERROR)
|
||||||
|
RNS.log("The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
# Handling for linkrequests to local destinations
|
# Handling for linkrequests to local destinations
|
||||||
elif packet.packet_type == RNS.Packet.LINKREQUEST:
|
elif packet.packet_type == RNS.Packet.LINKREQUEST:
|
||||||
@@ -955,8 +998,11 @@ class Transport:
|
|||||||
|
|
||||||
elif destination.proof_strategy == RNS.Destination.PROVE_APP:
|
elif destination.proof_strategy == RNS.Destination.PROVE_APP:
|
||||||
if destination.callbacks.proof_requested:
|
if destination.callbacks.proof_requested:
|
||||||
if destination.callbacks.proof_requested(packet):
|
try:
|
||||||
packet.prove()
|
if destination.callbacks.proof_requested(packet):
|
||||||
|
packet.prove()
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while executing proof request callback. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
# Handling for proofs and link-request proofs
|
# Handling for proofs and link-request proofs
|
||||||
elif packet.packet_type == RNS.Packet.PROOF:
|
elif packet.packet_type == RNS.Packet.PROOF:
|
||||||
@@ -1092,6 +1138,7 @@ class Transport:
|
|||||||
interface.tunnel_id = tunnel_id
|
interface.tunnel_id = tunnel_id
|
||||||
paths = tunnel_entry[2]
|
paths = tunnel_entry[2]
|
||||||
|
|
||||||
|
deprecated_paths = []
|
||||||
for destination_hash, path_entry in paths.items():
|
for destination_hash, path_entry in paths.items():
|
||||||
received_from = path_entry[1]
|
received_from = path_entry[1]
|
||||||
announce_hops = path_entry[2]
|
announce_hops = path_entry[2]
|
||||||
@@ -1111,11 +1158,20 @@ class Transport:
|
|||||||
else:
|
else:
|
||||||
RNS.log("Did not restore path to "+RNS.prettyhexrep(packet.destination_hash)+" because a newer path with fewer hops exist", RNS.LOG_DEBUG)
|
RNS.log("Did not restore path to "+RNS.prettyhexrep(packet.destination_hash)+" because a newer path with fewer hops exist", RNS.LOG_DEBUG)
|
||||||
else:
|
else:
|
||||||
should_add = True
|
if time.time() < expires:
|
||||||
|
should_add = True
|
||||||
|
else:
|
||||||
|
RNS.log("Did not restore path to "+RNS.prettyhexrep(packet.destination_hash)+" because it has expired", RNS.LOG_DEBUG)
|
||||||
|
|
||||||
if should_add:
|
if should_add:
|
||||||
Transport.destination_table[destination_hash] = new_entry
|
Transport.destination_table[destination_hash] = new_entry
|
||||||
RNS.log("Restored path to "+RNS.prettyhexrep(packet.destination_hash)+" is now "+str(announce_hops)+" hops away via "+RNS.prettyhexrep(received_from)+" on "+str(receiving_interface), RNS.LOG_DEBUG)
|
RNS.log("Restored path to "+RNS.prettyhexrep(packet.destination_hash)+" is now "+str(announce_hops)+" hops away via "+RNS.prettyhexrep(received_from)+" on "+str(receiving_interface), RNS.LOG_DEBUG)
|
||||||
|
else:
|
||||||
|
deprecated_paths.append(destination_hash)
|
||||||
|
|
||||||
|
for deprecated_path in deprecated_paths:
|
||||||
|
RNS.log("Removing path to "+RNS.prettyhexrep(deprecated_path)+" from tunnel "+RNS.prettyhexrep(tunnel_id), RNS.LOG_DEBUG)
|
||||||
|
paths.pop(deprecated_path)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -1337,12 +1393,15 @@ class Transport:
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def path_request_handler(data, packet):
|
def path_request_handler(data, packet):
|
||||||
if len(data) >= RNS.Identity.TRUNCATED_HASHLENGTH//8:
|
try:
|
||||||
Transport.path_request(
|
if len(data) >= RNS.Identity.TRUNCATED_HASHLENGTH//8:
|
||||||
data[:RNS.Identity.TRUNCATED_HASHLENGTH//8],
|
Transport.path_request(
|
||||||
Transport.from_local_client(packet),
|
data[:RNS.Identity.TRUNCATED_HASHLENGTH//8],
|
||||||
packet.receiving_interface
|
Transport.from_local_client(packet),
|
||||||
)
|
packet.receiving_interface
|
||||||
|
)
|
||||||
|
except Exception as e:
|
||||||
|
RNS.log("Error while handling path request. The contained exception was: "+str(e), RNS.LOG_ERROR)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def path_request(destination_hash, is_from_local_client, attached_interface):
|
def path_request(destination_hash, is_from_local_client, attached_interface):
|
||||||
@@ -1353,7 +1412,7 @@ class Transport:
|
|||||||
RNS.log("Destination is local to this system, announcing", RNS.LOG_DEBUG)
|
RNS.log("Destination is local to this system, announcing", RNS.LOG_DEBUG)
|
||||||
local_destination.announce(path_response=True)
|
local_destination.announce(path_response=True)
|
||||||
|
|
||||||
elif (RNS.Reticulum.transport_enabled() or is_from_local_client) and destination_hash in Transport.destination_table:
|
elif (RNS.Reticulum.transport_enabled() or is_from_local_client or len(Transport.local_client_interfaces) > 0) and destination_hash in Transport.destination_table:
|
||||||
RNS.log("Path found, inserting announce for transmission", RNS.LOG_DEBUG)
|
RNS.log("Path found, inserting announce for transmission", RNS.LOG_DEBUG)
|
||||||
packet = Transport.destination_table[destination_hash][6]
|
packet = Transport.destination_table[destination_hash][6]
|
||||||
received_from = Transport.destination_table[destination_hash][5]
|
received_from = Transport.destination_table[destination_hash][5]
|
||||||
|
|||||||
@@ -101,11 +101,31 @@ def program_setup(configdir, destination_hexhash, size=DEFAULT_PROBE_SIZE, full_
|
|||||||
rtt = round(rtt*1000, 3)
|
rtt = round(rtt*1000, 3)
|
||||||
rttstring = str(rtt)+" milliseconds"
|
rttstring = str(rtt)+" milliseconds"
|
||||||
|
|
||||||
|
reception_stats = ""
|
||||||
|
if reticulum.is_connected_to_shared_instance:
|
||||||
|
reception_rssi = reticulum.get_packet_rssi(receipt.proof_packet.packet_hash)
|
||||||
|
reception_snr = reticulum.get_packet_snr(receipt.proof_packet.packet_hash)
|
||||||
|
|
||||||
|
if reception_rssi != None:
|
||||||
|
reception_stats += " [RSSI "+str(reception_rssi)+" dBm]"
|
||||||
|
|
||||||
|
if reception_snr != None:
|
||||||
|
reception_stats += " [SNR "+str(reception_snr)+" dB]"
|
||||||
|
|
||||||
|
else:
|
||||||
|
if receipt.proof_packet != None:
|
||||||
|
if receipt.proof_packet.rssi != None:
|
||||||
|
reception_stats += " [RSSI "+str(receipt.proof_packet.rssi)+" dBm]"
|
||||||
|
|
||||||
|
if receipt.proof_packet.snr != None:
|
||||||
|
reception_stats += " [SNR "+str(receipt.proof_packet.snr)+" dB]"
|
||||||
|
|
||||||
print(
|
print(
|
||||||
"Valid reply received from "+
|
"Valid reply received from "+
|
||||||
RNS.prettyhexrep(receipt.destination.hash)+
|
RNS.prettyhexrep(receipt.destination.hash)+
|
||||||
"\nRound-trip time is "+rttstring+
|
"\nRound-trip time is "+rttstring+
|
||||||
" over "+str(hops)+" hop"+ms
|
" over "+str(hops)+" hop"+ms+
|
||||||
|
reception_stats
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -32,8 +32,8 @@ def program_setup(configdir, dispall=False, verbosity = 0):
|
|||||||
for ifstat in ifstats:
|
for ifstat in ifstats:
|
||||||
name = ifstat["name"]
|
name = ifstat["name"]
|
||||||
|
|
||||||
print("")
|
|
||||||
if dispall or not (name.startswith("LocalInterface[") or name.startswith("TCPInterface[Client")):
|
if dispall or not (name.startswith("LocalInterface[") or name.startswith("TCPInterface[Client")):
|
||||||
|
print("")
|
||||||
if ifstat["status"]:
|
if ifstat["status"]:
|
||||||
ss = "Up"
|
ss = "Up"
|
||||||
else:
|
else:
|
||||||
@@ -42,7 +42,7 @@ def program_setup(configdir, dispall=False, verbosity = 0):
|
|||||||
if ifstat["clients"] != None:
|
if ifstat["clients"] != None:
|
||||||
clients = ifstat["clients"]
|
clients = ifstat["clients"]
|
||||||
if name.startswith("Shared Instance["):
|
if name.startswith("Shared Instance["):
|
||||||
clients_string = "Connected applications: "+str(clients-1)
|
clients_string = "Connected applications: "+str(max(clients-1,0))
|
||||||
else:
|
else:
|
||||||
clients_string = "Connected clients: "+str(clients)
|
clients_string = "Connected clients: "+str(clients)
|
||||||
|
|
||||||
@@ -55,6 +55,8 @@ def program_setup(configdir, dispall=False, verbosity = 0):
|
|||||||
print("\t"+clients_string)
|
print("\t"+clients_string)
|
||||||
print("\tRX: {rxb}\n\tTX: {txb}".format(rxb=size_str(ifstat["rxb"]), txb=size_str(ifstat["txb"])))
|
print("\tRX: {rxb}\n\tTX: {txb}".format(rxb=size_str(ifstat["rxb"]), txb=size_str(ifstat["txb"])))
|
||||||
|
|
||||||
|
print("")
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print("Could not get RNS status")
|
print("Could not get RNS status")
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,8 @@ LOG_EXTREME = 7
|
|||||||
LOG_STDOUT = 0x91
|
LOG_STDOUT = 0x91
|
||||||
LOG_FILE = 0x92
|
LOG_FILE = 0x92
|
||||||
|
|
||||||
|
LOG_MAXSIZE = 5*1024*1024
|
||||||
|
|
||||||
loglevel = LOG_NOTICE
|
loglevel = LOG_NOTICE
|
||||||
logfile = None
|
logfile = None
|
||||||
logdest = LOG_STDOUT
|
logdest = LOG_STDOUT
|
||||||
@@ -82,6 +84,13 @@ def log(msg, level=3, _override_destination = False):
|
|||||||
file = open(logfile, "a")
|
file = open(logfile, "a")
|
||||||
file.write(logstring+"\n")
|
file.write(logstring+"\n")
|
||||||
file.close()
|
file.close()
|
||||||
|
|
||||||
|
if os.path.getsize(logfile) > LOG_MAXSIZE:
|
||||||
|
prevfile = logfile+".1"
|
||||||
|
if os.path.isfile(prevfile):
|
||||||
|
os.unlink(prevfile)
|
||||||
|
os.rename(logfile, prevfile)
|
||||||
|
|
||||||
logging_lock.release()
|
logging_lock.release()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logging_lock.release()
|
logging_lock.release()
|
||||||
|
|||||||
+1
-1
@@ -1 +1 @@
|
|||||||
__version__ = "0.2.6"
|
__version__ = "0.2.9"
|
||||||
Binary file not shown.
@@ -1,4 +1,4 @@
|
|||||||
# Sphinx build info version 1
|
# 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.
|
# This file hashes the configuration used when building these files. When it is not found, a full rebuild will be done.
|
||||||
config: bf2e68cefd79a49afe077549bac593bf
|
config: 427f8d18d50a00634173570b6c54ba3a
|
||||||
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
tags: 645f666f9bcd5a90fca523b33c5a78b7
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Try Using a Reticulum-based Program
|
|||||||
=============================================
|
=============================================
|
||||||
If you simply want to try using a program built with Reticulum, you can take
|
If you simply want to try using a program built with Reticulum, you can take
|
||||||
a look at `Nomad Network <https://github.com/markqvist/nomadnet>`_, which
|
a look at `Nomad Network <https://github.com/markqvist/nomadnet>`_, which
|
||||||
provides a basic encrypted communications suite built completely on Reticulum.
|
provides a complete encrypted communications suite built with Reticulum.
|
||||||
|
|
||||||
.. image:: screenshots/nomadnet_3.png
|
.. image:: screenshots/nomadnet_3.png
|
||||||
:target: _images/nomadnet_3.png
|
:target: _images/nomadnet_3.png
|
||||||
@@ -31,9 +31,21 @@ You can install Nomad Network via pip:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Using the Included Utilities
|
||||||
|
=============================================
|
||||||
|
Reticulum comes with a range of included utilities that make it easier to
|
||||||
|
manage your network, check connectivity and make Reticulum available to other
|
||||||
|
programs on your system.
|
||||||
|
|
||||||
|
You can use ``rnsd`` to run Reticulum as a background or foreground service,
|
||||||
|
and the ``rnstatus``, ``rnpath`` and ``rnprobe`` utilities to view and query
|
||||||
|
network status and connectivity.
|
||||||
|
|
||||||
|
To learn more about these utility programs, have a look at the
|
||||||
|
:ref:`Using Reticulum on Your System<using-main>` chapter of this manual.
|
||||||
|
|
||||||
Creating a Network With Reticulum
|
Creating a Network With Reticulum
|
||||||
=============================================
|
=============================================
|
||||||
|
|
||||||
To create a network, you will need to specify one or more *interfaces* for
|
To create a network, you will need to specify one or more *interfaces* for
|
||||||
Reticulum to use. This is done in the Reticulum configuration file, which by
|
Reticulum to use. This is done in the Reticulum configuration file, which by
|
||||||
default is located at ``~/.reticulum/config``.
|
default is located at ``~/.reticulum/config``.
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ for Reticulum to use.
|
|||||||
The following sections describe the interfaces currently available in Reticulum,
|
The following sections describe the interfaces currently available in Reticulum,
|
||||||
and gives example configurations for the respective interface types.
|
and gives example configurations for the respective interface types.
|
||||||
|
|
||||||
|
For a high-level overview of how networks can be formed over different interface
|
||||||
|
types, have a look at the :ref:`Building Networks<networks-main>` chapter of this
|
||||||
|
manual.
|
||||||
|
|
||||||
.. _interfaces-udp:
|
.. _interfaces-udp:
|
||||||
|
|
||||||
UDP Interface
|
UDP Interface
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ the underlying carrier for Reticulum.
|
|||||||
However, most real-world networks will probably involve either some form of
|
However, most real-world networks will probably involve either some form of
|
||||||
wireless or direct hardline communications. To allow Reticulum to communicate
|
wireless or direct hardline communications. To allow Reticulum to communicate
|
||||||
over any type of medium, you must specify it in the configuration file, by default
|
over any type of medium, you must specify it in the configuration file, by default
|
||||||
located at ``~/.reticulum/config``.
|
located at ``~/.reticulum/config``. See the :ref:`Supported Interfaces<interfaces-main>`
|
||||||
|
chapter of this manual for interface configuration examples.
|
||||||
|
|
||||||
Any number of interfaces can be configured, and Reticulum will automatically
|
Any number of interfaces can be configured, and Reticulum will automatically
|
||||||
decide which are suitable to use in any given situation, depending on where
|
decide which are suitable to use in any given situation, depending on where
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ What does Reticulum Offer?
|
|||||||
|
|
||||||
* Fully self-configuring multi-hop routing
|
* 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
|
* 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 ephemereal Elliptic Curve Diffie-Hellman keys on Curve25519
|
||||||
@@ -65,7 +67,7 @@ What does Reticulum Offer?
|
|||||||
Where can Reticulum be Used?
|
Where can Reticulum be Used?
|
||||||
============================
|
============================
|
||||||
Over practically any medium that can support at least a half-duplex channel
|
Over practically any medium that can support at least a half-duplex channel
|
||||||
with 1.000 bits per second throughput, and an MTU of 500 bytes. Data radios,
|
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,
|
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
|
ad-hoc WiFi, free-space optical links and similar systems are all examples
|
||||||
of the types of interfaces Reticulum was designed for.
|
of the types of interfaces Reticulum was designed for.
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
var DOCUMENTATION_OPTIONS = {
|
var DOCUMENTATION_OPTIONS = {
|
||||||
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'),
|
||||||
VERSION: '0.2.6 beta',
|
VERSION: '0.2.8 beta',
|
||||||
LANGUAGE: 'None',
|
LANGUAGE: 'None',
|
||||||
COLLAPSE_INDEX: false,
|
COLLAPSE_INDEX: false,
|
||||||
BUILDER: 'html',
|
BUILDER: 'html',
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Code Examples — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>Code Examples — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="reference.html" title="API Reference"
|
<a href="reference.html" title="API Reference"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Code Examples</a></li>
|
<li class="nav-item nav-item-this"><a href="">Code Examples</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -488,6 +488,8 @@ the Packet interface.</p>
|
|||||||
<span class="c1"># This initialisation is executed when the users chooses</span>
|
<span class="c1"># This initialisation is executed when the users chooses</span>
|
||||||
<span class="c1"># to run as a server</span>
|
<span class="c1"># to run as a server</span>
|
||||||
<span class="k">def</span> <span class="nf">server</span><span class="p">(</span><span class="n">configpath</span><span class="p">):</span>
|
<span class="k">def</span> <span class="nf">server</span><span class="p">(</span><span class="n">configpath</span><span class="p">):</span>
|
||||||
|
<span class="k">global</span> <span class="n">reticulum</span>
|
||||||
|
|
||||||
<span class="c1"># We must first initialise Reticulum</span>
|
<span class="c1"># We must first initialise Reticulum</span>
|
||||||
<span class="n">reticulum</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="p">(</span><span class="n">configpath</span><span class="p">)</span>
|
<span class="n">reticulum</span> <span class="o">=</span> <span class="n">RNS</span><span class="o">.</span><span class="n">Reticulum</span><span class="p">(</span><span class="n">configpath</span><span class="p">)</span>
|
||||||
|
|
||||||
@@ -544,11 +546,32 @@ the Packet interface.</p>
|
|||||||
|
|
||||||
|
|
||||||
<span class="k">def</span> <span class="nf">server_callback</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
|
<span class="k">def</span> <span class="nf">server_callback</span><span class="p">(</span><span class="n">message</span><span class="p">,</span> <span class="n">packet</span><span class="p">):</span>
|
||||||
|
<span class="k">global</span> <span class="n">reticulum</span>
|
||||||
|
|
||||||
<span class="c1"># Tell the user that we received an echo request, and</span>
|
<span class="c1"># Tell the user that we received an echo request, and</span>
|
||||||
<span class="c1"># that we are going to send a reply to the requester.</span>
|
<span class="c1"># that we are going to send a reply to the requester.</span>
|
||||||
<span class="c1"># Sending the proof is handled automatically, since we</span>
|
<span class="c1"># Sending the proof is handled automatically, since we</span>
|
||||||
<span class="c1"># set up the destination to prove all incoming packets.</span>
|
<span class="c1"># set up the destination to prove all incoming packets.</span>
|
||||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Received packet from echo client, proof sent"</span><span class="p">)</span>
|
|
||||||
|
<span class="n">reception_stats</span> <span class="o">=</span> <span class="s2">""</span>
|
||||||
|
<span class="k">if</span> <span class="n">reticulum</span><span class="o">.</span><span class="n">is_connected_to_shared_instance</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_rssi</span> <span class="o">=</span> <span class="n">reticulum</span><span class="o">.</span><span class="n">get_packet_rssi</span><span class="p">(</span><span class="n">packet</span><span class="o">.</span><span class="n">packet_hash</span><span class="p">)</span>
|
||||||
|
<span class="n">reception_snr</span> <span class="o">=</span> <span class="n">reticulum</span><span class="o">.</span><span class="n">get_packet_snr</span><span class="p">(</span><span class="n">packet</span><span class="o">.</span><span class="n">packet_hash</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="n">reception_rssi</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_stats</span> <span class="o">+=</span> <span class="s2">" [RSSI "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">reception_rssi</span><span class="p">)</span><span class="o">+</span><span class="s2">" dBm]"</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="n">reception_snr</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_stats</span> <span class="o">+=</span> <span class="s2">" [SNR "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">reception_snr</span><span class="p">)</span><span class="o">+</span><span class="s2">" dBm]"</span>
|
||||||
|
|
||||||
|
<span class="k">else</span><span class="p">:</span>
|
||||||
|
<span class="k">if</span> <span class="n">packet</span><span class="o">.</span><span class="n">rssi</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_stats</span> <span class="o">+=</span> <span class="s2">" [RSSI "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">packet</span><span class="o">.</span><span class="n">rssi</span><span class="p">)</span><span class="o">+</span><span class="s2">" dBm]"</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="n">packet</span><span class="o">.</span><span class="n">snr</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_stats</span> <span class="o">+=</span> <span class="s2">" [SNR "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">packet</span><span class="o">.</span><span class="n">snr</span><span class="p">)</span><span class="o">+</span><span class="s2">" dB]"</span>
|
||||||
|
|
||||||
|
<span class="n">RNS</span><span class="o">.</span><span class="n">log</span><span class="p">(</span><span class="s2">"Received packet from echo client, proof sent"</span><span class="o">+</span><span class="n">reception_stats</span><span class="p">)</span>
|
||||||
|
|
||||||
|
|
||||||
<span class="c1">##########################################################</span>
|
<span class="c1">##########################################################</span>
|
||||||
@@ -558,6 +581,8 @@ the Packet interface.</p>
|
|||||||
<span class="c1"># This initialisation is executed when the users chooses</span>
|
<span class="c1"># This initialisation is executed when the users chooses</span>
|
||||||
<span class="c1"># to run as a client</span>
|
<span class="c1"># to run as a client</span>
|
||||||
<span class="k">def</span> <span class="nf">client</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">,</span> <span class="n">configpath</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
<span class="k">def</span> <span class="nf">client</span><span class="p">(</span><span class="n">destination_hexhash</span><span class="p">,</span> <span class="n">configpath</span><span class="p">,</span> <span class="n">timeout</span><span class="o">=</span><span class="kc">None</span><span class="p">):</span>
|
||||||
|
<span class="k">global</span> <span class="n">reticulum</span>
|
||||||
|
|
||||||
<span class="c1"># We need a binary representation of the destination</span>
|
<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="c1"># hash that was entered on the command line</span>
|
||||||
<span class="k">try</span><span class="p">:</span>
|
<span class="k">try</span><span class="p">:</span>
|
||||||
@@ -654,6 +679,8 @@ the Packet interface.</p>
|
|||||||
<span class="c1"># This function is called when our reply destination</span>
|
<span class="c1"># This function is called when our reply destination</span>
|
||||||
<span class="c1"># receives a proof packet.</span>
|
<span class="c1"># receives a proof packet.</span>
|
||||||
<span class="k">def</span> <span class="nf">packet_delivered</span><span class="p">(</span><span class="n">receipt</span><span class="p">):</span>
|
<span class="k">def</span> <span class="nf">packet_delivered</span><span class="p">(</span><span class="n">receipt</span><span class="p">):</span>
|
||||||
|
<span class="k">global</span> <span class="n">reticulum</span>
|
||||||
|
|
||||||
<span class="k">if</span> <span class="n">receipt</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="n">RNS</span><span class="o">.</span><span class="n">PacketReceipt</span><span class="o">.</span><span class="n">DELIVERED</span><span class="p">:</span>
|
<span class="k">if</span> <span class="n">receipt</span><span class="o">.</span><span class="n">status</span> <span class="o">==</span> <span class="n">RNS</span><span class="o">.</span><span class="n">PacketReceipt</span><span class="o">.</span><span class="n">DELIVERED</span><span class="p">:</span>
|
||||||
<span class="n">rtt</span> <span class="o">=</span> <span class="n">receipt</span><span class="o">.</span><span class="n">get_rtt</span><span class="p">()</span>
|
<span class="n">rtt</span> <span class="o">=</span> <span class="n">receipt</span><span class="o">.</span><span class="n">get_rtt</span><span class="p">()</span>
|
||||||
<span class="k">if</span> <span class="p">(</span><span class="n">rtt</span> <span class="o">>=</span> <span class="mi">1</span><span class="p">):</span>
|
<span class="k">if</span> <span class="p">(</span><span class="n">rtt</span> <span class="o">>=</span> <span class="mi">1</span><span class="p">):</span>
|
||||||
@@ -663,10 +690,30 @@ the Packet interface.</p>
|
|||||||
<span class="n">rtt</span> <span class="o">=</span> <span class="nb">round</span><span class="p">(</span><span class="n">rtt</span><span class="o">*</span><span class="mi">1000</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
<span class="n">rtt</span> <span class="o">=</span> <span class="nb">round</span><span class="p">(</span><span class="n">rtt</span><span class="o">*</span><span class="mi">1000</span><span class="p">,</span> <span class="mi">3</span><span class="p">)</span>
|
||||||
<span class="n">rttstring</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">rtt</span><span class="p">)</span><span class="o">+</span><span class="s2">" milliseconds"</span>
|
<span class="n">rttstring</span> <span class="o">=</span> <span class="nb">str</span><span class="p">(</span><span class="n">rtt</span><span class="p">)</span><span class="o">+</span><span class="s2">" milliseconds"</span>
|
||||||
|
|
||||||
|
<span class="n">reception_stats</span> <span class="o">=</span> <span class="s2">""</span>
|
||||||
|
<span class="k">if</span> <span class="n">reticulum</span><span class="o">.</span><span class="n">is_connected_to_shared_instance</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_rssi</span> <span class="o">=</span> <span class="n">reticulum</span><span class="o">.</span><span class="n">get_packet_rssi</span><span class="p">(</span><span class="n">receipt</span><span class="o">.</span><span class="n">proof_packet</span><span class="o">.</span><span class="n">packet_hash</span><span class="p">)</span>
|
||||||
|
<span class="n">reception_snr</span> <span class="o">=</span> <span class="n">reticulum</span><span class="o">.</span><span class="n">get_packet_snr</span><span class="p">(</span><span class="n">receipt</span><span class="o">.</span><span class="n">proof_packet</span><span class="o">.</span><span class="n">packet_hash</span><span class="p">)</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="n">reception_rssi</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_stats</span> <span class="o">+=</span> <span class="s2">" [RSSI "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">reception_rssi</span><span class="p">)</span><span class="o">+</span><span class="s2">" dBm]"</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="n">reception_snr</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_stats</span> <span class="o">+=</span> <span class="s2">" [SNR "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">reception_snr</span><span class="p">)</span><span class="o">+</span><span class="s2">" dB]"</span>
|
||||||
|
|
||||||
|
<span class="k">else</span><span class="p">:</span>
|
||||||
|
<span class="k">if</span> <span class="n">receipt</span><span class="o">.</span><span class="n">proof_packet</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="k">if</span> <span class="n">receipt</span><span class="o">.</span><span class="n">proof_packet</span><span class="o">.</span><span class="n">rssi</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_stats</span> <span class="o">+=</span> <span class="s2">" [RSSI "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">receipt</span><span class="o">.</span><span class="n">proof_packet</span><span class="o">.</span><span class="n">rssi</span><span class="p">)</span><span class="o">+</span><span class="s2">" dBm]"</span>
|
||||||
|
|
||||||
|
<span class="k">if</span> <span class="n">receipt</span><span class="o">.</span><span class="n">proof_packet</span><span class="o">.</span><span class="n">snr</span> <span class="o">!=</span> <span class="kc">None</span><span class="p">:</span>
|
||||||
|
<span class="n">reception_stats</span> <span class="o">+=</span> <span class="s2">" [SNR "</span><span class="o">+</span><span class="nb">str</span><span class="p">(</span><span class="n">receipt</span><span class="o">.</span><span class="n">proof_packet</span><span class="o">.</span><span class="n">snr</span><span class="p">)</span><span class="o">+</span><span class="s2">" dB]"</span>
|
||||||
|
|
||||||
<span class="n">RNS</span><span class="o">.</span><span class="n">log</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">"Valid reply received from "</span><span class="o">+</span>
|
<span class="s2">"Valid reply received from "</span><span class="o">+</span>
|
||||||
<span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">receipt</span><span class="o">.</span><span class="n">destination</span><span class="o">.</span><span class="n">hash</span><span class="p">)</span><span class="o">+</span>
|
<span class="n">RNS</span><span class="o">.</span><span class="n">prettyhexrep</span><span class="p">(</span><span class="n">receipt</span><span class="o">.</span><span class="n">destination</span><span class="o">.</span><span class="n">hash</span><span class="p">)</span><span class="o">+</span>
|
||||||
<span class="s2">", round-trip time is "</span><span class="o">+</span><span class="n">rttstring</span>
|
<span class="s2">", round-trip time is "</span><span class="o">+</span><span class="n">rttstring</span><span class="o">+</span>
|
||||||
|
<span class="n">reception_stats</span>
|
||||||
<span class="p">)</span>
|
<span class="p">)</span>
|
||||||
|
|
||||||
<span class="c1"># This function is called if a packet times out.</span>
|
<span class="c1"># This function is called if a packet times out.</span>
|
||||||
@@ -2319,7 +2366,7 @@ interface to efficiently pass files of any size over a Reticulum <a class="refer
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="reference.html" title="API Reference"
|
<a href="reference.html" title="API Reference"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Code Examples</a></li>
|
<li class="nav-item nav-item-this"><a href="">Code Examples</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Index — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>Index — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||||
|
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
<li class="right" style="margin-right: 10px">
|
<li class="right" style="margin-right: 10px">
|
||||||
<a href="#" title="General Index"
|
<a href="#" title="General Index"
|
||||||
accesskey="I">index</a></li>
|
accesskey="I">index</a></li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Index</a></li>
|
<li class="nav-item nav-item-this"><a href="">Index</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -416,7 +416,7 @@
|
|||||||
<li class="right" style="margin-right: 10px">
|
<li class="right" style="margin-right: 10px">
|
||||||
<a href="#" title="General Index"
|
<a href="#" title="General Index"
|
||||||
>index</a></li>
|
>index</a></li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Index</a></li>
|
<li class="nav-item nav-item-this"><a href="">Index</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Getting Started Fast — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>Getting Started Fast — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="whatis.html" title="What is Reticulum?"
|
<a href="whatis.html" title="What is Reticulum?"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
|
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -50,7 +50,7 @@ scenarios.</p>
|
|||||||
<h2>Try Using a Reticulum-based Program<a class="headerlink" href="#try-using-a-reticulum-based-program" title="Permalink to this headline">¶</a></h2>
|
<h2>Try Using a Reticulum-based Program<a class="headerlink" href="#try-using-a-reticulum-based-program" title="Permalink to this headline">¶</a></h2>
|
||||||
<p>If you simply want to try using a program built with Reticulum, you can take
|
<p>If you simply want to try using a program built with Reticulum, you can take
|
||||||
a look at <a class="reference external" href="https://github.com/markqvist/nomadnet">Nomad Network</a>, which
|
a look at <a class="reference external" href="https://github.com/markqvist/nomadnet">Nomad Network</a>, which
|
||||||
provides a basic encrypted communications suite built completely on Reticulum.</p>
|
provides a complete encrypted communications suite built with Reticulum.</p>
|
||||||
<a class="reference external image-reference" href="_images/nomadnet_3.png"><img alt="_images/nomadnet_3.png" src="_images/nomadnet_3.png" /></a>
|
<a class="reference external image-reference" href="_images/nomadnet_3.png"><img alt="_images/nomadnet_3.png" src="_images/nomadnet_3.png" /></a>
|
||||||
<p><a class="reference external" href="https://github.com/markqvist/nomadnet">Nomad Network</a> is a user-facing client
|
<p><a class="reference external" href="https://github.com/markqvist/nomadnet">Nomad Network</a> is a user-facing client
|
||||||
in the development for the messaging and information-sharing protocol
|
in the development for the messaging and information-sharing protocol
|
||||||
@@ -64,6 +64,17 @@ in the development for the messaging and information-sharing protocol
|
|||||||
</pre></div>
|
</pre></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="section" id="using-the-included-utilities">
|
||||||
|
<h2>Using the Included Utilities<a class="headerlink" href="#using-the-included-utilities" title="Permalink to this headline">¶</a></h2>
|
||||||
|
<p>Reticulum comes with a range of included utilities that make it easier to
|
||||||
|
manage your network, check connectivity and make Reticulum available to other
|
||||||
|
programs on your system.</p>
|
||||||
|
<p>You can use <code class="docutils literal notranslate"><span class="pre">rnsd</span></code> to run Reticulum as a background or foreground service,
|
||||||
|
and the <code class="docutils literal notranslate"><span class="pre">rnstatus</span></code>, <code class="docutils literal notranslate"><span class="pre">rnpath</span></code> and <code class="docutils literal notranslate"><span class="pre">rnprobe</span></code> utilities to view and query
|
||||||
|
network status and connectivity.</p>
|
||||||
|
<p>To learn more about these utility programs, have a look at the
|
||||||
|
<a class="reference internal" href="using.html#using-main"><span class="std std-ref">Using Reticulum on Your System</span></a> chapter of this manual.</p>
|
||||||
|
</div>
|
||||||
<div class="section" id="creating-a-network-with-reticulum">
|
<div class="section" id="creating-a-network-with-reticulum">
|
||||||
<h2>Creating a Network With Reticulum<a class="headerlink" href="#creating-a-network-with-reticulum" title="Permalink to this headline">¶</a></h2>
|
<h2>Creating a Network With Reticulum<a class="headerlink" href="#creating-a-network-with-reticulum" title="Permalink to this headline">¶</a></h2>
|
||||||
<p>To create a network, you will need to specify one or more <em>interfaces</em> for
|
<p>To create a network, you will need to specify one or more <em>interfaces</em> for
|
||||||
@@ -145,6 +156,7 @@ don’t use pip, but try this recipe:</p>
|
|||||||
<ul>
|
<ul>
|
||||||
<li><a class="reference internal" href="#">Getting Started Fast</a><ul>
|
<li><a class="reference internal" href="#">Getting Started Fast</a><ul>
|
||||||
<li><a class="reference internal" href="#try-using-a-reticulum-based-program">Try Using a Reticulum-based Program</a></li>
|
<li><a class="reference internal" href="#try-using-a-reticulum-based-program">Try Using a Reticulum-based Program</a></li>
|
||||||
|
<li><a class="reference internal" href="#using-the-included-utilities">Using the Included Utilities</a></li>
|
||||||
<li><a class="reference internal" href="#creating-a-network-with-reticulum">Creating a Network With Reticulum</a></li>
|
<li><a class="reference internal" href="#creating-a-network-with-reticulum">Creating a Network With Reticulum</a></li>
|
||||||
<li><a class="reference internal" href="#develop-a-program-with-reticulum">Develop a Program with Reticulum</a></li>
|
<li><a class="reference internal" href="#develop-a-program-with-reticulum">Develop a Program with Reticulum</a></li>
|
||||||
<li><a class="reference internal" href="#participate-in-reticulum-development">Participate in Reticulum Development</a></li>
|
<li><a class="reference internal" href="#participate-in-reticulum-development">Participate in Reticulum Development</a></li>
|
||||||
@@ -191,7 +203,7 @@ don’t use pip, but try this recipe:</p>
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="whatis.html" title="What is Reticulum?"
|
<a href="whatis.html" title="What is Reticulum?"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
|
<li class="nav-item nav-item-this"><a href="">Getting Started Fast</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Reticulum Network Stack Manual — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>Reticulum Network Stack Manual — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||||
|
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="whatis.html" title="What is Reticulum?"
|
<a href="whatis.html" title="What is Reticulum?"
|
||||||
accesskey="N">next</a> |</li>
|
accesskey="N">next</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
|
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -54,6 +54,7 @@ to participate in the development of Reticulum itself.</p>
|
|||||||
</li>
|
</li>
|
||||||
<li class="toctree-l1"><a class="reference internal" href="gettingstartedfast.html">Getting Started Fast</a><ul>
|
<li class="toctree-l1"><a class="reference internal" href="gettingstartedfast.html">Getting Started Fast</a><ul>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="gettingstartedfast.html#try-using-a-reticulum-based-program">Try Using a Reticulum-based Program</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="gettingstartedfast.html#try-using-a-reticulum-based-program">Try Using a Reticulum-based Program</a></li>
|
||||||
|
<li class="toctree-l2"><a class="reference internal" href="gettingstartedfast.html#using-the-included-utilities">Using the Included Utilities</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="gettingstartedfast.html#creating-a-network-with-reticulum">Creating a Network With Reticulum</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="gettingstartedfast.html#creating-a-network-with-reticulum">Creating a Network With Reticulum</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="gettingstartedfast.html#develop-a-program-with-reticulum">Develop a Program with Reticulum</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="gettingstartedfast.html#develop-a-program-with-reticulum">Develop a Program with Reticulum</a></li>
|
||||||
<li class="toctree-l2"><a class="reference internal" href="gettingstartedfast.html#participate-in-reticulum-development">Participate in Reticulum Development</a></li>
|
<li class="toctree-l2"><a class="reference internal" href="gettingstartedfast.html#participate-in-reticulum-development">Participate in Reticulum Development</a></li>
|
||||||
@@ -199,7 +200,7 @@ to participate in the development of Reticulum itself.</p>
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="whatis.html" title="What is Reticulum?"
|
<a href="whatis.html" title="What is Reticulum?"
|
||||||
>next</a> |</li>
|
>next</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="#">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
|
<li class="nav-item nav-item-this"><a href="">Reticulum Network Stack Manual</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Supported Interfaces — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>Supported Interfaces — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="networks.html" title="Building Networks"
|
<a href="networks.html" title="Building Networks"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Supported Interfaces</a></li>
|
<li class="nav-item nav-item-this"><a href="">Supported Interfaces</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -50,6 +50,9 @@ common to them all is that you will need to define one or more <em>interfaces</e
|
|||||||
for Reticulum to use.</p>
|
for Reticulum to use.</p>
|
||||||
<p>The following sections describe the interfaces currently available in Reticulum,
|
<p>The following sections describe the interfaces currently available in Reticulum,
|
||||||
and gives example configurations for the respective interface types.</p>
|
and gives example configurations for the respective interface types.</p>
|
||||||
|
<p>For a high-level overview of how networks can be formed over different interface
|
||||||
|
types, have a look at the <a class="reference internal" href="networks.html#networks-main"><span class="std std-ref">Building Networks</span></a> chapter of this
|
||||||
|
manual.</p>
|
||||||
<div class="section" id="udp-interface">
|
<div class="section" id="udp-interface">
|
||||||
<span id="interfaces-udp"></span><h2>UDP Interface<a class="headerlink" href="#udp-interface" title="Permalink to this headline">¶</a></h2>
|
<span id="interfaces-udp"></span><h2>UDP Interface<a class="headerlink" href="#udp-interface" title="Permalink to this headline">¶</a></h2>
|
||||||
<p>A UDP interface can be useful for communicating over IP networks, both
|
<p>A UDP interface can be useful for communicating over IP networks, both
|
||||||
@@ -406,7 +409,7 @@ beaconing functionality described above.</p>
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="networks.html" title="Building Networks"
|
<a href="networks.html" title="Building Networks"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Supported Interfaces</a></li>
|
<li class="nav-item nav-item-this"><a href="">Supported Interfaces</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Building Networks — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>Building Networks — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="using.html" title="Using Reticulum on Your System"
|
<a href="using.html" title="Using Reticulum on Your System"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Building Networks</a></li>
|
<li class="nav-item nav-item-this"><a href="">Building Networks</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -114,7 +114,8 @@ the underlying carrier for Reticulum.</p>
|
|||||||
<p>However, most real-world networks will probably involve either some form of
|
<p>However, most real-world networks will probably involve either some form of
|
||||||
wireless or direct hardline communications. To allow Reticulum to communicate
|
wireless or direct hardline communications. To allow Reticulum to communicate
|
||||||
over any type of medium, you must specify it in the configuration file, by default
|
over any type of medium, you must specify it in the configuration file, by default
|
||||||
located at <code class="docutils literal notranslate"><span class="pre">~/.reticulum/config</span></code>.</p>
|
located at <code class="docutils literal notranslate"><span class="pre">~/.reticulum/config</span></code>. See the <a class="reference internal" href="interfaces.html#interfaces-main"><span class="std std-ref">Supported Interfaces</span></a>
|
||||||
|
chapter of this manual for interface configuration examples.</p>
|
||||||
<p>Any number of interfaces can be configured, and Reticulum will automatically
|
<p>Any number of interfaces can be configured, and Reticulum will automatically
|
||||||
decide which are suitable to use in any given situation, depending on where
|
decide which are suitable to use in any given situation, depending on where
|
||||||
traffic needs to flow.</p>
|
traffic needs to flow.</p>
|
||||||
@@ -246,7 +247,7 @@ connected outliers are now an integral part of the network.</p>
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="using.html" title="Using Reticulum on Your System"
|
<a href="using.html" title="Using Reticulum on Your System"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Building Networks</a></li>
|
<li class="nav-item nav-item-this"><a href="">Building Networks</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>API Reference — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>API Reference — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.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="index" title="Index" href="genindex.html" />
|
||||||
<link rel="search" title="Search" href="search.html" />
|
<link rel="search" title="Search" href="search.html" />
|
||||||
<link rel="next" title="Examples" href="examples.html" />
|
<link rel="next" title="Code Examples" href="examples.html" />
|
||||||
<link rel="prev" title="Understanding Reticulum" href="understanding.html" />
|
<link rel="prev" title="Understanding Reticulum" href="understanding.html" />
|
||||||
</head><body>
|
</head><body>
|
||||||
<div class="related" role="navigation" aria-label="related navigation">
|
<div class="related" role="navigation" aria-label="related navigation">
|
||||||
@@ -26,12 +26,12 @@
|
|||||||
<a href="genindex.html" title="General Index"
|
<a href="genindex.html" title="General Index"
|
||||||
accesskey="I">index</a></li>
|
accesskey="I">index</a></li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="examples.html" title="Examples"
|
<a href="examples.html" title="Code Examples"
|
||||||
accesskey="N">next</a> |</li>
|
accesskey="N">next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="understanding.html" title="Understanding Reticulum"
|
<a href="understanding.html" title="Understanding Reticulum"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">API Reference</a></li>
|
<li class="nav-item nav-item-this"><a href="">API Reference</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -1204,7 +1204,7 @@ will announce it.</p>
|
|||||||
title="previous chapter">Understanding Reticulum</a></p>
|
title="previous chapter">Understanding Reticulum</a></p>
|
||||||
<h4>Next topic</h4>
|
<h4>Next topic</h4>
|
||||||
<p class="topless"><a href="examples.html"
|
<p class="topless"><a href="examples.html"
|
||||||
title="next chapter">Examples</a></p>
|
title="next chapter">Code Examples</a></p>
|
||||||
<div role="note" aria-label="source link">
|
<div role="note" aria-label="source link">
|
||||||
<h3>This Page</h3>
|
<h3>This Page</h3>
|
||||||
<ul class="this-page-menu">
|
<ul class="this-page-menu">
|
||||||
@@ -1233,12 +1233,12 @@ will announce it.</p>
|
|||||||
<a href="genindex.html" title="General Index"
|
<a href="genindex.html" title="General Index"
|
||||||
>index</a></li>
|
>index</a></li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="examples.html" title="Examples"
|
<a href="examples.html" title="Code Examples"
|
||||||
>next</a> |</li>
|
>next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="understanding.html" title="Understanding Reticulum"
|
<a href="understanding.html" title="Understanding Reticulum"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">API Reference</a></li>
|
<li class="nav-item nav-item-this"><a href="">API Reference</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Search — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>Search — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||||
|
|
||||||
@@ -29,7 +29,7 @@
|
|||||||
<li class="right" style="margin-right: 10px">
|
<li class="right" style="margin-right: 10px">
|
||||||
<a href="genindex.html" title="General Index"
|
<a href="genindex.html" title="General Index"
|
||||||
accesskey="I">index</a></li>
|
accesskey="I">index</a></li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Search</a></li>
|
<li class="nav-item nav-item-this"><a href="">Search</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -85,7 +85,7 @@
|
|||||||
<li class="right" style="margin-right: 10px">
|
<li class="right" style="margin-right: 10px">
|
||||||
<a href="genindex.html" title="General Index"
|
<a href="genindex.html" title="General Index"
|
||||||
>index</a></li>
|
>index</a></li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Search</a></li>
|
<li class="nav-item nav-item-this"><a href="">Search</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Understanding Reticulum — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>Understanding Reticulum — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.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="index" title="Index" href="genindex.html" />
|
||||||
<link rel="search" title="Search" href="search.html" />
|
<link rel="search" title="Search" href="search.html" />
|
||||||
<link rel="next" title="API Reference" href="reference.html" />
|
<link rel="next" title="API Reference" href="reference.html" />
|
||||||
<link rel="prev" title="Building Networks" href="networks.html" />
|
<link rel="prev" title="Supported Interfaces" href="interfaces.html" />
|
||||||
</head><body>
|
</head><body>
|
||||||
<div class="related" role="navigation" aria-label="related navigation">
|
<div class="related" role="navigation" aria-label="related navigation">
|
||||||
<h3>Navigation</h3>
|
<h3>Navigation</h3>
|
||||||
@@ -29,9 +29,9 @@
|
|||||||
<a href="reference.html" title="API Reference"
|
<a href="reference.html" title="API Reference"
|
||||||
accesskey="N">next</a> |</li>
|
accesskey="N">next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="networks.html" title="Building Networks"
|
<a href="interfaces.html" title="Supported Interfaces"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
|
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -815,8 +815,8 @@ proof 11
|
|||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<h4>Previous topic</h4>
|
<h4>Previous topic</h4>
|
||||||
<p class="topless"><a href="networks.html"
|
<p class="topless"><a href="interfaces.html"
|
||||||
title="previous chapter">Building Networks</a></p>
|
title="previous chapter">Supported Interfaces</a></p>
|
||||||
<h4>Next topic</h4>
|
<h4>Next topic</h4>
|
||||||
<p class="topless"><a href="reference.html"
|
<p class="topless"><a href="reference.html"
|
||||||
title="next chapter">API Reference</a></p>
|
title="next chapter">API Reference</a></p>
|
||||||
@@ -851,9 +851,9 @@ proof 11
|
|||||||
<a href="reference.html" title="API Reference"
|
<a href="reference.html" title="API Reference"
|
||||||
>next</a> |</li>
|
>next</a> |</li>
|
||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="networks.html" title="Building Networks"
|
<a href="interfaces.html" title="Supported Interfaces"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
|
<li class="nav-item nav-item-this"><a href="">Understanding Reticulum</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>Using Reticulum on Your System — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>Using Reticulum on Your System — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="gettingstartedfast.html" title="Getting Started Fast"
|
<a href="gettingstartedfast.html" title="Getting Started Fast"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Using Reticulum on Your System</a></li>
|
<li class="nav-item nav-item-this"><a href="">Using Reticulum on Your System</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -246,7 +246,7 @@ optional arguments:
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="gettingstartedfast.html" title="Getting Started Fast"
|
<a href="gettingstartedfast.html" title="Getting Started Fast"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">Using Reticulum on Your System</a></li>
|
<li class="nav-item nav-item-this"><a href="">Using Reticulum on Your System</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
<title>What is Reticulum? — Reticulum Network Stack 0.2.6 beta documentation</title>
|
<title>What is Reticulum? — Reticulum Network Stack 0.2.8 beta documentation</title>
|
||||||
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
<link rel="stylesheet" type="text/css" href="_static/pygments.css" />
|
||||||
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
<link rel="stylesheet" type="text/css" href="_static/classic.css" />
|
||||||
|
|
||||||
@@ -31,7 +31,7 @@
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="index.html" title="Reticulum Network Stack Manual"
|
<a href="index.html" title="Reticulum Network Stack Manual"
|
||||||
accesskey="P">previous</a> |</li>
|
accesskey="P">previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
|
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,6 +60,7 @@
|
|||||||
<ul class="simple">
|
<ul class="simple">
|
||||||
<li><p>Coordination-less globally unique adressing and identification</p></li>
|
<li><p>Coordination-less globally unique adressing and identification</p></li>
|
||||||
<li><p>Fully self-configuring multi-hop routing</p></li>
|
<li><p>Fully self-configuring multi-hop routing</p></li>
|
||||||
|
<li><p>Complete initiator anonymity, communicate without revealing your identity</p></li>
|
||||||
<li><p>Asymmetric X25519 encryption and Ed25519 signatures as a basis for all communication</p></li>
|
<li><p>Asymmetric X25519 encryption and Ed25519 signatures as a basis for all communication</p></li>
|
||||||
<li><p>Forward Secrecy with ephemereal Elliptic Curve Diffie-Hellman keys on Curve25519</p></li>
|
<li><p>Forward Secrecy with ephemereal Elliptic Curve Diffie-Hellman keys on Curve25519</p></li>
|
||||||
<li><p>Reticulum uses the <a class="reference external" href="https://github.com/fernet/spec/blob/master/Spec.md">Fernet</a> specification for on-the-wire / over-the-air encryption</p>
|
<li><p>Reticulum uses the <a class="reference external" href="https://github.com/fernet/spec/blob/master/Spec.md">Fernet</a> specification for on-the-wire / over-the-air encryption</p>
|
||||||
@@ -91,7 +92,7 @@
|
|||||||
<div class="section" id="where-can-reticulum-be-used">
|
<div class="section" id="where-can-reticulum-be-used">
|
||||||
<h2>Where can Reticulum be Used?<a class="headerlink" href="#where-can-reticulum-be-used" title="Permalink to this headline">¶</a></h2>
|
<h2>Where can Reticulum be Used?<a class="headerlink" href="#where-can-reticulum-be-used" title="Permalink to this headline">¶</a></h2>
|
||||||
<p>Over practically any medium that can support at least a half-duplex channel
|
<p>Over practically any medium that can support at least a half-duplex channel
|
||||||
with 1.000 bits per second throughput, and an MTU of 500 bytes. Data radios,
|
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,
|
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
|
ad-hoc WiFi, free-space optical links and similar systems are all examples
|
||||||
of the types of interfaces Reticulum was designed for.</p>
|
of the types of interfaces Reticulum was designed for.</p>
|
||||||
@@ -183,7 +184,7 @@ network, and vice versa.</p>
|
|||||||
<li class="right" >
|
<li class="right" >
|
||||||
<a href="index.html" title="Reticulum Network Stack Manual"
|
<a href="index.html" title="Reticulum Network Stack Manual"
|
||||||
>previous</a> |</li>
|
>previous</a> |</li>
|
||||||
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.6 beta documentation</a> »</li>
|
<li class="nav-item nav-item-0"><a href="index.html">Reticulum Network Stack 0.2.8 beta documentation</a> »</li>
|
||||||
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
|
<li class="nav-item nav-item-this"><a href="">What is Reticulum?</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ copyright = '2021, Mark Qvist'
|
|||||||
author = 'Mark Qvist'
|
author = 'Mark Qvist'
|
||||||
|
|
||||||
# The full version, including alpha/beta/rc tags
|
# The full version, including alpha/beta/rc tags
|
||||||
release = '0.2.6 beta'
|
release = '0.2.8 beta'
|
||||||
|
|
||||||
|
|
||||||
# -- General configuration ---------------------------------------------------
|
# -- General configuration ---------------------------------------------------
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ Try Using a Reticulum-based Program
|
|||||||
=============================================
|
=============================================
|
||||||
If you simply want to try using a program built with Reticulum, you can take
|
If you simply want to try using a program built with Reticulum, you can take
|
||||||
a look at `Nomad Network <https://github.com/markqvist/nomadnet>`_, which
|
a look at `Nomad Network <https://github.com/markqvist/nomadnet>`_, which
|
||||||
provides a basic encrypted communications suite built completely on Reticulum.
|
provides a complete encrypted communications suite built with Reticulum.
|
||||||
|
|
||||||
.. image:: screenshots/nomadnet_3.png
|
.. image:: screenshots/nomadnet_3.png
|
||||||
:target: _images/nomadnet_3.png
|
:target: _images/nomadnet_3.png
|
||||||
@@ -31,9 +31,21 @@ You can install Nomad Network via pip:
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Using the Included Utilities
|
||||||
|
=============================================
|
||||||
|
Reticulum comes with a range of included utilities that make it easier to
|
||||||
|
manage your network, check connectivity and make Reticulum available to other
|
||||||
|
programs on your system.
|
||||||
|
|
||||||
|
You can use ``rnsd`` to run Reticulum as a background or foreground service,
|
||||||
|
and the ``rnstatus``, ``rnpath`` and ``rnprobe`` utilities to view and query
|
||||||
|
network status and connectivity.
|
||||||
|
|
||||||
|
To learn more about these utility programs, have a look at the
|
||||||
|
:ref:`Using Reticulum on Your System<using-main>` chapter of this manual.
|
||||||
|
|
||||||
Creating a Network With Reticulum
|
Creating a Network With Reticulum
|
||||||
=============================================
|
=============================================
|
||||||
|
|
||||||
To create a network, you will need to specify one or more *interfaces* for
|
To create a network, you will need to specify one or more *interfaces* for
|
||||||
Reticulum to use. This is done in the Reticulum configuration file, which by
|
Reticulum to use. This is done in the Reticulum configuration file, which by
|
||||||
default is located at ``~/.reticulum/config``.
|
default is located at ``~/.reticulum/config``.
|
||||||
|
|||||||
@@ -14,6 +14,10 @@ for Reticulum to use.
|
|||||||
The following sections describe the interfaces currently available in Reticulum,
|
The following sections describe the interfaces currently available in Reticulum,
|
||||||
and gives example configurations for the respective interface types.
|
and gives example configurations for the respective interface types.
|
||||||
|
|
||||||
|
For a high-level overview of how networks can be formed over different interface
|
||||||
|
types, have a look at the :ref:`Building Networks<networks-main>` chapter of this
|
||||||
|
manual.
|
||||||
|
|
||||||
.. _interfaces-udp:
|
.. _interfaces-udp:
|
||||||
|
|
||||||
UDP Interface
|
UDP Interface
|
||||||
|
|||||||
@@ -63,7 +63,8 @@ the underlying carrier for Reticulum.
|
|||||||
However, most real-world networks will probably involve either some form of
|
However, most real-world networks will probably involve either some form of
|
||||||
wireless or direct hardline communications. To allow Reticulum to communicate
|
wireless or direct hardline communications. To allow Reticulum to communicate
|
||||||
over any type of medium, you must specify it in the configuration file, by default
|
over any type of medium, you must specify it in the configuration file, by default
|
||||||
located at ``~/.reticulum/config``.
|
located at ``~/.reticulum/config``. See the :ref:`Supported Interfaces<interfaces-main>`
|
||||||
|
chapter of this manual for interface configuration examples.
|
||||||
|
|
||||||
Any number of interfaces can be configured, and Reticulum will automatically
|
Any number of interfaces can be configured, and Reticulum will automatically
|
||||||
decide which are suitable to use in any given situation, depending on where
|
decide which are suitable to use in any given situation, depending on where
|
||||||
|
|||||||
@@ -27,6 +27,8 @@ What does Reticulum Offer?
|
|||||||
|
|
||||||
* Fully self-configuring multi-hop routing
|
* 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
|
* 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 ephemereal Elliptic Curve Diffie-Hellman keys on Curve25519
|
||||||
@@ -65,7 +67,7 @@ What does Reticulum Offer?
|
|||||||
Where can Reticulum be Used?
|
Where can Reticulum be Used?
|
||||||
============================
|
============================
|
||||||
Over practically any medium that can support at least a half-duplex channel
|
Over practically any medium that can support at least a half-duplex channel
|
||||||
with 1.000 bits per second throughput, and an MTU of 500 bytes. Data radios,
|
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,
|
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
|
ad-hoc WiFi, free-space optical links and similar systems are all examples
|
||||||
of the types of interfaces Reticulum was designed for.
|
of the types of interfaces Reticulum was designed for.
|
||||||
|
|||||||
Reference in New Issue
Block a user