diff --git a/docs/clean_md.py b/docs/clean_md.py index fd5656dd..e4e503ff 100755 --- a/docs/clean_md.py +++ b/docs/clean_md.py @@ -37,6 +37,10 @@ def should_remove_line(line, start_patterns, any_patterns): def clean_markdown_content(content, start_patterns, any_patterns, api_ref=False): + content = content.replace("**\n : ", "**\n ") + content = content.replace("\n* **", "\n\n* **") + content = content.replace("\n\n\n", "\n\n") + lines = content.split('\n') result = [] skip_next_empty = False @@ -59,8 +63,6 @@ def clean_markdown_content(content, start_patterns, any_patterns, api_ref=False) line = f"{line}`" line = line.replace("
", "") - line = line.replace("\n* **", "\n\n* **") - line = line.replace("**\n : ", "**\n ") result.append(line) diff --git a/docs/markdown/distributed.md b/docs/markdown/distributed.md index c49e1b2b..a06b45c6 100644 --- a/docs/markdown/distributed.md +++ b/docs/markdown/distributed.md @@ -83,10 +83,15 @@ The `rngit` system is not a monolithic application prescribing a specific workfl The core primitives include: * **Repository Hosting**: Bare Git repositories served over Reticulum links, accessible via standard Git commands through the `rns://` URL scheme. + * **Identity-Based Access Control**: Fine-grained permissions managed through cryptographically verifiable identity hashes, configurable at the group, repository, or document level. + * **Release Distribution**: Cryptographically signed release artifacts with embedded provenance information, verifiable offline and distributable through any Reticulum or physical path. + * **Work Document Tracking**: Structured, threaded work management attached to repositories, with precise permission controls, and the ability to contain updates or discussions. + * **Forking and Mirroring**: Automated replication of repositories from any accessible Git URL, with metadata tracking upstream relationships for synchronization. + * **Nomad Network Integration**: Page node functionality for browsing repository contents, commit history, and release information through the Nomad Network protocol. These primitives can be composed into workflows ranging from single-developer projects to complex multi-organizational collaborations. A solo developer might use only repository hosting and release distribution. A research group might add work document tracking for structured peer review. A software distribution network might combine mirroring with cryptographic release verification to create resilient update channels. diff --git a/docs/markdown/examples.md b/docs/markdown/examples.md index 559e76af..2d8ab715 100644 --- a/docs/markdown/examples.md +++ b/docs/markdown/examples.md @@ -61,7 +61,6 @@ def program_setup(configpath): # Let's hand over control to the announce loop announceLoop(destination) - def announceLoop(destination): # Let the user know that everything is ready RNS.log( @@ -79,7 +78,6 @@ def announceLoop(destination): destination.announce() RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash)) - ########################################################## #### Program Startup ##################################### ########################################################## @@ -202,7 +200,6 @@ def program_setup(configpath): # Let's hand over control to the announce loop announceLoop(destination_1, destination_2) - def announceLoop(destination_1, destination_2): # Let the user know that everything is ready RNS.log("Announce example running, hit enter to manually send an announce (Ctrl-C to quit)") @@ -380,7 +377,6 @@ def broadcastLoop(destination): packet.send() - ########################################################## #### Program Startup ##################################### ########################################################## @@ -454,7 +450,6 @@ import RNS # them all within the app namespace "example_utilities" APP_NAME = "example_utilities" - ########################################################## #### Server Part ######################################### ########################################################## @@ -500,7 +495,6 @@ def server(configpath): # Let's Wait for client requests or user input announceLoop(echo_destination) - def announceLoop(destination): # Let the user know that everything is ready RNS.log( @@ -518,7 +512,6 @@ def announceLoop(destination): destination.announce() RNS.log("Sent announce from "+RNS.prettyhexrep(destination.hash)) - def server_callback(message, packet): global reticulum @@ -547,7 +540,6 @@ def server_callback(message, packet): RNS.log("Received packet from echo client, proof sent"+reception_stats) - ########################################################## #### Client Part ######################################### ########################################################## @@ -698,7 +690,6 @@ def packet_timed_out(receipt): if receipt.status == RNS.PacketReceipt.FAILED: RNS.log("Packet "+RNS.prettyhexrep(receipt.hash)+" timed out") - ########################################################## #### Program Startup ##################################### ########################################################## @@ -877,7 +868,6 @@ def server_packet_received(message, packet): reply_data = reply_text.encode("utf-8") RNS.Packet(latest_client_link, reply_data).send() - ########################################################## #### Client Part ######################################### ########################################################## @@ -1014,7 +1004,6 @@ def client_packet_received(message, packet): print("> ", end=" ") sys.stdout.flush() - ########################################################## #### Program Startup ##################################### ########################################################## @@ -1187,7 +1176,6 @@ def server_packet_received(message, packet): reply_data = reply_text.encode("utf-8") RNS.Packet(latest_client_link, reply_data).send() - ########################################################## #### Client Part ######################################### ########################################################## @@ -1337,7 +1325,6 @@ def client_packet_received(message, packet): print("> ", end=" ") sys.stdout.flush() - ########################################################## #### Program Startup ##################################### ########################################################## @@ -1499,7 +1486,6 @@ def client_connected(link): def client_disconnected(link): RNS.log("Client disconnected") - ########################################################## #### Client Part ######################################### ########################################################## @@ -1588,7 +1574,6 @@ def client_loop(): failed_callback = request_failed ) - except Exception as e: RNS.log("Error while sending request over the link: "+str(e)) should_quit = True @@ -1606,7 +1591,6 @@ def request_received(request_receipt): def request_failed(request_receipt): RNS.log("The request "+RNS.prettyhexrep(request_receipt.request_id)+" failed.") - # This function is called when a link # has been established with the server def link_established(link): @@ -1632,7 +1616,6 @@ def link_closed(link): time.sleep(1.5) sys.exit(0) - ########################################################## #### Program Startup ##################################### ########################################################## @@ -1784,7 +1767,6 @@ class StringMessage(RNS.MessageBase): def unpack(self, raw): self.data, self.timestamp = umsgpack.unpackb(raw) - ########################################################## #### Server Part ######################################### ########################################################## @@ -1888,7 +1870,6 @@ def server_message_received(message): # handlers are skipped. return True - ########################################################## #### Client Part ######################################### ########################################################## @@ -2031,7 +2012,6 @@ def client_message_received(message): print("> ", end=" ") sys.stdout.flush() - ########################################################## #### Program Startup ##################################### ########################################################## @@ -2117,7 +2097,6 @@ from RNS.vendor import umsgpack # them all within the app namespace "example_utilities" APP_NAME = "example_utilities" - ########################################################## #### Server Part ######################################### ########################################################## @@ -2190,7 +2169,6 @@ def client_connected(link): if latest_buffer: latest_buffer.close() - # Create buffer objects. # The stream_id parameter to these functions is # a bit like a file descriptor, except that it @@ -2227,7 +2205,6 @@ def server_buffer_ready(ready_bytes: int): - ########################################################## #### Client Part ######################################### ########################################################## @@ -2319,7 +2296,6 @@ def client_loop(): # Flush the buffer to force the data to be sent. buffer.flush() - except Exception as e: RNS.log("Error while sending data over the link buffer: "+str(e)) should_quit = True @@ -2363,7 +2339,6 @@ def client_buffer_ready(ready_bytes: int): print("> ", end=" ") sys.stdout.flush() - ########################################################## #### Program Startup ##################################### ########################################################## @@ -2639,7 +2614,6 @@ download_time = 0 transfer_size = 0 file_size = 0 - # This initialisation is executed when the users chooses # to run as a client def client(destination_hexhash, configpath): @@ -2660,7 +2634,6 @@ def client(destination_hexhash, configpath): # We must first initialise Reticulum reticulum = RNS.Reticulum(configpath) - # Check if we know a path to the destination if not RNS.Transport.has_path(destination_hash): RNS.log("Destination is not yet known. Requesting path and waiting for announce to arrive...") @@ -2895,7 +2868,6 @@ def filelist_timeout_job(): RNS.log("Timed out waiting for filelist, exiting") sys.exit(0) - # When a link is closed, we'll inform the # user, and exit the program def link_closed(link): @@ -3226,7 +3198,6 @@ class ExampleInterface(Interface): self.online = True RNS.log("Serial port "+self.port+" is now open", RNS.LOG_VERBOSE) - # This method will be called from our read-loop # whenever a full packet has been received over # the underlying medium. diff --git a/docs/markdown/gettingstartedfast.md b/docs/markdown/gettingstartedfast.md index af386919..366515a1 100644 --- a/docs/markdown/gettingstartedfast.md +++ b/docs/markdown/gettingstartedfast.md @@ -161,7 +161,9 @@ We strongly encourage everyone, even home users, to think in terms of building * There is no requirement to commit to a single strategy. The most robust setups often mix static, dynamic, and discovered interfaces. * **Static Interfaces:** You maintain a permanent interface to a trusted friend or organization using a static configuration. + * **Bootstrap Links:** You connect a `bootstrap_only` interface to a public gateway on the Internet to scan for new connectable peers or to regain connectivity if your other interfaces fail. + * **Local Wide-Area Connectivity:** You run a `RNodeInterface` on a shared frequency, giving you completely self-sovereign and private wide-area access to both your own network and other Reticulum peers globally, without any “service providers” being able to control or monitor how you interact with people. By combining these methods, you create a system that is secure against single points of failure, adaptable to changing network conditions, and better integrated into your physical and social reality. diff --git a/docs/markdown/networks.md b/docs/markdown/networks.md index 147b2e33..2d2da75a 100644 --- a/docs/markdown/networks.md +++ b/docs/markdown/networks.md @@ -142,16 +142,19 @@ This has profound implications for network design: * **No address allocation planning:** You never need to reserve address ranges, plan subnets, or coordinate with other network operators. Nodes simply generate destinations and announce them. + * **Global portability:** A destination is not tied to a physical location or network segment. A node can move its destinations across interfaces, mediums, or even between entirely separate Reticulum networks simply by sending an announce on the new medium. + * **Implicit authentication:** Because destinations are bound to public keys, communication to a destination is inherently cryptographically authenticated. Only the holder of the corresponding private key can decrypt and respond to traffic addressed to that destination. This also makes application-level authentication *much* simpler, since it can directly use the foundational identity verification built into the core networking layer. + * **Identity abstraction:** A single Reticulum Identity can create multiple destinations. This allows a single entity (a person, a device, a service) to present multiple endpoints without needing multiple cryptographic keypairs. @@ -191,9 +194,11 @@ The distinction is important. **Not** every node should be a Transport Node: * **Resource consumption:** Transport nodes maintain path tables, process announces, and forward traffic. This requires memory and CPU resources that may be limited on low-powered devices. + * **Stability requirements:** Transport nodes contribute to network convergence. If Transport Nodes frequently go offline, path tables become stale and convergence suffers. Stable, always-on nodes make better Transport Nodes. + * **Bandwidth considerations:** Transport nodes process and rebroadcast network maintenance traffic. On very low-bandwidth mediums, having too many Transport Nodes will consume capacity that should be used for actual data. @@ -228,15 +233,19 @@ of communication is secured cryptographically: * **Traffic encryption:** All traffic to single destinations is encrypted using ephemeral keys. + * **Source anonymity:** Reticulum packets do not include source addresses. An observer intercepting a packet cannot determine who sent it, only who it is addressed to (unless IFAC is enabled, in which case nothing can be determined). This provides initiator anonymity by default. + * **Path verification:** The announce mechanism includes cryptographic signatures that prove the authenticity of destination announcements. + * **Unforgeable delivery confirmations:** When a destination proves receipt of a packet, the proof is signed with the destination’s identity key. This prevents false acknowledgments and ensures reliable delivery verification. + * **Interface authentication:** When using Interface Access Codes (IFAC), packets on authenticated interfaces carry signatures derived from a shared secret. Only nodes with the correct network name and passphrase can generate valid packets, allowing creation @@ -248,10 +257,12 @@ The trustless design has important consequences for network design: join without pre-approval. Because traffic is encrypted and authenticated end- to-end, participants cannot interfere with each other’s private communication, even if they share the same transport infrastructure. + * **No traffic inspection or prioritization:** Because traffic contents and sources are opaque to intermediate nodes, there is no mechanism for filtering, prioritizing, or throttling traffic based on its type or origin. All traffic is treated equally. From a neutrality perspective, this is a feature. + * **Adversarial resilience:** The network can operate even if some nodes are malicious or controlled by adversaries. While a malicious Transport Node could refuse to forward certain traffic or drop packets, it cannot decrypt, modify, @@ -280,12 +291,15 @@ to seamlessly mix mediums with vastly different characteristics: interconnect with gigabit Ethernet backbones. Reticulum automatically manages the flow of information, prioritizing local traffic on slow segments while allowing global convergence. + * **Latency:** Satellite links with multi-second latency can coexist with local links measured in milliseconds. The transport system handles timing, asynchronous delivery and retransmissions transparently. + * **Topology:** Point-to-point microwave links, broadcast radio networks, switched Ethernet fabrics, and virtual tunnels over the Internet can all be part of the same Reticulum network. + * **Reliability:** Intermittent connections that come and go (such as mobile devices or opportunistic radio contacts) can participate alongside always-on infrastructure. Reticulum gracefully handles link loss and reconnection. @@ -295,12 +309,15 @@ This heterogeneity is achieved through several design elements: * **Expandable, medium-agnostic interface system:** Reticulum communicates with the physical world through interface modules. Adding support for a new medium is a matter of implementing an interface class. The protocol itself remains unchanged. + * **Interface modes:** Different modes (`full`, `gateway`, `access_point`, `roaming`, `boundary`) allow you to configure how interfaces interact with the wider network based on their characteristics and role. + * **Announce propagation rules:** Announces are forwarded between interfaces according to rules that account for bandwidth limitations and interface modes. Slow segments are not overwhelmed by traffic from fast segments. + * **Local traffic prioritization:** When bandwidth is constrained, Reticulum prioritizes announces for nearby destinations. This ensures that local connectivity remains functional even when global convergence is incomplete. diff --git a/docs/markdown/reference.md b/docs/markdown/reference.md index 0398cfd2..4615e086 100644 --- a/docs/markdown/reference.md +++ b/docs/markdown/reference.md @@ -198,6 +198,7 @@ search for an identity from a known *identity hash*, by setting the * **Parameters:** * **target_hash** – Destination or identity hash as *bytes*. * **from_identity_hash** – Whether to search based on identity hash instead of destination hash as *bool*. + * **Returns:** An [RNS.Identity](#api-identity) instance that can be used to create an outgoing [RNS.Destination](#api-destination), or *None* if the destination is unknown. @@ -207,6 +208,7 @@ Recall last heard app_data for a destination hash. * **Parameters:** **destination_hash** – Destination hash as *bytes*. + * **Returns:** *Bytes* containing app_data, or *None* if the destination is unknown. @@ -216,6 +218,7 @@ Get a SHA-256 hash of passed data. * **Parameters:** **data** – Data to be hashed as *bytes*. + * **Returns:** SHA-256 hash as *bytes*. @@ -225,6 +228,7 @@ Get a truncated SHA-256 hash of passed data. * **Parameters:** **data** – Data to be hashed as *bytes*. + * **Returns:** Truncated SHA-256 hash as *bytes*. @@ -234,6 +238,7 @@ Get a random SHA-256 hash. * **Parameters:** **data** – Data to be hashed as *bytes*. + * **Returns:** Truncated SHA-256 hash of random data as *bytes*. @@ -243,6 +248,7 @@ Get the ID of the currently used ratchet key for a given destination hash * **Parameters:** **destination_hash** – A destination hash as *bytes*. + * **Returns:** A ratchet ID as *bytes* or *None*. @@ -253,6 +259,7 @@ Can be used to load previously created and saved identities into Reticulum. * **Parameters:** **prv_bytes** – The *bytes* of private a saved private key. **HAZARD!** Never use this to generate a new key by feeding random data in prv_bytes. + * **Returns:** A [RNS.Identity](#api-identity) instance, or *None* if the *bytes* data was invalid. @@ -263,6 +270,7 @@ Can be used to load previously created and saved identities into Reticulum. * **Parameters:** **path** – The full path to the saved [RNS.Identity](#api-identity) data + * **Returns:** A [RNS.Identity](#api-identity) instance, or *None* if the loaded data was invalid. @@ -274,6 +282,7 @@ communication for the identity. Be very careful with this method. * **Parameters:** **path** – The full path specifying where to save the identity. + * **Returns:** True if the file was saved, otherwise False. @@ -283,6 +292,7 @@ Saves the public identity to a file. * **Parameters:** **path** – The full path specifying where to save the identity. + * **Returns:** True if the file was saved, otherwise False. @@ -302,6 +312,7 @@ Load a private key into the instance. * **Parameters:** **prv_bytes** – The private key as *bytes*. + * **Returns:** True if the key was loaded, otherwise False. @@ -311,6 +322,7 @@ Load a public key into the instance. * **Parameters:** **pub_bytes** – The public key as *bytes*. + * **Returns:** True if the key was loaded, otherwise False. @@ -320,8 +332,10 @@ Encrypts information for the identity. * **Parameters:** **plaintext** – The plaintext to be encrypted as *bytes*. + * **Returns:** Ciphertext token as *bytes*. + * **Raises:** *KeyError* if the instance does not hold a public key. @@ -331,8 +345,10 @@ Decrypts information for the identity. * **Parameters:** **ciphertext** – The ciphertext to be decrypted as *bytes*. + * **Returns:** Plaintext as *bytes*, or *None* if decryption fails. + * **Raises:** *KeyError* if the instance does not hold a private key. @@ -342,8 +358,10 @@ Signs information by the identity. * **Parameters:** **message** – The message to be signed as *bytes*. + * **Returns:** Signature as *bytes*. + * **Raises:** *KeyError* if the instance does not hold a private key. @@ -354,8 +372,10 @@ Validates the signature of a signed message. * **Parameters:** * **signature** – The signature to be validated as *bytes*. * **message** – The message to be validated as *bytes*. + * **Returns:** True if the signature is valid, otherwise False. + * **Raises:** *KeyError* if the instance does not hold a public key. @@ -418,6 +438,7 @@ Set or query whether the destination accepts incoming link requests. * **Parameters:** **accepts** – If `True` or `False`, this method sets whether the destination accepts incoming link requests. If not provided or `None`, the method returns whether the destination currently accepts link requests. + * **Returns:** `True` or `False` depending on whether the destination accepts incoming link requests, if the *accepts* parameter is not provided or `None`. @@ -463,6 +484,7 @@ Registers a request handler. * **allow** – One of `RNS.Destination.ALLOW_NONE`, `RNS.Destination.ALLOW_ALL` or `RNS.Destination.ALLOW_LIST`. If `RNS.Destination.ALLOW_LIST` is set, the request handler will only respond to requests for identified peers in the supplied list. * **allowed_list** – A list of *bytes-like* [RNS.Identity](#api-identity) hashes. * **auto_compress** – If `True` or `False`, determines whether automatic compression of responses should be carried out. If set to an integer value, responses will only be auto-compressed if under this size in bytes. If omitted, the default compression settings will be followed. + * **Raises:** `ValueError` if any of the supplied arguments are invalid. @@ -472,6 +494,7 @@ Deregisters a request handler. * **Parameters:** **path** – The path for the request handler to be deregistered. + * **Returns:** True if the handler was deregistered, otherwise False. @@ -489,6 +512,7 @@ Enabling ratchets will have a small impact on announce size, adding 32 bytes to * **Parameters:** **ratchets_path** – The path to a file to store ratchet data in. + * **Returns:** True if the operation succeeded, otherwise False. @@ -505,6 +529,7 @@ and try to use when decrypting incoming packets. Defaults to `Destination.RATCHE * **Parameters:** **retained_ratchets** – The number of generated ratchets to retain. + * **Returns:** True if the operation succeeded, False if not. @@ -515,6 +540,7 @@ Defaults to `Destination.RATCHET_INTERVAL`. * **Parameters:** **interval** – The minimum interval in seconds. + * **Returns:** True if the operation succeeded, False if not. @@ -538,6 +564,7 @@ For a `RNS.Destination.GROUP` type destination, loads a symmetric private key. * **Parameters:** **key** – A *bytes-like* containing the symmetric key. + * **Raises:** `TypeError` if called on an incompatible type of destination. @@ -547,6 +574,7 @@ Encrypts information for `RNS.Destination.SINGLE` or `RNS.Destination.GROUP` typ * **Parameters:** **plaintext** – A *bytes-like* containing the plaintext to be encrypted. + * **Raises:** `ValueError` if destination does not hold a necessary key for encryption. @@ -556,6 +584,7 @@ Decrypts information for `RNS.Destination.SINGLE` or `RNS.Destination.GROUP` typ * **Parameters:** **ciphertext** – *Bytes* containing the ciphertext to be decrypted. + * **Raises:** `ValueError` if destination does not hold a necessary key for decryption. @@ -565,6 +594,7 @@ Signs information for `RNS.Destination.SINGLE` type destination. * **Parameters:** **message** – *Bytes* containing the message to be signed. + * **Returns:** A *bytes-like* containing the message signature, or *None* if the destination could not sign the message. @@ -737,6 +767,7 @@ Sends a request to the remote peer. * **failed_callback** – An optional function or method with the signature *failed_callback(request_receipt)* to be called when a request fails. See the [Request Example](examples.md#example-request) for more info. * **progress_callback** – An optional function or method with the signature *progress_callback(request_receipt)* to be called when progress is made receiving the response. Progress can be accessed as a float between 0.0 and 1.0 by the *request_receipt.progress* property. * **timeout** – An optional timeout in seconds for the request. If *None* is supplied it will be calculated based on link RTT. + * **Returns:** A [RNS.RequestReceipt](#api-requestreceipt) instance if the request was sent, or *False* if it was not. @@ -888,6 +919,7 @@ Sets the resource strategy for the link. * **Parameters:** **resource_strategy** – One of `RNS.Link.ACCEPT_NONE`, `RNS.Link.ACCEPT_ALL` or `RNS.Link.ACCEPT_APP`. If `RNS.Link.ACCEPT_APP` is set, the resource_callback will be called to determine whether the resource should be accepted or not. + * **Raises:** *TypeError* if the resource strategy is unsupported. @@ -1121,6 +1153,7 @@ of this object, see the Python documentation for * **stream_id** – the local stream id to receive from * **channel** – the channel to receive on * **ready_callback** – function to call when new data is available + * **Returns:** a BufferedReader object @@ -1136,6 +1169,7 @@ of this object, see the Python documentation for * **Parameters:** * **stream_id** – the remote stream id to send to * **channel** – the channel to send on + * **Returns:** a BufferedWriter object @@ -1156,6 +1190,7 @@ of this object, see the Python documentation for * **send_stream_id** – the remote stream id to send to * **channel** – the channel to send and receive on * **ready_callback** – function to call when new data is available + * **Returns:** a BufferedRWPair object @@ -1251,6 +1286,7 @@ Deregisters an announce handler. * **Parameters:** **destination_hash** – A destination hash as *bytes*. + * **Returns:** *True* if a path to the destination is known, otherwise *False*. @@ -1258,6 +1294,7 @@ Deregisters an announce handler. * **Parameters:** **destination_hash** – A destination hash as *bytes*. + * **Returns:** The number of hops to the specified destination, or `RNS.Transport.PATHFINDER_M` if the number of hops is unknown. @@ -1265,6 +1302,7 @@ Deregisters an announce handler. * **Parameters:** **destination_hash** – A destination hash as *bytes*. + * **Returns:** The destination hash as *bytes* for the next hop to the specified destination, or *None* if the next hop is unknown. @@ -1272,6 +1310,7 @@ Deregisters an announce handler. * **Parameters:** **destination_hash** – A destination hash as *bytes*. + * **Returns:** The interface for the next hop to the specified destination, or *None* if the interface is unknown. @@ -1284,6 +1323,7 @@ blocks until the path is available, or the timeout is reached. * **destination_hash** – A destination hash as *bytes*. * **timeout** – An optional timeout in seconds. * **on_interface** – If specified, the path request will only be sent on this interface. In normal use, Reticulum handles this automatically, and this parameter should not be used. + * **Returns:** *True* if a path to the destination is found, otherwise *False*. @@ -1305,6 +1345,7 @@ Blackholes an identity. * **identity_hash** – The identity hash to blackhole as *bytes*. * **until** – Optional unix timestamp of when the blackhole expires as *float* or *int*. * **reason** – Optional reason for the blackhole as *str*. + * **Returns:** *True* if successful, otherwise *False*. @@ -1314,5 +1355,6 @@ Lifts blackhole for an identity. * **Parameters:** **identity_hash** – The identity hash to blackhole as *bytes*. + * **Returns:** *True* if successful, otherwise *False*. \ No newline at end of file diff --git a/docs/markdown/understanding.md b/docs/markdown/understanding.md index 1bca0822..f98571cf 100644 --- a/docs/markdown/understanding.md +++ b/docs/markdown/understanding.md @@ -25,39 +25,47 @@ The ultimate aim of Reticulum is to allow anyone to be their own network operato To be as widely usable and efficient to deploy as possible, the following goals have been used to guide the design of Reticulum: * **Fully useable as open source software stack** - : Reticulum must be implemented with, and be able to run using only open source software. This is + Reticulum must be implemented with, and be able to run using only open source software. This is critical to ensuring the availability, security and transparency of the system. + * **Hardware layer agnosticism** - : Reticulum must be fully hardware agnostic, and shall be useable over a wide range of + Reticulum must be fully hardware agnostic, and shall be useable over a wide range of physical networking layers, such as data radios, serial lines, modems, handheld transceivers, wired Ethernet, WiFi, or anything else that can carry a digital data stream. Hardware made for dedicated Reticulum use shall be as cheap as possible and use off-the-shelf components, so it can be easily modified and replicated by anyone interested in doing so. + * **Very low bandwidth requirements** - : Reticulum should be able to function reliably over links with a transmission capacity as low + Reticulum should be able to function reliably over links with a transmission capacity as low as *5 bits per second*. + * **Encryption by default** - : Reticulum must use strong encryption by default for all communication. + Reticulum must use strong encryption by default for all communication. + * **Initiator Anonymity** - : It must be possible to communicate over a Reticulum network without revealing any identifying + It must be possible to communicate over a Reticulum network without revealing any identifying information about oneself. + * **Unlicensed use** - : Reticulum shall be functional over physical communication mediums that do not require any + Reticulum shall be functional over physical communication mediums that do not require any form of license to use. Reticulum must be designed in a way, so it is usable over ISM radio frequency bands, and can provide functional long distance links in such conditions, for example by connecting a modem to a PMR or CB radio, or by using LoRa or WiFi modules. + * **Supplied software** - : In addition to the core networking stack and API, that allows a developer to build + In addition to the core networking stack and API, that allows a developer to build applications with Reticulum, a basic set of Reticulum-based communication tools must be implemented and released along with Reticulum itself. These shall serve both as a functional, basic communication suite, and as an example and learning resource to others wishing to build applications with Reticulum. + * **Ease of use** - : The reference implementation of Reticulum is written in Python, to make it easy to use and + The reference implementation of Reticulum is written in Python, to make it easy to use and understand. A programmer with only basic experience should be able to use Reticulum to write networked applications. + * **Low cost** - : It shall be as cheap as possible to deploy a communication system based on Reticulum. This + It shall be as cheap as possible to deploy a communication system based on Reticulum. This should be achieved by using cheap off-the-shelf hardware that potential users might already own. The cost of setting up a functioning node should be less than $100 even if all parts needs to be purchased. @@ -83,26 +91,29 @@ Reticulum can connect to a variety of interfaces such as radio modems, data radi To receive and send data with the Reticulum stack, an application needs to create one or more destinations. Reticulum uses three different basic destination types, and one special: * **Single** - : The *single* destination type is the most common type in Reticulum, and should be used for + The *single* destination type is the most common type in Reticulum, and should be used for most purposes. It is always identified by a unique public key. Any data sent to this destination will be encrypted using ephemeral keys derived from an ECDH key exchange, and will only be readable by the creator of the destination, who holds the corresponding private key. + * **Plain** - : A *plain* destination type is unencrypted, and suited for traffic that should be broadcast to a + A *plain* destination type is unencrypted, and suited for traffic that should be broadcast to a number of users, or should be readable by anyone. Traffic to a *plain* destination is not encrypted. Generally, *plain* destinations can be used for broadcast information intended to be public. Plain destinations are only reachable directly, and packets addressed to plain destinations are never transported over multiple hops in the network. To be transportable over multiple hops in Reticulum, information *must* be encrypted, since Reticulum uses the per-packet encryption to verify routing paths and keep them alive. + * **Group** - : The *group* special destination type, that defines a symmetrically encrypted virtual destination. + The *group* special destination type, that defines a symmetrically encrypted virtual destination. Data sent to this destination will be encrypted with a symmetric key, and will be readable by anyone in possession of the key, but as with the *plain* destination type, packets to this type of destination are not currently transported over multiple hops, although a planned upgrade to Reticulum will allow globally reachable *group* destinations. + * **Link** - : A *link* is a special destination type, that serves as an abstract channel to a *single* + A *link* is a special destination type, that serves as an abstract channel to a *single* destination, directly connected or over multiple hops. The *link* also offers reliability and more efficient encryption, forward secrecy, initiator anonymity, and as such can be useful even when a node is directly reachable. It also offers a more capable API and allows easily carrying @@ -139,12 +150,14 @@ Any destination on a Reticulum network can be addressed and reached simply by kn To recap, the different destination types should be used in the following situations: * **Single** - : When private communication between two endpoints is needed. Supports multiple hops. + When private communication between two endpoints is needed. Supports multiple hops. + * **Group** - : When private communication between two or more endpoints is needed. Supports multiple hops + When private communication between two or more endpoints is needed. Supports multiple hops indirectly, but must first be established through a *single* destination. + * **Plain** - : When plain-text communication is desirable, for example when broadcasting information, or for local discovery purposes. + When plain-text communication is desirable, for example when broadcasting information, or for local discovery purposes. To communicate with a *single* destination, you need to know its public key. Any method for obtaining the public key is valid, but Reticulum includes a simple mechanism for making other nodes aware of your destinations public key, called the *announce*. It is also possible to request an unknown public key from the network, as all transport instances serve as a distributed ledger of public keys. @@ -406,8 +419,11 @@ While the current implementation focuses on interface discovery, the concept of As the ecosystem evolves, Network Identities will facilitate: * **Distributed Name Resolution:** A system where networks can publish name-to-identity mappings, allowing human-readable names to resolve without centralized servers. + * **Service Publishing:** Networks will be able to announce specific capabilities, services, or information endpoints available publicly or to their members. + * **Inter-Network Federation:** Trust relationships between different networks, allowing for seamless but managed flow of traffic and information across distinct administrative boundaries. + * **Distributed Blackhole Management:** A reputation-based system for blackhole list distribution, where trusted Network Identities can sign and publish lists of blackholed identities. This allows communities to collaboratively enforce security standards and filter spam or malicious identities across the parts of the wider mesh that they are responsible for. By adopting the use of Network Identities now, you are preparing your infrastructure to be compatible with this future functionality. @@ -443,26 +459,30 @@ The communication channel must support at least half-duplex operation, and provi That being said, this reference setup has been outlined to provide a common platform for anyone who wants to help in the development of Reticulum, and for everyone who wants to know a recommended setup to get started experimenting. A reference system consists of three parts: * **An Interface Device** - : Which provides access to the physical medium whereupon the communication + Which provides access to the physical medium whereupon the communication takes place, for example a radio with an integrated modem. A setup with a separate modem connected to a radio would also be an interface device. + * **A Host Device** - : Some sort of computing device that can run the necessary software, communicate with the + Some sort of computing device that can run the necessary software, communicate with the interface device, and provide user interaction. + * **A Software Stack** - : The software implementing the Reticulum protocol and applications using it. + The software implementing the Reticulum protocol and applications using it. The reference setup can be considered a relatively stable platform to develop on, and also to start building networks or applications on. While details of the implementation might change at the current stage of development, it is the goal to maintain hardware compatibility for as long as entirely possible, and the current reference setup has been determined to provide a functional platform for many years into the future. The current Reference System Setup is as follows: * **Interface Device** - : A data radio consisting of a LoRa radio module, and a microcontroller with open source + A data radio consisting of a LoRa radio module, and a microcontroller with open source firmware, that can connect to host devices via USB. It operates in either the 430, 868 or 900 MHz frequency bands. More details can be found on the [RNode Page](https://github.com/markqvist/rnode_firmware). + * **Host Device** - : Any computer device running Linux and Python. A Raspberry Pi with a Debian based OS is + Any computer device running Linux and Python. A Raspberry Pi with a Debian based OS is a good place to start, but anything can be used. + * **Software Stack** - : The most recently released Python Implementation of Reticulum, running on a Linux-based + The most recently released Python Implementation of Reticulum, running on a Linux-based operating system. #### NOTE @@ -527,25 +547,21 @@ IFAC Flag open 0 Packet for publically accessible interface authenticated 1 Interface authentication is included in packet - Header Types ----------------- type 1 0 Two byte header, one 16 byte address field type 2 1 Two byte header, two 16 byte address fields - Context Flag ----------------- unset 0 The context flag is used for various types set 1 of signalling, depending on packet context - Propagation Types ----------------- broadcast 0 transport 1 - Destination Types ----------------- single 00 @@ -553,7 +569,6 @@ group 01 plain 10 link 11 - Packet Types ----------------- data 00 @@ -561,7 +576,6 @@ announce 01 link request 10 proof 11 - +- Packet Example -+ HEADER FIELD DESTINATION FIELDS CONTEXT FIELD DATA FIELD @@ -576,7 +590,6 @@ proof 11 |+------------- Header Type = HEADER_2 (two byte header, two address fields) +-------------- Access Codes = DISABLED - +- Packet Example -+ HEADER FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD @@ -591,7 +604,6 @@ proof 11 |+------------- Header Type = HEADER_1 (two byte header, one address field) +-------------- Access Codes = DISABLED - +- Packet Example -+ HEADER FIELD IFAC FIELD DESTINATION FIELD CONTEXT FIELD DATA FIELD @@ -606,7 +618,6 @@ proof 11 |+------------- Header Type = HEADER_1 (two byte header, one address field) +-------------- Access Codes = ENABLED - Size examples of different packet types --------------------------------------- diff --git a/docs/markdown/using.md b/docs/markdown/using.md index 0338f9e2..3031fd64 100644 --- a/docs/markdown/using.md +++ b/docs/markdown/using.md @@ -58,7 +58,6 @@ configuration file is created. The default configuration looks like this: # configuration example, you can run the command: # rnsd --exampleconfig - [reticulum] # If you enable Transport, your system will route traffic @@ -70,7 +69,6 @@ configuration file is created. The default configuration looks like this: enable_transport = No - # By default, the first program to launch the Reticulum # Network Stack will create a shared instance, that other # programs can communicate with. Only the shared instance @@ -82,7 +80,6 @@ enable_transport = No share_instance = Yes - # If you want to run multiple *different* shared instances # on the same system, you will need to specify different # instance names for each. On platforms supporting domain @@ -97,14 +94,12 @@ instance_name = default # shared_instance_port = 37428 # instance_control_port = 37429 - # If you want to explicitly use TCP for shared instance # communication, instead of domain sockets, this is also # possible, by using the following option: # shared_instance_type = tcp - # On systems where running instances may not have access # to the same shared Reticulum configuration directory, # it is still possible to allow full interactivity for @@ -115,7 +110,6 @@ instance_name = default # rpc_key = e5c032d3ec4e64a6aca9927ba8ab73336780f6d71790 - # It is possible to allow remote management of Reticulum # systems using the various built-in utilities, such as # rnstatus and rnpath. You will need to specify one or @@ -127,7 +121,6 @@ instance_name = default # enable_remote_management = yes # remote_management_allowed = 9fb6d773498fb3feda407ed8ef2c3229, 2d882c5586e548d79b5af27bca1776dc - # You can configure Reticulum to panic and forcibly close # if an unrecoverable interface error occurs, such as the # hardware device for an interface disappearing. This is @@ -136,7 +129,6 @@ instance_name = default # panic_on_interface_error = No - # When Transport is enabled, it is possible to allow the # Transport Instance to respond to probe requests from # the rnprobe utility. This can be a useful tool to test @@ -147,7 +139,6 @@ instance_name = default # respond_to_probes = No - [logging] # Valid log levels are 0 through 7: # 0: Log only critical information @@ -161,7 +152,6 @@ instance_name = default loglevel = 4 - # The interfaces section defines the physical and virtual # interfaces Reticulum will use to communicate on. This # section will contain examples for a variety of interface @@ -1227,6 +1217,7 @@ This provides users and operators with control over what they want to allow *on This functionality serves a dual purpose: * **For Individual Users:** It offers a simple way to maintain a quiet and efficient local network by manually blocking spammy or unwanted peers. + * **For Network Operators:** It enables the creation of federated, community-wide security standards. By publishing and sharing blackhole lists, operators can protect large infrastructures and distribute spam filtering rules across the mesh without manual intervention. ### Local Blackhole Management