## File: README.md

Reticulum Network Stack [](https://github.com/markqvist/Reticulum/actions/workflows/build.yml)
==========



*This repository is [a public mirror](./MIRROR.md). All development is happening elsewhere.*

To understand the foundational philosophy and goals of this system, read the [Zen of Reticulum](Zen%20of%20Reticulum.md).

Reticulum is the cryptography-based networking stack for building local and wide-area
networks with readily available hardware. It can operate even with very high latency
and extremely low bandwidth. Reticulum allows you to build wide-area networks
with off-the-shelf tools, and offers end-to-end encryption and connectivity,
initiator anonymity, autoconfiguring cryptographically backed multi-hop
transport, efficient addressing, unforgeable delivery acknowledgements and
more.

The vision of Reticulum is to allow anyone to be their own network operator,
and to make it cheap and easy to cover vast areas with a myriad of independent,
inter-connectable and autonomous networks. Reticulum **is not** *one* network.
It is **a tool** for building *thousands of networks*. Networks without
kill-switches, surveillance, censorship and control. Networks that can freely
interoperate, associate and disassociate with each other, and require no
central oversight. Networks for human beings. *Networks for the people*.

Reticulum is a complete networking stack, and does not rely on IP or higher
layers, but it is possible to use IP as the underlying carrier for Reticulum.
It is therefore trivial to tunnel Reticulum over the Internet or private IP
networks.

Having no dependencies on traditional networking stacks frees up overhead that
has been used to implement a networking stack built directly on cryptographic
principles, allowing resilience and stable functionality, even in open and
trustless networks.

No kernel modules or drivers are required. Reticulum runs completely in
userland, and can run on practically any system that runs Python 3.

## Read The Manual
The full documentation for Reticulum is available at [markqvist.github.io/Reticulum/manual/](https://markqvist.github.io/Reticulum/manual/).

You can also download the [Reticulum manual as a PDF](https://github.com/markqvist/Reticulum/releases/latest/download/Reticulum.Manual.pdf) or [as an e-book in EPUB format](https://github.com/markqvist/Reticulum/releases/latest/download/Reticulum.Manual.epub).

For more info, see [reticulum.network](https://reticulum.network/) and [the FAQ section of the wiki](https://github.com/markqvist/Reticulum/wiki/Frequently-Asked-Questions).

## Notable Features
- Coordination-less globally unique addressing and identification
- Fully self-configuring multi-hop routing over heterogeneous carriers
- Flexible scalability over heterogeneous topologies
  - Reticulum can carry data over any mixture of physical mediums and topologies
  - Low-bandwidth networks can co-exist and interoperate with large, high-bandwidth networks
- Initiator anonymity, communicate without revealing your identity
  - Reticulum does not include source addresses on any packets
- Asymmetric X25519 encryption and Ed25519 signatures as a basis for all communication
  - The foundational Reticulum Identity Keys are 512-bit Elliptic Curve keysets
- Forward Secrecy is available for all communication types, both for single packets and over links
- Reticulum uses the following format for encrypted tokens:
  - Ephemeral per-packet and link keys and derived from an ECDH key exchange on Curve25519
  - AES-256 in CBC mode with PKCS7 padding
  - HMAC using SHA256 for authentication
  - IVs are generated through os.urandom()
- Unforgeable packet delivery confirmations
- Flexible and extensible interface system
  - Reticulum includes a large variety of built-in interface types
  - Ability to load and utilise custom user- or community-supplied interface types
  - Easily create your own custom interfaces for communicating over anything
- Authentication and virtual network segmentation on all supported interface types
- An intuitive and easy-to-use API
  - Simpler and easier to use than sockets APIs, but more powerful
  - Makes building distributed and decentralised applications much simpler
- Reliable and efficient transfer of arbitrary amounts of data
  - Reticulum can handle a few bytes of data or files of many gigabytes
  - Sequencing, compression, transfer coordination and checksumming are automatic
  - The API is very easy to use, and provides transfer progress
- Lightweight, flexible and expandable Request/Response mechanism
- Efficient link establishment
  - Total cost of setting up an encrypted and verified link is only 3 packets, totalling 297 bytes
  - Low cost of keeping links open at only 0.44 bits per second
- Reliable sequential delivery with Channel and Buffer mechanisms

## Reference Implementation

The Python code in this repository is the Reference Implementation of Reticulum.
The Reticulum Protocol is defined entirely and authoritatively by this reference
implementation, and its associated manual. It is maintained by Mark Qvist,
identified by the Reticulum Identity ``.

No second-order protocol specification derivatives currently do, or will ever exist. You can't get a better specification than one that is executable, functional, testable, deployed and operating 24/7 across the planet.

There is not, and never will be a separate, derived "formal spec", "RFC" or anything similar for Reticulum:

**The reference implementation *is* the final, authoritative specification.**

Compatibility with the Reticulum Protocol is defined as having full interoperability,
and sufficient functional parity with this reference implementation. Any specific protocol
implementation that achieves this is Reticulum. Any that does not is not Reticulum.

The reference implementation is licensed under the Reticulum License.

The Reticulum Protocol was dedicated to the Public Domain in 2016.

## Examples of Reticulum Applications
If you want to quickly get an idea of what Reticulum can do, take a look at the
[Programs Using Reticulum](https://reticulum.network/manual/software.html)
section of the manual, or the following resources:

- [LXMF](https://github.com/markqvist/lxmf) is a distributed, delay and disruption tolerant message transfer protocol built on Reticulum
- The [LXST](https://github.com/markqvist/lxst) protocol and framework provides real-time audio and signals transport over Reticulum. It includes primitives and utilities for building voice-based applications and hardware devices, such as the `rnphone` program, that can be used to build hardware telephones.
- For an off-grid, encrypted and resilient mesh communications platform, see [Nomad Network](https://github.com/markqvist/NomadNet)
- The Android, Linux, macOS and Windows app [Sideband](https://github.com/markqvist/Sideband) has a graphical interface and many advanced features, such as file transfers, image and voice messages, real-time voice calls, a distributed telemetry system, mapping capabilities and full plugin extensibility.
- [MeshChatX](https://git.quad4.io/RNS-Things/MeshChatX) is a full-featured LXMF client with many built-in tools and functionalities, that also supports image and voice messages, file transfers and voice calls. It also includes a built-in page browser for browsing Nomad Network nodes.
- You can use the included [rnsh](https://reticulum.network/manual/using.html#the-rnsh-utility) program to establish remote shell sessions over Reticulum.

## Where can Reticulum be used?
Over practically any medium that can support at least a half-duplex channel
with greater throughput than 5 bits per second, and an MTU of 500 bytes. Data radios,
modems, LoRa radios, serial lines, AX.25 TNCs, amateur radio digital modes,
WiFi and Ethernet devices, free-space optical links, and similar systems are
all examples of the types of physical devices Reticulum can use.

An open-source LoRa-based interface called
[RNode](https://markqvist.github.io/Reticulum/manual/hardware.html#rnode) has
been designed specifically for use with Reticulum. It is possible to build
yourself, or it can be purchased as a complete transceiver that just needs a
USB connection to the host.

Reticulum can also be encapsulated over existing IP networks, so there's
nothing stopping you from using it over wired Ethernet, your local WiFi network
or the Internet, where it'll work just as well. In fact, one of the strengths
of Reticulum is how easily it allows you to connect different mediums into a
self-configuring, resilient and encrypted mesh, using any available mixture of
available infrastructure.

As an example, it's possible to set up a Raspberry Pi connected to both a LoRa
radio, a packet radio TNC and a WiFi network. Once the interfaces are
configured, Reticulum will take care of the rest, and any device on the WiFi
network can communicate with nodes on the LoRa and packet radio sides of the
network, and vice versa.

## How do I get started?
The best way to get started with the Reticulum Network Stack depends on what
you want to do. For full details and examples, have a look at the 
[Getting Started Fast](https://markqvist.github.io/Reticulum/manual/gettingstartedfast.html) 
section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/).

To simply install Reticulum and related utilities on your system, the easiest way is via `pip`.
You can then start any program that uses Reticulum, or start Reticulum as a system service with
[the rnsd utility](https://markqvist.github.io/Reticulum/manual/using.html#the-rnsd-utility).

```bash
pip install rns
```

If you are using an operating system that blocks normal user package installation via `pip`,
you can return `pip` to normal behaviour by editing the `~/.config/pip/pip.conf` file,
and adding the following directive in the `[global]` section:

```text
[global]
break-system-packages = true
```

Alternatively, you can use the `pipx` tool to install Reticulum in an isolated environment:

```bash
pipx install rns
```

When first started, Reticulum will create a default configuration file,
providing basic connectivity to other Reticulum peers that might be locally
reachable. The default config file contains a few examples, and references for
creating a more complex configuration.

If you have an old version of `pip` on your system, you may need to upgrade it first with `pip install pip --upgrade`. If you no not already have `pip` installed, you can install it using the package manager of your system with `sudo apt install python3-pip` or similar.

For more detailed examples on how to expand communication over many mediums such 
as packet radio or LoRa, serial ports, or over fast IP links and the Internet using 
the UDP and TCP interfaces, take a look at the [Supported Interfaces](https://markqvist.github.io/Reticulum/manual/interfaces.html) 
section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/).

## Included Utilities
Reticulum includes a range of useful utilities for managing your networks, 
viewing status and information, and other tasks. You can read more about these 
programs in the [Included Utility Programs](https://markqvist.github.io/Reticulum/manual/using.html#included-utility-programs) 
section of the [Reticulum Manual](https://markqvist.github.io/Reticulum/manual/).

- The system daemon `rnsd` for running Reticulum as an always-available service
- An interface status utility called `rnstatus`, that displays information about interfaces
- The path lookup and management tool `rnpath` letting you view and modify path tables
- A diagnostics tool called `rnprobe` for checking connectivity to destinations
- A simple file transfer program called `rncp` making it easy to transfer files between systems
- The identity management and encryption utility `rnid` let's you manage Identities and encrypt/decrypt files
- The `rnsh` program allows you to establish fully interactive shell session with remote systems
- The remote command execution program `rnx` let's you run simple commands and programs and retrieve output from remote systems
- The `rngit` program provides a full multi-repository Git node for serving repositories over Reticulum
- The included `git-remote-rns` helper allows you to interact with Git repositories over Reticulum

All tools, including `rnx` and `rncp`, work reliably and well even over very
low-bandwidth links like LoRa or Packet Radio. For full-featured remote shells
over Reticulum, also have a look at the [rnsh](https://github.com/acehoss/rnsh)
program.

## Supported interface types and devices

Reticulum implements a range of generalised interface types that covers most of
the communications hardware that Reticulum can run over. If your hardware is
not supported, it's [simple to implement a custom interface module](https://markqvist.github.io/Reticulum/manual/interfaces.html#custom-interfaces).

Pull requests for custom interfaces are gratefully accepted, provided they are
generally useful and well-tested in real-world usage.

Currently, the following built-in interfaces are supported:

- Any Ethernet device
- LoRa using [RNode](https://unsigned.io/rnode/)
- Packet Radio TNCs (with or without AX.25)
- KISS-compatible hardware and software modems
- Any device with a serial port
- TCP over IP networks
- UDP over IP networks
- External programs via stdio or pipes
- Custom hardware via stdio or pipes

## Performance
Reticulum targets a *very* wide usable performance envelope, but prioritises
functionality and performance on low-bandwidth mediums. The goal is to
provide a dynamic performance envelope from 250 bits per second, to 1 gigabit
per second on normal hardware.

Currently, the usable performance envelope is approximately 150 bits per second
to 500 megabits per second, with physical mediums faster than that not being
saturated. Performance beyond the current level is intended for future
upgrades, but not highly prioritised at this point in time.

## Current Status
All core protocol features are implemented and functioning, but additions will
probably occur as real-world use is explored and understood. The API and wire-format
can be considered stable.

## Dependencies
The installation of the default `rns` package requires only two external dependencies, listed
below. Almost all systems and distributions have readily available packages for
these dependencies, and when the `rns` package is installed with `pip`, they
will be downloaded and installed as well.

- [PyCA/cryptography](https://github.com/pyca/cryptography)
- [pyserial](https://github.com/pyserial/pyserial)

On more unusual systems, and in some rare cases, it might not be possible to
install or even compile one or more of the above modules. In such situations,
you can use the `rnspure` package instead, which require no external
dependencies for installation. Please note that the contents of the `rns` and
`rnspure` packages are *identical*. The only difference is that the `rnspure`
package lists no dependencies required for installation.

No matter how Reticulum is installed and started, it will load external
dependencies only if they are *needed* and *available*. If for example you want
to use Reticulum on a system that cannot support
[pyserial](https://github.com/pyserial/pyserial), it is perfectly possible to
do so using the `rnspure` package, but Reticulum will not be able to use
serial-based interfaces. All other available modules will still be loaded when
needed.

**Please Note!** If you use the `rnspure` package to run Reticulum on systems
that do not support [PyCA/cryptography](https://github.com/pyca/cryptography),
it is important that you read and understand the [Cryptographic
Primitives](#cryptographic-primitives) section of this document.

## Bootstrapping Connectivity

Reticulum is not a service you subscribe to, nor is it a single global network you "join".
Reticulum provides functionality for discovering available public interfaces
over the network itself, and the broader community has provided various directories
of publicly available entrypoints to bootstrap connectivity.

To learn how to establish initial connectivity over Reticulum, read the [Bootstrapping Connectivity](https://reticulum.network/manual/gettingstartedfast.html#bootstrapping-connectivity) section of the manual.

If you already have a general idea of how this works, you can use community-run
sites such as [directory.rns.recipes](https://directory.rns.recipes/) and [rmap.world](https://rmap.world)
to find interface definitions for initial connectivity to the global distributed Reticulum backbone.

## Public Testnet
***Important!** Historically, a developer-targeted testnet was made available by the Reticulum project itself. As the amount of global Reticulum nodes and entrypoints have grown to a substantial quantity, this public testnet, including the Amsterdam Testnet entrypoint, has now been decommissioned. If your still have instances that relied on this entrypoint for connectivity, transition to using the distributed backbone instead. Reticulum now includes a full on-network interface discovery and connectivity bootstrapping system. Read the [Bootstrapping Connectivity](https://reticulum.network/manual/gettingstartedfast.html#bootstrapping-connectivity) section of the manual for pointers.*

## Support Reticulum
For this to be possible, I need your help. Please support the continued development of open, free and private communications systems by donating via one of the following channels:

- Monero:
  ```
  84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w
  ```
- Bitcoin
  ```
  bc1pgqgu8h8xvj4jtafslq396v7ju7hkgymyrzyqft4llfslz5vp99psqfk3a6
  ```
- Ethereum
  ```
  0x91C421DdfB8a30a49A71d63447ddb54cEBe3465E
  ```
- Liberapay: https://liberapay.com/Reticulum/

- Ko-Fi: https://ko-fi.com/markqvist

## Cryptographic Primitives
Reticulum uses a simple suite of efficient, strong and well-tested cryptographic
primitives, with widely available implementations that can be used both on
general-purpose CPUs and on microcontrollers.

One of the primary considerations for choosing this particular set of primitives is
that they can be implemented *safely* with relatively few pitfalls, on practically
all current computing platforms.

The primitives listed here **are authoritative**. Anything claiming to be Reticulum,
but not using these exact primitives **is not** Reticulum, and possibly an
intentionally compromised or weakened clone. The utilised primitives are:

- Reticulum Identity Keys are 512-bit Curve25519 keysets
  - A 256-bit Ed25519 key for signatures
  - A 256-bit X22519 key for ECDH key exchanges
- HKDF for key derivation
- Encrypted tokens are based on the [Fernet spec](https://github.com/fernet/spec/)
  - Ephemeral keys derived from an ECDH key exchange on Curve25519
  - HMAC using SHA256 for message authentication
  - IVs must be generated through `os.urandom()` or better
  - AES-256 in CBC mode with PKCS7 padding
  - No Fernet version and timestamp metadata fields
- SHA-256
- SHA-512

In the default installation configuration, the `X25519`, `Ed25519`,
and `AES-256-CBC` primitives are provided by [OpenSSL](https://www.openssl.org/)
(via the [PyCA/cryptography](https://github.com/pyca/cryptography) package).
The hashing functions `SHA-256` and `SHA-512` are provided by the standard
Python [hashlib](https://docs.python.org/3/library/hashlib.html). The `HKDF`,
`HMAC`, `Token` primitives, and the `PKCS7` padding function are always
provided by the following internal implementations:

- [HKDF.py](RNS/Cryptography/HKDF.py)
- [HMAC.py](RNS/Cryptography/HMAC.py)
- [Token.py](RNS/Cryptography/Token.py)
- [PKCS7.py](RNS/Cryptography/PKCS7.py)


Reticulum also includes a complete implementation of all necessary primitives
in pure Python. If OpenSSL and PyCA are not available on the system when
Reticulum is started, Reticulum will instead use the internal pure-python
primitives. A trivial consequence of this is performance, with the OpenSSL
backend being *much* faster. The most important consequence however, is the
potential loss of security by using primitives that has not seen the same
amount of scrutiny, testing and review as those from OpenSSL.

Please note that by default, installing Reticulum will **require** OpenSSL and
PyCA to also be automatically installed if not already available. It is only
possible to use the pure-python primitives if this requirement is specifically
overridden by the user, for example by installing the `rnspure` package instead
of the normal `rns` package, or by running directly from local source-code.

If you want to use the internal pure-python primitives, it is **highly
advisable** that you have a good understanding of the risks that this pose, and
make an informed decision on whether those risks are acceptable to you.

Reticulum is relatively young 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 or security breaking bugs. If you want to help out, or help sponsor an
audit, please do get in touch.

## Acknowledgements & Credits
Reticulum can only exist because of the mountain of Open Source work it was
built on top of, the contributions of everyone involved, and everyone that has
supported the project through the years. To everyone who has helped, thank you
so much.

A number of other modules and projects are either part of, or used by
Reticulum. Sincere thanks to the authors and contributors of the following
projects:

- [PyCA/cryptography](https://github.com/pyca/cryptography), *BSD License*
- [Pure-25519](https://github.com/warner/python-pure25519) by [Brian Warner](https://github.com/warner), *MIT License*
- [Pysha2](https://github.com/thomdixon/pysha2) by [Thom Dixon](https://github.com/thomdixon), *MIT License*
- [Python AES-128](https://github.com/orgurar/python-aes) by [Or Gur Arie](https://github.com/orgurar), *MIT License*
- [Python AES-256](https://github.com/boppreh/aes) by [BoppreH](https://github.com/boppreh), *MIT License*
- [Curve25519.py](https://gist.github.com/nickovs/cc3c22d15f239a2640c185035c06f8a3#file-curve25519-py) by [Nicko van Someren](https://gist.github.com/nickovs), *Public Domain*
- [I2Plib](https://github.com/l-n-s/i2plib) by [Viktor Villainov](https://github.com/l-n-s)
- [PySerial](https://github.com/pyserial/pyserial) by Chris Liechti, *BSD License*
- [Configobj](https://github.com/DiffSK/configobj) by Michael Foord, Nicola Larosa, Rob Dennis & Eli Courtwright, *BSD License*
- [ifaddr](https://github.com/pydron/ifaddr) by Stefan C. Mueller, *MIT License*
- [Umsgpack.py](https://github.com/vsergeev/u-msgpack-python) by [Ivan A. Sergeev](https://github.com/vsergeev)
- [rnsh](https://github.com/acehoss/rnsh) by [Aaron Heise](https://github.com/acehoss)
- [Python](https://www.python.org)

---

## File: docs/source/examples.rst

.. _examples-main:

*************
Code Examples
*************

A number of examples are included in the source distribution of Reticulum. You can use these examples to learn how to write your own programs.

.. _example-minimal:

Minimal
=======

The *Minimal* example demonstrates the bare-minimum setup required to connect to a Reticulum network from your program. In about five lines of code, you will have the Reticulum Network Stack initialised, and ready to pass traffic in your program.

.. literalinclude:: ../../Examples/Minimal.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Minimal.py>`_.

.. _example-announce:

Announce
========

The *Announce* example builds upon the previous example by exploring how to announce a destination on the network, and how to let your program receive notifications about announces from relevant destinations.

.. literalinclude:: ../../Examples/Announce.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Announce.py>`_.

.. _example-broadcast:

Broadcast
=========
The *Broadcast* example explores how to transmit plaintext broadcast messages over the network.

.. literalinclude:: ../../Examples/Broadcast.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Broadcast.py>`_.

.. _example-echo:

Echo
====

The *Echo* example demonstrates communication between two destinations using the Packet interface.

.. literalinclude:: ../../Examples/Echo.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Echo.py>`_.

.. _example-link:

Link
====

The *Link* example explores establishing an encrypted link to a remote destination, and passing traffic back and forth over the link.

.. literalinclude:: ../../Examples/Link.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Link.py>`_.

.. _example-identify:

Identification
==============

The *Identify* example explores identifying an intiator of a link, once the link has been established.

.. literalinclude:: ../../Examples/Identify.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Identify.py>`_.

.. _example-request:

Requests & Responses
====================

The *Request* example explores sending requests and receiving responses.

.. literalinclude:: ../../Examples/Request.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Request.py>`_.

.. _example-channel:

Channel
=======

The *Channel* example explores using a ``Channel`` to send structured data between peers of a ``Link``.

.. literalinclude:: ../../Examples/Channel.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Channel.py>`_.

Buffer
======

The *Buffer* example explores using buffered readers and writers to send binary data between peers of a ``Link``.

.. literalinclude:: ../../Examples/Buffer.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Buffer.py>`_.

.. _example-filetransfer:

Filetransfer
============

The *Filetransfer* example implements a basic file-server program that allow clients to connect and download files. The program uses the Resource interface to efficiently pass files of any size over a Reticulum :ref:`Link<api-link>`.

.. literalinclude:: ../../Examples/Filetransfer.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/Filetransfer.py>`_.

.. _example-custominterface:

Custom Interfaces
=================

The *ExampleInterface* demonstrates creating custom interfaces for Reticulum. Any number of custom interfaces can be loaded and utilised by Reticulum, and will be fully on-par with natively included interfaces, including all supported :ref:`interface modes` and :ref:`common configuration options`.

.. literalinclude:: ../../Examples/ExampleInterface.py

This example can also be found at `<https://github.com/markqvist/Reticulum/blob/master/Examples/ExampleInterface.py>`_.

---

## File: docs/source/forhumans.rst

********************************************
An Explanation of Reticulum for Human Beings
********************************************

---

## File: docs/source/gettingstartedfast.rst

********************
Getting Started Fast
********************

The best way to get started with the Reticulum Network Stack depends on what you want to do. This guide will outline sensible starting paths for different scenarios.


Standalone Reticulum Installation
=================================
If you simply want to install Reticulum and related utilities on a system, the easiest way is via the ``pip`` package manager:

.. code:: shell

   pip install rns

If you do not already have pip installed, you can install it using the package manager of your system with a command like ``sudo apt install python3-pip``, ``sudo pamac install python-pip`` or similar.

You can also dowload the Reticulum release wheels from GitHub, or other release channels, and install them offline using ``pip``:

.. code:: shell

   pip install ./rns-1.1.2-py3-none-any.whl

On platforms that limit user package installation via ``pip``, you may need to manually allow this using the ``--break-system-packages`` command line flag when installing. This will not actually break any packages, unless you have installed Reticulum directly via your operating system's package manager.

.. code:: shell

  pip install rns --break-system-packages

For more detailed installation instructions, please see the :ref:`Platform-Specific Install Notes` section.

After installation is complete, it might be helpful to refer to the :ref:`Using Reticulum on Your System` chapter.

Resolving Dependency & Installation Issues
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
On some platforms, there may not be binary packages available for all dependencies, and ``pip`` installation may fail with an error message. In these cases, the issue can usually be resolved by installing the development essentials packages for your platform:

.. code:: shell

    # Debian / Ubuntu / Derivatives
    sudo apt install build-essential

    # Arch / Manjaro / Derivatives
    sudo pamac install base-devel

    # Fedora
    sudo dnf groupinstall "Development Tools" "Development Libraries"

With the base development packages installed, ``pip`` should be able to compile any missing dependencies from source, and complete installation even on platforms that don't have pre-compiled packages available.

Try Using a Reticulum-based Program
===================================

If you simply want to try using a program built with Reticulum, a :ref:`range of different programs <software-main>` exist that allow basic communication and a various other useful functions, even over extremely low-bandwidth Reticulum networks.


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` chapter of this manual.


Creating a Network With Reticulum
=================================
To create a network, you will need to specify one or more *interfaces* for Reticulum to use. This is done in the Reticulum configuration file, which by default is located at ``~/.reticulum/config``. You can get an example configuration file with all options via ``rnsd --exampleconfig``.

When Reticulum is started for the first time, it will create a default configuration file, with one active interface. This default interface uses your existing Ethernet and WiFi networks (if any), and only allows you to communicate with other Reticulum peers within your local broadcast domains.

To communicate further, you will have to add one or more interfaces. The default configuration includes a number of examples, ranging from using TCP over the internet, to LoRa and Packet Radio interfaces.

With Reticulum, you only need to configure what interfaces you want to communicate over. There is no need to configure address spaces, subnets, routing tables, or other things you might be used to from other network types.

Once Reticulum knows which interfaces it should use, it will automatically discover topography and configure transport of data to any destinations it knows about.

In situations where you already have an established WiFi or Ethernet network, and many devices that want to utilise the same external Reticulum network paths (for example over LoRa), it will often be sufficient to let one system act as a Reticulum gateway, by adding any external interfaces to the configuration of this system, and then enabling transport on it. Any other device on your local WiFi will then be able to connect to this wider Reticulum network just using the default (:ref:`AutoInterface`) configuration.

Possibly, the examples in the config file are enough to get you started. If you want more information, you can read the :ref:`Building Networks<networks-main>` and :ref:`Interfaces` chapters of this manual, but most importantly, start with reading the next section, :ref:`Bootstrapping Connectivity`, as this provides the most essential understanding of how to ensure reliable connectivity with a minimum of maintenance.


.. _bootstrapping-connectivity:

Bootstrapping Connectivity
==========================

Reticulum is not a service you subscribe to, nor is it a single global network you "join". It is a *networking stack*; a toolkit for building communications systems that align with your specific values, requirements, and operational environment. The way you choose to connect to other Reticulum peers is entirely your own choice.

One of the most powerful aspects of Reticulum is that it provides a multitude of tools to establish, maintain, and optimize connectivity. You can use these tools in isolation or combine them in complex configurations to achieve a vast array of goals.

Whether your aim is to create a completely private, air-gapped network for your family; to build a resilient community mesh that survives infrastructure collapse; to connect far and wide to as many nodes as possible; or simply to maintain a reliable, encrypted link to a specific organization you care about, Reticulum provides the mechanisms to make it happen.

There is no "right" or "wrong" way to build a Reticulum network, and you don't need to be a network engineer just to get started. If the information flows in the way you intend, and your privacy and security requirements are met, your configuration is a success. Reticulum is designed to make the most challenging and difficult scenarios attainable, even when other networking technologies fail.


Finding Your Way
^^^^^^^^^^^^^^^^

When you first start using Reticulum, you need a way to obtain connectivity with the peers you want to communicate with - the process of *bootstrapping connectivity*.

.. important::
  
  A common mistake in modern networking is the reliance on a few centralized, hard-coded entrypoints. If every user simply connects to the same list of public IP addresses found on a website, the network becomes brittle, centralized, and ultimately fails to deliver on the promise of decentralization and resilience. You have a responsibility here.

Reticulum encourages the approach of *organic growth*. Instead of relying on permanent static connections to distant servers, you can use temporary bootstrap connections to continously *discover* more relevant or local infrastructure. Once discovered, your system can automatically form stronger, more direct links to these peers, and discard the temporary bootstrap links. This results in a web of connections that are geographically relevant, resilient and efficient.

It *is* possible to simply add a few public entrypoints to the ``[interfaces]`` section of your Reticulum configuration and be connected, but a better option is to enable :ref:`interface discovery` and either manually select relevant, local interfaces, or enable discovered interface auto-connection.

A relevant option in this context is the :ref:`bootstrap only` interface option. This is an automated tool for better distributing connectivity. By enabling interface discovery and auto-connection, and marking an interface as ``bootstrap_only``, you tell Reticulum to use that interface primarliy to find connectivity options, and then disconnect it once sufficient entrypoints have been discovered. This helps create a network topology that favors locality and resilience over the simple centralization caused by using only a few static entrypoints.

Good places to find interface definitions for bootstrapping connectivity are websites like
`directory.rns.recipes <https://directory.rns.recipes/>`_ and `rmap.world <https://rmap.world/>`_.


Build Personal Infrastructure
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

You do not need a datacenter to be a meaningful part of the Reticulum ecosystem. In fact, the most important nodes in the network are often the smallest ones.

We strongly encourage everyone, even home users, to think in terms of building **personal infrastructure**. Don't connect every phone, tablet, and computer in your house directly to a public internet gateway. Instead, repurpose an old computer, a Raspberry Pi, or a supported router to act as your own, personal **Transport Node**:

*   Your local Transport Node sits in your home, connected to your WiFi and perhaps a radio interface (like an RNode).
*   You configure this node with a ``bootstrap_only`` interface (perhaps a TCP tunnel to a wider network) and enable interface discovery.
*   While you sleep, work, or cook, your node listens to the network. It discovers other local community members, validates their Network Identities, and automatically establishes direct links.
*   Your personal devices now connect to your *local* node, which is integrated into a living, breathing local mesh. Your traffic flows through local paths provided by other real people in the community rather than bouncing off a distant server.

**Don't wait for others to build the networks you want to see**. Every network is important, perhaps even most so those that support individual families and persons. Once enough of this personal, local infrastructure exist, connecting them directly to each other, without traversing the public Internet, becomes inevitable.


Mixing Strategies
^^^^^^^^^^^^^^^^^

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.


Network Health & Responsibility
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

As you participate in the wider networks you discover and build, you will inevitably encounter peers that are misconfigured, malicious, or simply broken. To protect your resources and those of your local peers, you can utilize the :ref:`Blackhole Management` system.

Whether you manually block a spamming identity or subscribe to a blackhole list maintained by a trusted Network Identity, these tools help ensure that *your* transport capacity is used for what *you* consider legitimate communication. This keeps your local segment efficient and contributes to the health of the wider network.


Contributing to the Global Ret
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

If you have the means to host a stable node with a public IP address, consider becoming a :ref:`Public Entrypoint<hosting-entrypoints>`. By :ref:`publishing your interface as discoverable`, you provide a potential connection point for others, helping the network grow and reach new areas.

For guidelines on how to properly configure a public entrypoint, refer to the :ref:`Hosting Public Entrypoints<hosting-entrypoints>` section.

Connect to the Distributed Backbone
===================================

A global, distributed backbone of Reticulum Transport Nodes is being run by volunteers from around the world. This network constitutes a heterogenous collection of both public and private nodes that form an uncoordinated, voluntary inter-networking backbone that currently provides global transport and internetworking capabilities for Reticulum.

As a good starting point, you can find interface definitions for connecting your own networks to this backbone on websites such as `directory.rns.recipes <https://directory.rns.recipes/>`_ and `rmap.world <https://rmap.world/>`_.

.. tip::
  Don't rely on just a single connection to the distributed backbone for everyday use. It is much better to have several redundant connections configured, and enable the interface discovery options, so your nodes can continously discover peering opportunities as the network evolves. Refer to the :ref:`Bootstrapping Connectivity` section to understand the options.



.. _hosting-entrypoints:

Hosting Public Entrypoints
==========================

If you want to help build a strong global interconnection backbone, you can host a public (or private) entry-point to a Reticulum network over the Internet. This section offers some helpful pointers. Once you have set up your public entrypoint, it is a great idea to :ref:`make it discoverable over Reticulum`.

You will need a machine, physical or virtual with a public IP address, that can be reached by other devices on the Internet.

The most efficient and performant way to host a connectable entry-point supporting many users is to use the ``BackboneInterface``. This interface type is fully compatible with the ``TCPClientInterface`` and ``TCPServerInterface`` types, but much faster and uses less system resources, allowing your device to handle thousands of connections even on small systems.

It is also important to set your connectable interface to ``gateway`` mode, since this will greatly improve network convergence time and path resolution for anyone connecting to your entry-point.

.. code:: ini

  # This example demonstrates a backbone interface
  # configured for acting as a gateway for users to
  # connect to either a public or private network

  [[Public Gateway]]
    type = BackboneInterface
    enabled = yes
    mode = gateway
    listen_on = 0.0.0.0
    port = 4242

    # On publicly available interfaces, it is
    # essential to configure sensible announce
    # rate targets.
    announce_rate_target = 3600
    announce_rate_penalty = 3600
    announce_rate_grace = 6

If instead you want to make a private entry-point from the Internet, you can use the :ref:`IFAC name and passphrase options` to secure your interface with a network name and passphrase.

.. code:: ini

  # A private entry-point requiring a pre-shared
  # network name and passphrase to connect to.

  [[Private Gateway]]
    type = BackboneInterface
    enabled = yes
    mode = gateway
    listen_on = 0.0.0.0
    port = 4242
    network_name = private_ret
    passphrase = 2owjajquafIanPecAc

If you are hosting an entry-point on an operating system that does not support ``BackboneInterface``, you can use ``TCPServerInterface`` instead, although it will not be as performant.


Connecting Reticulum Instances Over the Internet
================================================
Reticulum currently offers three interfaces suitable for connecting instances over the Internet: :ref:`Backbone`, :ref:`TCP` and :ref:`I2P`. Each interface offers a different set of features, and Reticulum users should carefully choose the interface which best suites their needs.

The ``TCPServerInterface`` allows users to host an instance accessible over TCP/IP. This method is generally faster, lower latency, and more energy efficient than using ``I2PInterface``, however it also leaks more data about the server host.

The ``BackboneInterface`` is a very fast and efficient interface type available on POSIX operating systems, designed to handle thousands of connections simultaneously with low memory, processing and I/O overhead. It is fully compatible with the TCP-based interface types.

TCP connections reveal the IP address of both your instance and the server to anyone who can inspect the connection. Someone could use this information to determine your location or identity. Adversaries inspecting your packets may be able to record packet metadata like time of transmission and packet size. Even though Reticulum encrypts traffic, TCP does not, so an adversary may be able to use packet inspection to learn that a system is running Reticulum, and what other IP addresses connect to it. Hosting a publicly reachable instance over TCP also requires a publicly reachable IP address, which most Internet connections don't offer anymore.

The ``I2PInterface`` routes messages through the `Invisible Internet Protocol (I2P) <https://geti2p.net/en/>`_. To use this interface, users must also run an I2P daemon in parallel to ``rnsd``. For always-on I2P nodes it is recommended to use `i2pd <https://i2pd.website/>`_.

By default, I2P will encrypt and mix all traffic sent over the Internet, and hide both the sender and receiver Reticulum instance IP addresses. Running an I2P node will also relay other I2P user's encrypted packets, which will use extra bandwidth and compute power, but also makes timing attacks and other forms of deep-packet-inspection much more difficult.

I2P also allows users to host globally available Reticulum instances from non-public IP's and behind firewalls and NAT.

In general it is recommended to use an I2P node if you want to host a publicly accessible instance, while preserving anonymity. If you care more about performance, and a slightly easier setup, use TCP.

Adding Radio Interfaces
=======================
Once you have Reticulum installed and working, you can add radio interfaces with any compatible hardware you have available. Reticulum supports a wide range of radio hardware, and if you already have any available, it is very likely that it will work with Reticulum. For information on how to configure this, see the :ref:`Interfaces` section of this manual.

If you do not already have transceiver hardware available, you can easily and cheaply build an :ref:`RNode<rnode-main>`, which is a general-purpose long-range digital radio transceiver, that integrates easily with Reticulum.

To build one yourself requires installing a custom firmware on a supported LoRa development board with an auto-install script or web-based flasher. Please see the :ref:`Communications Hardware<hardware-main>` chapter for a guide. If you prefer purchasing a ready-made unit, you can refer to the :ref:`list of suppliers<rnode-suppliers>`. 

Other radio-based hardware interfaces are being developed and made available by the broader Reticulum community. You can find more information on such topics over Reticulum-based information sharing systems.

If you have communications hardware that is not already supported by any of the :ref:`existing interface types`, it is easy to write (and potentially publish) a :ref:`custom interface module` that makes it compatible with Reticulum.


Creating and Using Custom Interfaces
====================================

While Reticulum includes a flexible and broad range of built-in interfaces, these will not cover every conceivable type of communications hardware that Reticulum can potentially use to communicate.

It is therefore possible to easily write your own interface modules, that can be loaded at run-time and used on-par with any of the built-in interface types.

For more information on this subject, and code examples to build on, please see the :ref:`Configuring Interfaces` chapter.


Develop a Program with Reticulum
================================
If you want to develop programs that use Reticulum, the easiest way to get started is to install the latest release of Reticulum via pip:

.. code::

   pip install rns

The above command will install Reticulum and dependencies, and you will be ready to import and use RNS in your own programs. The next step will most likely be to look at some :ref:`Example Programs<examples-main>`.

The entire Reticulum API is documented in the :ref:`API Reference<api-main>` chapter of this manual. Before diving in, it's probably a good idea to read this manual in full, but at least start with the :ref:`Understanding Reticulum` chapter.


.. _install-guides:

Platform-Specific Install Notes
===============================

Some platforms require a slightly different installation procedure, or have various quirks that are worth being aware of. These are listed here.

Android
^^^^^^^
Reticulum can be used on Android in different ways. The easiest way to get started is using an app like `Sideband <https://unsigned.io/sideband>`_.

For more control and features, you can use Reticulum and related programs via the `Termux app <https://termux.com/>`_, at the time of writing available on `F-droid <https://f-droid.org>`_.

Termux is a terminal emulator and Linux environment for Android based devices, which includes the ability to use many different programs and libraries, including Reticulum.

To use Reticulum within the Termux environment, you will need to install ``python`` and the ``python-cryptography`` library using ``pkg``, the package-manager build into Termux. After that, you can use ``pip`` to install Reticulum.

From within Termux, execute the following:

.. code:: shell

    # First, make sure indexes and packages are up to date.
    pkg update
    pkg upgrade

    # Then install python and the cryptography library.
    pkg install python python-cryptography

    # Make sure pip is up to date, and install the wheel module.
    pip install wheel pip --upgrade

    # Install Reticulum
    pip install rns

If for some reason the ``python-cryptography`` package is not available for your platform via the Termux package manager, you can attempt to build it locally on your device using the following command:

.. code:: shell

    # First, make sure indexes and packages are up to date.
    pkg update
    pkg upgrade

    # Then install dependencies for the cryptography library.
    pkg install python build-essential openssl libffi rust

    # Make sure pip is up to date, and install the wheel module.
    pip install wheel pip --upgrade

    # To allow the installer to build the cryptography module,
    # we need to let it know what platform we are compiling for:
    export CARGO_BUILD_TARGET="aarch64-linux-android"

    # Start the install process for the cryptography module.
    # Depending on your device, this can take several minutes,
    # since the module must be compiled locally on your device.
    pip install cryptography

    # If the above installation succeeds, you can now install
    # Reticulum and any related software
    pip install rns

It is also possible to include Reticulum in apps compiled and distributed as Android APKs. A detailed tutorial and example source code will be included here at a later point. Until then you can use the `Sideband source code <https://github.com/markqvist/sideband>`_ as an example and starting point.


ARM64
^^^^^
On some architectures, including ARM64, not all dependencies have precompiled binaries. On such systems, you may need to install ``python3-dev`` (or similar) before installing Reticulum or programs that depend on Reticulum.

.. code:: shell

   # Install Python and development packages
   sudo apt update
   sudo apt install python3 python3-pip python3-dev

   # Install Reticulum
   python3 -m pip install rns

With these packages installed, ``pip`` will be able to build any missing dependencies
on your system locally.


Debian Bookworm
^^^^^^^^^^^^^^^
On versions of Debian released after April 2023, it is no longer possible by default to use ``pip`` to install packages onto your system. Unfortunately, you will need to use the replacement ``pipx`` command instead, which places installed packages in an isolated environment. This should not negatively affect Reticulum, but will not work for including and using Reticulum in your own scripts and programs.

.. code:: shell

    # Install pipx
    sudo apt install pipx

    # Make installed programs available on the command line
    pipx ensurepath

    # Install Reticulum
    pipx install rns

Alternatively, you can restore normal behaviour to ``pip`` by creating or editing the configuration file located at ``~/.config/pip/pip.conf``, and adding the following section:

.. code:: ini

    [global]
    break-system-packages = true

For a one-shot installation of Reticulum, without globally enabling the ``break-system-packages`` option, you can use the following command:

.. code:: shell

    pip install rns --break-system-packages

.. note::
   The ``--break-system-packages`` directive is a somewhat misleading choice of words. Setting it will of course not break any system packages, but will simply allow installing ``pip`` packages user- and system-wide. While this *could* in rare cases lead to version conflicts, it does not generally pose any problems, especially not in the case of installing Reticulum.


MacOS
^^^^^
To install Reticulum on macOS, you will need to have Python and the ``pip`` package manager installed.

Systems running macOS can vary quite widely in whether or not Python is pre-installed, and if it is, which version is installed, and whether the ``pip`` package manager is also installed and set up. If in doubt, you can `download and install <https://www.python.org/downloads/>`_ Python manually.

When Python and ``pip`` is available on your system, simply open a terminal window and use one of the following commands:

.. code:: shell

   # Install Reticulum and utilities with pip:
   pip3 install rns
   
   # On some versions, you may need to use the
   # flag --break-system-packages to install:
   pip3 install rns --break-system-packages

.. note::
   The ``--break-system-packages`` directive is a somewhat misleading choice of words. Setting it will of course not break any system packages, but will simply allow installing ``pip`` packages user- and system-wide. While this *could* in rare cases lead to version conflicts, it does not generally pose any problems, especially not in the case of installing Reticulum.

Additionally, some version combinations of macOS and Python require you to manually add your installed ``pip`` packages directory to your `PATH` environment variable, before you can use installed commands in your terminal. Usually, adding the following line to your shell init script (for example ``~/.zshrc``) will be enough:

.. code:: shell

   export PATH=$PATH:~/Library/Python/3.9/bin

Adjust Python version and shell init script location according to your system.


OpenWRT
^^^^^^^
On OpenWRT systems with sufficient storage and memory, you can install Reticulum and related utilities using the `opkg` package manager and `pip`.

.. note::
   At the time of releasing this manual, work is underway to create pre-built Reticulum packages for OpenWRT, with full configuration, service and ``uci`` integration. Please see the `feed-reticulum <https://github.com/gretel/feed-reticulum>`_ and `reticulum-openwrt <https://github.com/gretel/reticulum-openwrt>`_ repositories for more information.

To install Reticulum on OpenWRT, first log into a command line session, and then use the following instructions:

.. code:: shell

   # Install dependencies
   opkg install python3 python3-pip python3-cryptography python3-pyserial
   
   # Install Reticulum
   pip install rns

   # Start rnsd with debug logging enabled
   rnsd -vvv

.. note::
   The above instructions have been verified and tested on OpenWRT 21.02 only. It is likely that other versions may require slightly altered installation commands or package names. You will also need enough free space in your overlay FS, and enough free RAM to actually run Reticulum and any related programs and utilities.

Depending on your device configuration, you may need to adjust firewall rules for Reticulum connectivity to and from your device to work. Until proper packaging is ready, you will also need to manually create a service or startup script to automatically laucnh Reticulum at boot time.

Please also note that the `AutoInterface` requires link-local IPv6 addresses to be enabled for any Ethernet and WiFi devices you intend to use. If ``ip a`` shows an address starting with ``fe80::`` for the device in question, ``AutoInterface`` should work for that device.

Raspberry Pi
^^^^^^^^^^^^
It is currently recommended to use a 64-bit version of the Raspberry Pi OS if you want to run Reticulum on Raspberry Pi computers, since 32-bit versions don't always have packages available for some dependencies. If Python and the `pip` package manager is not already installed, do that first, and then install Reticulum using `pip`.

.. code:: shell

   # Install dependencies
   sudo apt install python3 python3-pip python3-cryptography python3-pyserial
   
   # Install Reticulum
   pip install rns --break-system-packages

.. note::
   The ``--break-system-packages`` directive is a somewhat misleading choice of words. Setting it will of course not break any system packages, but will simply allow installing ``pip`` packages user- and system-wide. While this *could* in rare cases lead to version conflicts, it does not generally pose any problems, especially not in the case of installing Reticulum.

While it is possible to install and run Reticulum on 32-bit Rasperry Pi OSes, it will require manually configuring and installing required build dependencies, and is not detailed in this manual.


RISC-V
^^^^^^
On some architectures, including RISC-V, not all dependencies have precompiled binaries. On such systems, you may need to install ``python3-dev`` (or similar) before installing Reticulum or programs that depend on Reticulum.

.. code:: shell

   # Install Python and development packages
   sudo apt update
   sudo apt install python3 python3-pip python3-dev

   # Install Reticulum
   python3 -m pip install rns

With these packages installed, ``pip`` will be able to build any missing dependencies on your system locally.


Ubuntu Lunar
^^^^^^^^^^^^
On versions of Ubuntu released after April 2023, it is no longer possible by default to use ``pip`` to install packages onto your system. Unfortunately, you will need to use the replacement ``pipx`` command instead, which places installed packages in an isolated environment. This should not negatively affect Reticulum, but will not work for including and using Reticulum in your own scripts and programs.

.. code:: shell

    # Install pipx
    sudo apt install pipx

    # Make installed programs available on the command line
    pipx ensurepath

    # Install Reticulum
    pipx install rns

Alternatively, you can restore normal behaviour to ``pip`` by creating or editing the configuration file located at ``~/.config/pip/pip.conf``, and adding the following section:

.. code:: text

    [global]
    break-system-packages = true

For a one-shot installation of Reticulum, without globally enabling the ``break-system-packages`` option, you can use the following command:

.. code:: text

    pip install rns --break-system-packages

.. note::
   The ``--break-system-packages`` directive is a somewhat misleading choice of words. Setting it will of course not break any system packages, but will simply allow installing ``pip`` packages user- and system-wide. While this *could* in rare cases lead to version conflicts, it does not generally pose any problems, especially not in the case of installing Reticulum.

Windows
^^^^^^^
On Windows operating systems, the easiest way to install Reticulum is by using the ``pip`` package manager from the command line (either the command prompt or Windows Powershell).

If you don't already have Python installed, `download and install Python <https://www.python.org/downloads/>`_. At the time of publication of this manual, the recommended version is `Python 3.12.7 <https://www.python.org/downloads/release/python-3127>`_.

**Important!** When asked by the installer, make sure to add the Python program to your PATH environment variables. If you don't do this, you will not be able to use the ``pip`` installer, or run the included Reticulum utility programs (such as ``rnsd`` and ``rnstatus``) from the command line.

After installing Python, open the command prompt or Windows Powershell, and type:

.. code:: shell

   pip install rns

You can now use Reticulum and all included utility programs directly from your preferred command line interface.

Pure-Python Reticulum
=====================

.. warning::
   If you use the ``rnspure`` package to run Reticulum on systems that
   do not support `PyCA/cryptography <https://github.com/pyca/cryptography>`_, it is
   important that you read and understand the :ref:`Cryptographic Primitives `
   section of this manual.

In some rare cases, and on more obscure system types, it is not possible to install one or more dependencies. In such situations, you can use the ``rnspure`` package instead of the ``rns`` package, or use ``pip`` with the ``--no-dependencies`` command-line option. The ``rnspure`` package requires no external dependencies for installation. Please note that the actual contents of the ``rns`` and ``rnspure`` packages are *completely identical*. The only difference is that the ``rnspure`` package lists no dependencies required for installation.

No matter how Reticulum is installed and started, it will load external dependencies only if they are *needed* and *available*. If for example you want to use Reticulum on a system that cannot support ``pyserial``, it is perfectly possible to do so using the `rnspure` package, but Reticulum will not be able to use serial-based interfaces. All other available modules will still be loaded when needed.

---

## File: docs/source/hardware.rst

.. _hardware-main:

***********************
Communications Hardware
***********************

One of the truly valuable aspects of Reticulum is the ability to use it over
almost any conceivable kind of communications medium. The :ref:`interface types`
available for configuration in Reticulum are flexible enough to cover the use
of most wired and wireless communications hardware available, from decades-old
packet radio modems to modern millimeter-wave backhaul systems.

If you already have or operate some kind of communications hardware, there is a
very good chance that it will work with Reticulum out of the box. In case it does
not, it is possible to provide the necessary glue with very little effort using
for example the :ref:`PipeInterface` or the :ref:`TCPClientInterface`
in combination with code like `TCP KISS Server <https://github.com/simplyequipped/tcpkissserver>`_
by `simplyequipped <https://github.com/simplyequipped>`_.

It is also very easy to write and load :ref:`custom interface modules`
into Reticulum, allowing you to communicate with more or less anything you can think of.

While this broad support and flexibility is very useful, an abundance of options
can sometimes make it difficult to know where to begin, especially when you are
starting from scratch.

This chapter will outline a few different sensible starting paths to get
real-world functional wireless communications up and running with minimal cost
and effort. Two fundamental devices categories will be covered, *RNodes* and
*WiFi-based radios*. Additionally, other common options will be briefly described.

Knowing how to employ just a few different types of hardware will make it possible
to build a wide range of useful networks with little effort.

Combining Hardware Types
========================

It is useful to combine different link and hardware types when designing and
building a network. One useful design pattern is to employ high-capacity point-to-point
links based on WiFi or millimeter-wave radios (with high-gain directional antennas)
for the network backbone, and using LoRa-based RNodes for covering large areas with
connectivity for client devices.


.. _rnode-main:

RNode
=====

Reliable and general-purpose long-range digital radio transceiver systems are
commonly either very expensive, difficult to set up and operate, hard to source,
power-hungry, or all of the above at the same time. In an attempt to alleviate
this situation, the transceiver system *RNode* was designed. It is important to
note that RNode is not one specific device, from one particular vendor, but
*an open plaform* that anyone can use to build interoperable digital transceivers
suited to their needs and particular situations.

An RNode is a general purpose, interoperable, low-power and long-range, reliable,
open and flexible radio communications device. Depending on its components, it can
operate on many different frequency bands, and use many different modulation
schemes, but most commonly, and for the purposes of this chapter, we will limit
the discussion to RNodes using *LoRa* modulation in common ISM bands.

**Avoid Confusion!** RNodes can use LoRa as a *physical-layer modulation*, but it
does not use, and has nothing to do with the *LoRaWAN* protocol and standard, commonly
used for centrally controlled IoT devices. RNodes use *raw LoRa modulation*, without
any additional protocol overhead. All high-level protocol functionality is handled
directly by Reticulum.

.. _rnode-creating:

Creating RNodes
^^^^^^^^^^^^^^^
RNode has been designed as a system that is easy to replicate across time and
space. You can put together a functioning transceiver using commonly available
components, and a few open source software tools. While you can design and build RNodes
completely from scratch, to your exact desired specifications, this chapter
will explain the easiest possible approach to creating RNodes: Using common
LoRa development boards. This approach can be boiled down to two simple steps:

1. Obtain one or more :ref:`supported development boards<rnode-supported>`
2. Install the RNode firmware with the :ref:`automated installer<rnode-installation>`

Once the firmware has been installed and provisioned by the install script, it
is ready to use with any software that supports RNodes, including Reticulum.
The device can be used with Reticulum by adding an :ref:`RNodeInterface`
to the configuration.

.. _rnode-supported:

Supported Boards and Devices
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
To create one or more RNodes, you will need to obtain supported development
boards or completed devices. The following boards and devices are supported
by the auto-installer.

------------

.. image:: graphics/board_tbeam_supreme.png
    :width: 75%
    :align: center

LilyGO T-Beam Supreme
"""""""""""""
- **Transceiver IC** Semtech SX1262 or SX1268
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_

------------

.. image:: graphics/board_tbeam.png
    :width: 75%
    :align: center

LilyGO T-Beam
"""""""""""""
- **Transceiver IC** Semtech SX1262, SX1268, SX1276 or SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_

------------

.. image:: graphics/board_t3s3.png
    :width: 50%
    :align: center

LilyGO T3S3
"""""""""""
- **Transceiver IC** Semtech SX1262, SX1268, SX1276 or SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_

------------

.. image:: graphics/board_rak4631.png
    :width: 45%
    :align: center

RAK4631-based Boards
""""""""""""""""""""
- **Transceiver IC** Semtech SX1262 or SX1268
- **Device Platform** nRF52
- **Manufacturer** `RAK Wireless <https://www.rakwireless.com>`_

------------

.. image:: graphics/board_opencomxl.png
    :width: 45%
    :align: center

OpenCom XL
""""""""""""""""""""
- **Transceiver ICs** Semtech SX1262 and SX1280 (dual transceiver)
- **Device Platform** nRF52
- **Manufacturer** `Liberated Embedded Systems <https://liberatedsystems.co.uk/>`_

------------

.. image:: graphics/board_rnodev2.png
    :width: 68%
    :align: center

Unsigned RNode v2.x
"""""""""""""""""""
- **Transceiver IC** Semtech SX1276 or SX1278
- **Device Platform** ESP32
- **Manufacturer** `unsigned.io <https://unsigned.io>`_

------------

.. image:: graphics/board_t3v21.png
    :width: 46%
    :align: center

LilyGO LoRa32 v2.1
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 or SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_

------------

.. image:: graphics/board_t3v20.png
    :width: 46%
    :align: center

LilyGO LoRa32 v2.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 or SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_

------------

.. image:: graphics/board_t3v10.png
    :width: 46%
    :align: center

LilyGO LoRa32 v1.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 or SX1278
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_

------------

.. image:: graphics/board_tdeck.png
    :width: 45%
    :align: center

LilyGO T-Deck
"""""""""""""
- **Transceiver IC** Semtech SX1262 or SX1268
- **Device Platform** ESP32
- **Manufacturer** `LilyGO <https://lilygo.cn>`_

------------

.. image:: graphics/board_techo.png
    :width: 45%
    :align: center

LilyGO T-Echo
"""""""""""""
- **Transceiver IC** Semtech SX1262 or SX1268
- **Device Platform** nRF52
- **Manufacturer** `LilyGO <https://lilygo.cn>`_

------------

.. image:: graphics/board_t114.png
    :width: 58%
    :align: center

Heltec T114
"""""""""""
- **Transceiver IC** Semtech SX1262 or SX1268
- **Device Platform** nRF52
- **Manufacturer** `Heltec Automation <https://heltec.org>`_

------------

.. image:: graphics/board_heltec32v4.png
    :width: 58%
    :align: center

Heltec LoRa32 v4.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1262
- **Device Platform** ESP32
- **Manufacturer** `Heltec Automation <https://heltec.org>`_

------------

.. image:: graphics/board_heltec32v30.png
    :width: 58%
    :align: center

Heltec LoRa32 v3.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1262 or SX1268
- **Device Platform** ESP32
- **Manufacturer** `Heltec Automation <https://heltec.org>`_

------------

.. image:: graphics/board_heltec32v20.png
    :width: 58%
    :align: center

Heltec LoRa32 v2.0
""""""""""""""""""
- **Transceiver IC** Semtech SX1276 or SX1278
- **Device Platform** ESP32
- **Manufacturer** `Heltec Automation <https://heltec.org>`_

------------

.. _rnode-installation:

Installation
^^^^^^^^^^^^

Once you have obtained compatible boards, you can install the `RNode Firmware <https://github.com/markqvist/RNode_Firmware>`_
using the `RNode Configuration Utility <https://github.com/markqvist/rnodeconfigutil>`_.
If you have installed Reticulum on your system, the ``rnodeconf`` program will already be
available. If not, make sure that ``Python3`` and ``pip`` is installed on your system, and
then install Reticulum with with ``pip``:

.. code::

   pip install rns

Once installation has completed, it is time to start installing the firmware on your
devices. Run ``rnodeconf`` in auto-install mode like so:

.. code::

   rnodeconf --autoinstall

The utility will guide you through the installation process by asking a series of
questions about your hardware. Simply follow the guide, and the utility will
auto-install and configure your devices.

.. _rnode-usage:

Usage with Reticulum
^^^^^^^^^^^^^^^^^^^^
When the devices have been installed and provisioned, you can use them with Reticulum
by adding the :ref:`relevant interface section` to the configuration
file of Reticulum. In the configuraion you can specify all interface parameters,
such as serial port and on-air parameters.


WiFi-based Hardware
===================

It is possible to use all kinds of both short- and long-range WiFi-based hardware
with Reticulum. Any kind of hardware that fully supports bridged Ethernet over the
WiFi interface will work with the :ref:`AutoInterface` in Reticulum.
Most devices will behave like this by default, or allow it via configuration options.

This means that you can simply configure the physical links of the WiFi based devices,
and start communicating over them using Reticulum. It is not necessary to enable any IP
infrastructure such as DHCP servers, DNS or similar, as long as at least Ethernet is
available, and packets are passed transparently over the physical WiFi-based devices.

.. only:: html

    .. image:: graphics/radio_rblhg5.png
        :width: 49%

    .. image:: graphics/radio_is5ac.png
        :width: 49%

Below is a list of example WiFi (and similar) radios that work well for high capacity
Reticulum links over long distances:

- `Ubiquiti airMAX radios <https://store.ui.com/collections/operator-airmax-devices>`_
- `Ubiquiti LTU radios <https://store.ui.com/collections/operator-ltu>`_
- `MikroTik radios <https://mikrotik.com/products/group/wireless-systems>`_

This list is by no means exhaustive, and only serves as a few examples of radio hardware
that is relatively cheap while providing long range and high capacity for Reticulum
networks. As in all other cases, it is also possible for Reticulum to co-exist with IP
networks running concurrently on such devices.

Ethernet-based Hardware
=======================

Reticulum can run over any kind of hardware that can provide a switched Ethernet-based
medium. This means that anything from a plain Ethernet switch, to fiber-optic systems,
to data radios with Ethernet interfaces can be used by Reticulum.

The Ethernet medium does not need to have any IP infrastructure such as DHCP servers
or routing set up, but in case such infrastructure does exist, Reticulum will simply
co-exist with.

To use Reticulum over Ethernet-based mediums, it is generally enough to use the included
:ref:`AutoInterface`. This interface also works over any kind of
virtual networking adapter, such as ``tun`` and ``tap`` devices in Linux.

Serial Lines & Devices
======================

Using Reticulum over any kind of raw serial line is also possible with the
:ref:`SerialInterface`. This interface type is also useful for
using Reticulum over communications hardware that provides a serial port interface.

Packet Radio Modems
===================

Any packet radio modem that provides a standard KISS interface over USB, serial or TCP
can be used with Reticulum. This includes virtual software modems such as
`FreeDV TNC <https://github.com/xssfox/freedv-tnc>`_ and `Dire Wolf <https://github.com/wb2osz/direwolf>`_.

---

## File: docs/source/index.rst

******************************
Reticulum Network Stack Manual
******************************

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

.. only:: builder_html

   This manual is also available in `PDF <https://github.com/markqvist/Reticulum/releases/latest/download/Reticulum.Manual.pdf>`_ and `EPUB <https://github.com/markqvist/Reticulum/releases/latest/download/Reticulum.Manual.epub>`_ formats.

.. only:: builder_html

   Table Of Contents
   =================

.. toctree::
   :maxdepth: 3

   whatis
   gettingstartedfast
   zen
   software
   using
   understanding
   hardware
   interfaces
   networks
   distributed
   git
   support
   examples
   license

.. toctree::
   :maxdepth: 2

   reference


.. only:: html

   Indices and Tables
   ==================

   * :ref:`genindex`
   * :ref:`search`

---

## File: docs/source/interfaces.rst

.. _interfaces-main:

**********************
Configuring Interfaces
**********************

Reticulum supports using many kinds of devices as networking interfaces, and
allows you to mix and match them in any way you choose. The number of distinct
network topologies you can create with Reticulum is more or less endless, but
common to them all is that you will need to define one or more *interfaces*
for Reticulum to use.

The following sections describe the interfaces currently available in Reticulum,
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-custom:

Custom Interfaces
=================

In addition to the built-in interface types, Reticulum is **fully extensible** with
custom, user- or community-supplied interfaces, and creating custom interface
modules is straightforward. Please see the :ref:`custom interface<example-custominterface>`
example for basic interface code to build upon.

.. _interfaces-auto:

Auto Interface
==============

The ``AutoInterface`` enables communication with other discoverable Reticulum
nodes over any kind of local Ethernet or WiFi-based medium. Even though it uses IPv6 for peer
discovery, and UDP for packet transport, it **does not** need any functional IP
infrastructure like routers or DHCP servers, on your physical network.

.. warning::
  If you have **firewall** software running on your computer, it may block traffic
  required for ``AutoInterface`` to work. If this is the case, you will have to
  allow UDP traffic on port ``29716`` and ``42671``.

As long as there is at least some sort of switching medium present between peers (a
wired switch, a hub, a WiFi access point or similar, or simply two devices connected
directly by Ethernet cable), it will work without any configuration, setup or intermediary devices.

For ``AutoInterface`` peer discovery to work, it's also required that link-local
IPv6 support is available on your system, which it should be by default in all
current operating systems, both desktop and mobile.

.. note::
  Almost all current Ethernet and WiFi hardware will work without any kind
  of configuration or setup with ``AutoInterface``, but a small subset of
  devices turn on options that limit device-to-device communication by default,
  resulting in ``AutoInterface`` peer discovery being blocked. This issue is
  most commonly seen on very cheap, ISP-supplied WiFi routers, and can sometimes
  be turned off in the router configuration.

.. code:: ini

  # This example demonstrates a bare-minimum setup
  # of an Auto Interface. It will allow communica-
  # tion with all other reachable devices on all
  # usable physical ethernet-based devices that
  # are available on the system.
  [[Default Interface]]
    type = AutoInterface
    enabled = yes

  # This example demonstrates an more specifically
  # configured Auto Interface, that only uses spe-
  # cific physical interfaces, and has a number of
  # other configuration options set.
  [[Default Interface]]
    type = AutoInterface
    enabled = yes

    # You can create multiple isolated Reticulum
    # networks on the same physical LAN by
    # specifying different Group IDs.
    group_id = reticulum

    # You can also choose the multicast address type:
    # temporary (default, Temporary Multicast Address)
    # or permanent (Permanent Multicast Address)
    multicast_address_type = permanent

    # You can also select specifically which
    # kernel networking devices to use.
    devices = wlan0,eth1

    # Or let AutoInterface use all suitable
    # devices except for a list of ignored ones.
    ignored_devices = tun0,eth0


If you are connected to the Internet with IPv6, and your provider will route
IPv6 multicast, you can potentially configure the Auto Interface to globally
autodiscover other Reticulum nodes within your selected Group ID. You can specify
the discovery scope by setting it to one of ``link``, ``admin``, ``site``,
``organisation`` or ``global``.

.. code:: ini
  
  [[Default Interface]]
    type = AutoInterface
    enabled = yes

    # Configure global discovery

    group_id = custom_network_name
    discovery_scope = global

    # Other configuration options

    discovery_port = 48555
    data_port = 49555


.. _interfaces-backbone:

Backbone Interface
====================

The Backbone interface is a very fast and resource efficient interface type, primarily
intended for interconnecting Reticulum instances over many different types of mediums.
It uses a kernel-event I/O backend, and can handle thousands of interfaces and/or clients
with relatively low system resource utilisation. **This interface type is currently only
supported on Linux and Android**.

.. note::
  The Backbone Interface is fully compatible with the ``TCPServerInterface`` and ``TCPClientInterface``
  types, and they can be used interchangably, and cross-connect with each other. On systems that support
  ``BackboneInterface``, it is generally recommended to use it, unless you need specific options or
  features that the TCP server and client interfaces provide.

While the goal is to support *all* socket types and I/O devices provided by the underlying
operating system, the initial release only provides support for TCP connections over IPv4
and IPv6.

For all types of connections over a ``BackboneInterface``, Reticulum will gracefully
handle intermittency, link loss, and connections that come and go.

Listeners
---------

The following examples illustrates various ways to set up ``BackboneInterface`` listeners.

.. code:: ini

  # This example demonstrates a backbone interface
  # that listens for incoming connections on the
  # specified IP address and port number.
  [[Backbone Listener]]
    type = BackboneInterface
    enabled = yes    
    listen_on = 0.0.0.0
    port = 4242

  # Alternatively you can bind to a specific IP
  [[Backbone Listener]]
    type = BackboneInterface
    enabled = yes    
    listen_on = 10.0.0.88
    port = 4242

  # Or a specific network device
  [[Backbone Listener]]
    type = BackboneInterface
    enabled = yes
    device = eth0
    port = 4242

If you are using the interface on a device which has both IPv4 and IPv6 addresses available,
you can use the ``prefer_ipv6`` option to bind to the IPv6 address:

.. code:: ini

  # This example demonstrates a backbone interface
  # listening on the IPv6 address of a specified
  # kernel networking device.
  [[Backbone Listener]]
    type = BackboneInterface
    enabled = yes
    prefer_ipv6 = yes
    device = eth0
    port = 4242

To use the ``BackboneInterface`` over `Yggdrasil <https://yggdrasil-network.github.io/>`_, you
can simply specify the Yggdrasil ``tun`` device and a listening port, like so:

.. code:: ini

  # This example demonstrates a backbone interface
  # listening for connections over Yggdrasil.
  [[Yggdrasil Backbone Interface]]
    type = BackboneInterface
    enabled = yes
    device = tun0
    port = 4343

Connecting Remotes
------------------
The following examples illustrates various ways to connect to remote ``BackboneInterface`` listeners.
As noted above, ``BackboneInterface`` interfaces can also connect to remote ``TCPServerInterface``,
and as such these interface types can be used interchangably.

.. code:: ini

  # Here's an example of a backbone interface that
  # connects to a remote listener.
  [[Backbone Remote]]
    type = BackboneInterface
    enabled = yes
    remote = amsterdam.connect.reticulum.network
    target_port = 4251

To connect to remotes over `Yggdrasil <https://yggdrasil-network.github.io/>`_, simply
specify the target Yggdrasil IPv6 address and port, like so:

.. code:: ini

  [[Yggdrasil Remote]]
      type = BackboneInterface
      enabled = yes
      target_host = 201:5d78:af73:5caf:a4de:a79f:3278:71e5
      target_port = 4343

Automated Blocking
------------------
Listener instances of ``BackboneInterface`` will automatically block fast-flapping clients,
that repeatedly connect for a short amount of time, and then disconnect. Such behavior usually
occurs from clients trying to spam the network with announces or path requests, by connecting, dumping
a massive amount of requests, and then disconnecting in an attempt to bypass rate limits.

While such bypass attempts only have very limited effect on the amount of spam actually dumped (ingress limits
trigger immediately once a client exceeds rate limits), the behavior is often seen anyways, and
causes log noise and needless interface rotation. The fast-flapping block ensures such clients
are never allocated an interface on the transport instance.

Another common cause can simply be clients using implementations that are broken, or automated
scanning tools attempting to connect to the instance.

.. code:: ini

  [[Backbone Listener]]
    type = BackboneInterface
    enabled = yes    
    listen_on = 0.0.0.0
    port = 4242

    # Whether to enable blocking
    block_fast_flapping = yes

    # How long an IP address stays
    # blocked, in minutes. Set to
    # 12 hours by default.
    fast_flapping_block_time = 720

    # The minimum time, in seconds,
    # an interface must stay connected
    # to be considered not fast-flapping.
    fast_flapping_threshold = 20

    # Amount of fast flaps a remote
    # IP can perform before having
    # blocking triggered.
    fast_flapping_grace = 5

The configuration options listed in the example above are the *default values*, and you do
not need to add them for automated blocking to work, but you can use them to change the
behavior from the defaults, if necessary.

.. _interfaces-tcps:

TCP Server Interface
====================

The TCP Server interface is suitable for allowing other peers to connect over
the Internet or private IPv4 and IPv6 networks. When a TCP server interface has been
configured, other Reticulum peers can connect to it with a TCP Client interface.

.. code:: ini

  # This example demonstrates a TCP server interface.
  # It will listen for incoming connections on all IP
  # interfaces on port 4242.  
  [[TCP Server Interface]]
    type = TCPServerInterface
    enabled = yes
    listen_ip = 0.0.0.0
    listen_port = 4242

  # Alternatively you can bind to a specific IP
  [[TCP Server Interface]]
    type = TCPServerInterface
    enabled = yes
    listen_ip = 10.0.0.88
    listen_port = 4242

  # Or a specific network device
  [[TCP Server Interface]]
    type = TCPServerInterface
    enabled = yes    
    device = eth0
    listen_port = 4242

If you are using the interface on a device which has both IPv4 and IPv6 addresses available,
you can use the ``prefer_ipv6`` option to bind to the IPv6 address:

.. code:: ini

  # This example demonstrates a TCP server interface.
  # It will listen for incoming connections on the
  # specified IP address and port number.
  
  [[TCP Server Interface]]
    type = TCPServerInterface
    enabled = yes
    prefer_ipv6 = True
    device = eth0
    port = 4242

To use the TCP Server Interface over `Yggdrasil <https://yggdrasil-network.github.io/>`_, you
can simply specify the Yggdrasil ``tun`` device and a listening port, like so:

.. code:: ini

  [[Yggdrasil TCP Server Interface]]
    type = TCPServerInterface
    enabled = yes
    device = tun0
    listen_port = 4343

.. note::
   The TCP interfaces support tunneling over I2P, but to do so reliably,
   you must use the i2p_tunneled option:

.. code::

  [[TCP Server on I2P]]
    type = TCPServerInterface
    enabled = yes
    listen_ip = 127.0.0.1
    listen_port = 5001
    i2p_tunneled = yes

In almost all cases, it is easier to use the dedicated ``I2PInterface``, but for complete
control, and using I2P routers running on external systems, this option also exists.

.. _interfaces-tcpc:

TCP Client Interface
====================

To connect to a TCP server interface, you can use the TCP client
interface. Many TCP Client interfaces from different peers can connect to the
same TCP Server interface at the same time.

The TCP interface types can also tolerate intermittency in the IP link layer.
This means that Reticulum will gracefully handle IP links that go up and down,
and restore connectivity after a failure, once the other end of a TCP interface reappears.

.. code:: ini

  # Here's an example of a TCP Client interface. The
  # target_host can be a hostname or an IPv4 or IPv6 address.
  [[TCP Client Interface]]
    type = TCPClientInterface
    enabled = yes
    target_host = 127.0.0.1
    target_port = 4242

To use the TCP Client Interface over `Yggdrasil <https://yggdrasil-network.github.io/>`_, simply
specify the target Yggdrasil IPv6 address and port, like so:

.. code:: ini

  [[Yggdrasil TCP Client Interface]]
      type = TCPClientInterface
      enabled = yes
      target_host = 201:5d78:af73:5caf:a4de:a79f:3278:71e5
      target_port = 4343

It is also possible to use this interface type to connect via other programs
or hardware devices that expose a KISS interface on a TCP port, for example
software-based soundmodems. To do this, use the ``kiss_framing`` option:

.. code:: ini

  # Here's an example of a TCP Client interface that connects
  # to a software TNC soundmodem on a KISS over TCP port.

  [[TCP KISS Interface]]
    type = TCPClientInterface
    enabled = yes
    kiss_framing = True
    target_host = 127.0.0.1
    target_port = 8001
    fixed_mtu = 500

**Caution!** Only use the KISS framing option when connecting to external devices
and programs like soundmodems and similar over TCP. When using the
``TCPClientInterface`` in conjunction with the ``TCPServerInterface`` you should
never enable ``kiss_framing``, since this will disable internal reliability and
recovery mechanisms that greatly improves performance over unreliable and
intermittent TCP links.

For KISS devices that need only supports a particular MTU, you can use the
``fixed_mtu`` option.

.. note::
   The TCP interfaces support tunneling over I2P, but to do so reliably,
   you must use the i2p_tunneled option:

.. code:: ini

  [[TCP Client over I2P]]
      type = TCPClientInterface
      enabled = yes
      target_host = 127.0.0.1
      target_port = 5001
      i2p_tunneled = yes


.. _interfaces-udp:

UDP Interface
=============

A UDP interface can be useful for communicating over IP networks, both
private and the internet. It can also allow broadcast communication
over IP networks, so it can provide an easy way to enable connectivity
with all other peers on a local area network.

.. warning::
   Using broadcast UDP traffic has performance implications,
   especially on WiFi. If your goal is simply to enable easy communication
   with all peers in your local Ethernet broadcast domain, the
   :ref:`Auto Interface` performs *much* better, and is even
   easier to use.

.. code:: ini

  # This example enables communication with other
  # local Reticulum peers over UDP.
  
  [[UDP Interface]]
    type = UDPInterface
    enabled = yes

    listen_ip = 0.0.0.0
    listen_port = 4242
    forward_ip = 255.255.255.255
    forward_port = 4242

    # The above configuration will allow communication
    # within the local broadcast domains of all local
    # IP interfaces.

    # Instead of specifying listen_ip, listen_port,
    # forward_ip and forward_port, you can also bind
    # to a specific network device like below.

    # device = eth0
    # port = 4242

    # Assuming the eth0 device has the address
    # 10.55.0.72/24, the above configuration would
    # be equivalent to the following manual setup.
    # Note that we are both listening and forwarding to
    # the broadcast address of the network segments.

    # listen_ip = 10.55.0.255
    # listen_port = 4242
    # forward_ip = 10.55.0.255
    # forward_port = 4242

    # You can of course also communicate only with
    # a single IP address

    # listen_ip = 10.55.0.15
    # listen_port = 4242
    # forward_ip = 10.55.0.16
    # forward_port = 4242


.. _interfaces-i2p:

I2P Interface
=============

The I2P interface lets you connect Reticulum instances over the
`Invisible Internet Protocol <https://i2pd.website>`_. This can be
especially useful in cases where you want to host a globally reachable
Reticulum instance, but do not have access to any public IP addresses,
have a frequently changing IP address, or have firewalls blocking
inbound traffic.

Using the I2P interface, you will get a globally reachable, portable
and persistent I2P address that your Reticulum instance can be reached
at.

To use the I2P interface, you must have an I2P router running
on your system. The easiest way to achieve this is to download and
install the `latest release <https://github.com/PurpleI2P/i2pd/releases/latest>`_
of the ``i2pd`` package. For more details about I2P, see the
`geti2p.net website <https://geti2p.net/en/about/intro>`_.

When an I2P router is running on your system, you can simply add
an I2P interface to Reticulum:

.. code:: ini

  [[I2P]]
    type = I2PInterface
    enabled = yes
    connectable = yes

On the first start, Reticulum will generate a new I2P address for the
interface and start listening for inbound traffic on it. This can take
a while the first time, especially if your I2P router was also just
started, and is not yet well-connected to the I2P network. When ready,
you should see I2P base32 address printed to your log file. You can
also inspect the status of the interface using the ``rnstatus`` utility.

To connect to other Reticulum instances over I2P, just add a comma-separated
list of I2P base32 addresses to the ``peers`` option of the interface:

.. code:: ini

  [[I2P]]
    type = I2PInterface
    enabled = yes
    connectable = yes
    peers = 5urvjicpzi7q3ybztsef4i5ow2aq4soktfj7zedz53s47r54jnqq.b32.i2p

It can take anywhere from a few seconds to a few minutes to establish
I2P connections to the desired peers, so Reticulum handles the process
in the background, and will output relevant events to the log.

.. note::
   While the I2P interface is the simplest way to use
   Reticulum over I2P, it is also possible to tunnel the TCP server and
   client interfaces over I2P manually. This can be useful in situations
   where more control is needed, but requires manual tunnel setup through
   the I2P daemon configuration.

It is important to note that the two methods are *interchangably compatible*.
You can use the I2PInterface to connect to a TCPServerInterface that
was manually tunneled over I2P, for example. This offers a high degree
of flexibility in network setup, while retaining ease of use in simpler
use-cases.


.. _interfaces-rnode:

RNode LoRa Interface
====================

To use Reticulum over LoRa, the `RNode <https://unsigned.io/rnode/>`_ interface
can be used, and offers full control over LoRa parameters.

.. warning::
   Radio frequency spectrum is a legally controlled resource, and legislation
   varies widely around the world. It is your responsibility to be aware of any
   relevant regulation for your location, and to make decisions accordingly.

.. code:: ini

  # Here's an example of how to add a LoRa interface
  # using the RNode LoRa transceiver.

  [[RNode LoRa Interface]]
    type = RNodeInterface

    # Enable interface if you want use it!
    enabled = yes

    # Serial port for the device
    port = /dev/ttyUSB0

    # You can connect wirelessly to the
    # RNode device if it supports WiFi.

    # Connect by IP address
    # port = tcp://10.0.0.1

    # Or, connect by hostname
    # port = tcp://rnodef3b9.local

    # It is also possible to use BLE devices
    # instead of wired serial ports. The
    # target RNode must be paired with the
    # host device before connecting. BLE
    # devices can be connected by name,
    # BLE MAC address or by any available.
    
    # Connect to specific device by name
    # port = ble://RNode 3B87

    # Or by BLE MAC address
    # port = ble://F4:12:73:29:4E:89

    # Or connect to the first available,
    # paired device
    # port = ble://

    # Set frequency to 867.2 MHz
    frequency = 867200000

    # Set LoRa bandwidth to 125 KHz
    bandwidth = 125000

    # Set TX power to 7 dBm (5 mW)
    txpower = 7

    # Select spreading factor 8. Valid 
    # range is 7 through 12, with 7
    # being the fastest and 12 having
    # the longest range.
    spreadingfactor = 8

    # Select coding rate 5. Valid range
    # is 5 throough 8, with 5 being the
    # fastest, and 8 the longest range.
    codingrate = 5

    # You can configure the RNode to send
    # out identification on the channel with
    # a set interval by configuring the
    # following two parameters.
    
    # id_callsign = MYCALL-0
    # id_interval = 600

    # For certain homebrew RNode interfaces
    # with low amounts of RAM, using packet
    # flow control can be useful. By default
    # it is disabled.
    
    # flow_control = False

    # It is possible to limit the airtime
    # utilisation of an RNode by using the
    # following two configuration options.
    # The short-term limit is applied in a
    # window of approximately 15 seconds,
    # and the long-term limit is enforced
    # over a rolling 60 minute window. Both
    # options are specified in percent.
    
    # airtime_limit_long = 1.5
    # airtime_limit_short = 33


.. _interfaces-rnode-multi:

RNode Multi Interface
=====================

For RNodes that support multiple LoRa transceivers, the RNode
Multi interface can be used to configure sub-interfaces individually.

.. warning::
   Radio frequency spectrum is a legally controlled resource, and legislation
   varies widely around the world. It is your responsibility to be aware of any
   relevant regulation for your location, and to make decisions accordingly.

.. code:: ini

  # Here's an example of how to add an RNode Multi interface
  # using the RNode LoRa transceiver.

  [[RNode Multi Interface]]
  type = RNodeMultiInterface

  # Enable interface if you want to use it!
  enabled = yes

  # Serial port for the device
  port = /dev/ttyACM0

  # You can configure the RNode to send
  # out identification on the channel with
  # a set interval by configuring the
  # following two parameters.

  # id_callsign = MYCALL-0
  # id_interval = 600

    # A subinterface
    [[[High Datarate]]]
      # Subinterfaces can be enabled and disabled in of themselves
      enabled = yes

      # Set frequency to 2.4GHz
      frequency = 2400000000

      # Set LoRa bandwidth to 1625 KHz
      bandwidth = 1625000

      # Set TX power to 0 dBm (0.12 mW)
      txpower = 0

      # The virtual port, only the manufacturer
      # or the person who wrote the board config
      # can tell you what it will be for which
      # physical hardware interface
      vport = 1

      # Select spreading factor 5. Valid
      # range is 5 through 12, with 5 
      # being the fastest and 12 having
      # the longest range.
      spreadingfactor = 5

      # Select coding rate 5. Valid range
      # is 5 throough 8, with 5 being the
      # fastest, and 8 the longest range.
      codingrate = 5

      # It is possible to limit the airtime
      # utilisation of an RNode by using the
      # following two configuration options.
      # The short-term limit is applied in a
      # window of approximately 15 seconds,
      # and the long-term limit is enforced
      # over a rolling 60 minute window. Both
      # options are specified in percent.

      # airtime_limit_long = 100
      # airtime_limit_short = 100

    [[[Low Datarate]]]
      # Subinterfaces can be enabled and disabled in of themselves
      enabled = yes

      # Set frequency to 865.6 MHz
      frequency = 865600000

      # The virtual port, only the manufacturer
      # or the person who wrote the board config
      # can tell you what it will be for which
      # physical hardware interface
      vport = 0

      # Set LoRa bandwidth to 125 KHz
      bandwidth = 125000

      # Set TX power to 0 dBm (0.12 mW)
      txpower = 0

      # Select spreading factor 7. Valid
      # range is 5 through 12, with 5 
      # being the fastest and 12 having
      # the longest range.
      spreadingfactor = 7

      # Select coding rate 5. Valid range
      # is 5 throough 8, with 5 being the
      # fastest, and 8 the longest range.
      codingrate = 5

      # It is possible to limit the airtime
      # utilisation of an RNode by using the
      # following two configuration options.
      # The short-term limit is applied in a
      # window of approximately 15 seconds,
      # and the long-term limit is enforced
      # over a rolling 60 minute window. Both
      # options are specified in percent.

      # airtime_limit_long = 100
      # airtime_limit_short = 100

.. _interfaces-serial:

Serial Interface
================

Reticulum can be used over serial ports directly, or over any device with a
serial port, that will transparently pass data. Useful for communicating
directly over a wire-pair, or for using devices such as data radios and lasers.

.. code:: ini

  [[Serial Interface]]
    type = SerialInterface
    enabled = yes

    # Serial port for the device
    port = /dev/ttyUSB0

    # Set the serial baud-rate and other
    # configuration parameters.
    speed = 115200
    databits = 8
    parity = none
    stopbits = 1

.. _interfaces-pipe:

Pipe Interface
==============

Using this interface, Reticulum can use any program as an interface via `stdin` and
`stdout`. This can be used to easily create virtual interfaces, or to interface with
custom hardware or other systems.

.. code:: ini

  [[Pipe Interface]]
    type = PipeInterface
    enabled = yes

    # External command to execute
    command = netcat -l 5757

    # Optional respawn delay, in seconds
    respawn_delay = 5

Reticulum will write all packets to `stdin` of the ``command`` option, and will
continuously read and scan its `stdout` for Reticulum packets. If ``EOF`` is reached,
Reticulum will try to respawn the program after waiting for ``respawn_interval`` seconds.

.. _interfaces-kiss:

KISS Interface
==============

With the KISS interface, you can use Reticulum over a variety of packet
radio modems and TNCs, including `OpenModem <https://unsigned.io/openmodem/>`_.
KISS interfaces can also be configured to periodically send out beacons
for station identification purposes.

.. warning::
   Radio frequency spectrum is a legally controlled resource, and legislation
   varies widely around the world. It is your responsibility to be aware of any
   relevant regulation for your location, and to make decisions accordingly.

.. code:: ini

  [[Packet Radio KISS Interface]]
    type = KISSInterface
    enabled = yes

    # Serial port for the device
    port = /dev/ttyUSB1

    # Set the serial baud-rate and other
    # configuration parameters.
    speed = 115200    
    databits = 8
    parity = none
    stopbits = 1

    # Set the modem preamble.
    preamble = 150

    # Set the modem TX tail.
    txtail = 10

    # Configure CDMA parameters. These
    # settings are reasonable defaults.
    persistence = 200
    slottime = 20

    # You can configure the interface to send
    # out identification on the channel with
    # a set interval by configuring the
    # following two parameters. The KISS
    # interface will only ID if the set
    # interval has elapsed since it's last
    # actual transmission. The interval is
    # configured in seconds.
    # This option is commented out and not
    # used by default.
    # id_callsign = MYCALL-0
    # id_interval = 600

    # Whether to use KISS flow-control.
    # This is useful for modems that have
    # a small internal packet buffer, but
    # support packet flow control instead.
    flow_control = false

.. _interfaces-ax25:

AX.25 KISS Interface
====================

If you're using Reticulum on amateur radio spectrum, you might want to
use the AX.25 KISS interface. This way, Reticulum will automatically
encapsulate it's traffic in AX.25 and also identify your stations
transmissions with your callsign and SSID. 

Only do this if you really need to! Reticulum doesn't need the AX.25
layer for anything, and it incurs extra overhead on every packet to
encapsulate in AX.25.

A more efficient way is to use the plain KISS interface with the
beaconing functionality described above.

.. warning::
   Radio frequency spectrum is a legally controlled resource, and legislation
   varies widely around the world. It is your responsibility to be aware of any
   relevant regulation for your location, and to make decisions accordingly.

.. code:: ini

  [[Packet Radio AX.25 KISS Interface]]
    type = AX25KISSInterface

    # Set the station callsign and SSID
    callsign = NO1CLL
    ssid = 0

    # Enable interface if you want use it!
    enabled = yes

    # Serial port for the device
    port = /dev/ttyUSB2

    # Set the serial baud-rate and other
    # configuration parameters.
    speed = 115200    
    databits = 8
    parity = none
    stopbits = 1

    # Set the modem preamble. A 150ms
    # preamble should be a reasonable
    # default, but may need to be
    # increased for radios with slow-
    # opening squelch and long TX/RX
    # turnaround
    preamble = 150

    # Set the modem TX tail. In most
    # cases this should be kept as low
    # as possible to not waste airtime.
    txtail = 10

    # Configure CDMA parameters. These
    # settings are reasonable defaults.
    persistence = 200
    slottime = 20

    # Whether to use KISS flow-control.
    # This is useful for modems with a
    # small internal packet buffer.
    flow_control = false

.. _interfaces-discoverable:

Discoverable Interfaces
=======================

Reticulum includes a powerful system for publishing your local interfaces to the wider network, allowing other peers to :ref:`discover, validate, and automatically connect to them`. This feature is particularly useful for creating decentralized networks where peers can dynamically find entrypoints, such as public Internet gateways or local radio access points, without relying on static configuration files or centralized directories.

When an interface is made **discoverable**, your Reticulum instance will periodically broadcast an announce packet containing the connection details and parameters required for other peers to establish a connection. These announces are propagated over the network using the standard Reticulum announce mechanism using the ``rnstransport.discovery.interface`` destination type.

.. note::
   To use the interface discovery functionality, the ``LXMF`` module must be installed in your Python environment. You can install it using pip:

   .. code:: sh

     pip install lxmf


Enabling Discovery
------------------

Interface discovery is enabled on a per-interface basis. To make a specific interface discoverable, you must add the ``discoverable`` option to that interface's configuration block and set it to ``yes``.

.. code:: ini

  [[My Public Gateway]]
    type = BackboneInterface
    ...
    discoverable = yes

Once enabled, Reticulum will automatically handle the generation, signing, stamping, and broadcasting of the discovery announces. It is not *required* to enable Transport to publish interface discovery information, but for most use cases where you want others to connect to you, you will likely want ``enable_transport`` set to ``yes`` in the ``[reticulum]`` section of your configuration.


Discovery Parameters
--------------------

When ``discoverable`` is enabled, a variety of additional options become available to control how the interface is presented to the network. These parameters allow you to fine-tune the metadata, security requirements, and visibility of your interface.

**Basic Metadata**

``discovery_name``
  A human-readable name for the interface. This name will be displayed to users on remote systems when they list discovered interfaces. If not specified, the interface name (the section header) will be used.

``announce_interval``
  The interval in minutes between successive discovery announces for this interface. Default is 360 minutes (6 hours). For stable, long-running infrastructure, higher intervals (12 to 22 hours) are usually sufficient and reduce network load. Minimum allowed value is 5 minutes (but expect to have your announces throttled if using intervals below one hour).

**Connectivity Specification**

``reachable_on``
  Specifies the address that remote peers should use to connect to this interface. 
  
  *   For TCP and Backbone interfaces, this is typically the public IP address or hostname. Do not include the port, this is fetched automatically from the interface.
  *   For I2P interfaces, this is usually the I2P ``b32`` address. This value is fetched automatically from the ``I2PInterface`` once it is up and connected to the I2P network, so you should not set this manually, unless you absolutely know what you're doing.
  
  **Dynamic Resolution:** This option also accepts a path to an external executable script or binary. If a path is provided, Reticulum will execute the script and use its ``stdout`` as the reachability address. This is useful for devices behind dynamic DNS, NATs, or complex cloud environments where the external IP is not known locally. The script must simply print the address to stdout and exit.

.. note::
  When using an executable script for ``reachable_on``, Reticulum expects the script to output only the IP address or hostname to ``stdout``, followed by a newline character. Any additional output or errors may cause the resolution to fail. Ensure the script has executable permissions and is robust against temporary network failures.

A minimal example of a script that resolves the externally available, public IP of an internet-connected system could look like this:

.. code:: bash

  #!/bin/bash
  curl -s ip.me
  exit $?

On a real system, you should make the script robust enough to deal with intermittent Internet or service failures, such that the script *always* returns a sensible value, or if not possible at least exits with a non-zero exit return code, so Reticulum knows the output is invalid.

**Security & Cost**

``discovery_stamp_value``
  Defines the proof-of-work difficulty for the cryptographic stamp included in the announce. This value acts as a cost barrier to prevent network flooding. The default value is ``14``. Increasing this value makes it computationally more expensive to generate an announce, which can be useful to prevent spam on very large networks, but it also increases CPU load on your system when generating announces. Stamps are cached, and only generated if interface information changes, or at instance restart. If you have the computational resources, it is generally advisable to use as high a stamp value as possible.

**Privacy & Encryption**

``discovery_encrypt``
  If set to ``yes``, the discovery announce payload will be encrypted. To decrypt the announce, remote peers must possess the *network identity* configured for your instance (see ``network_identity`` in the ``[reticulum]`` section). This allows you to publish private interfaces that are only discoverable to specific trusted networks.

.. important::
   If you enable ``discovery_encrypt`` but do not configure a valid ``network_identity`` in the ``[reticulum]`` section of your configuration, Reticulum will abort the interface discovery announce. Encryption requires a valid network identity key to function.

``publish_ifac``
  If set to ``yes``, the Interface Access Code (IFAC) name and passphrase for this interface will be included in the discovery announce. This allows peers to automatically configure the correct authentication parameters when connecting to the interface.

**Physical Location**

``latitude``, ``longitude``, ``height``
  Optional physical coordinates for the interface. These are useful for mapping discovered interfaces geographically or for clients to automatically select the nearest access point. Coordinates should be in decimal degrees, height in meters above mean sea level.

``location_cmd``
  Optional path to executable or script that returns the physical coordinates for the interface. This can be used instead of manually setting ``latitude``, ``longitude`` and ``height``. Reticulum expects the script to output the location data to ``stdout`` on a single line, separated by commas, with values as floating point numbers in the format ``LAT, LON, HEIGHT``. Coordinates should be in decimal degrees, height in meters above mean sea level.

.. note::
   The height value for interface discovery is specified in *height above mean sea level*! This is the geoid-corrected height value, and is distinct from GPS altitude. If you manually specify height, it will typically be set to what you find on a topographical map. If you are using a script to output the location data, make sure that you are using the geoid-corrected altitude, not height above the GPS ellipsoid. Most GPS systems will make both figures available.

**Radio Parameters**

For physical radio interfaces like ``RNodeInterface`` or ``KISSInterface``, the following optional parameters allow you to broadcast the operating frequency and characteristics, allowing clients to verify compatibility before connecting:

``discovery_frequency``
  The operating frequency in Hz. Auto-configured on RNode interfaces. Necessary on KISS-based radio interfaces and ``TCPClientInterfaces`` connecting to radio modems.

``discovery_bandwidth``
  The signal bandwidth in Hz. Auto-configured on RNode interfaces. Useful on KISS-based radio interfaces and ``TCPClientInterfaces`` connecting to radio modems.

``discovery_modulation``
  The modulation type or scheme. Auto-configured on RNode interfaces, but highly advisable to include on other radio-based interfaces.


Interface Modes
---------------

When you enable discovery on an interface, Reticulum enforces certain interface modes to ensure the interface is actually useful for remote peers. 

If an interface is configured as ``discoverable``, but its mode is not explicitly set to ``gateway`` (for server-style interfaces like ``BackboneInterface`` or ``TCPServerInterface``) or ``access_point`` (for radio interfaces like ``RNodeInterface``), Reticulum will automatically configure the appropriate mode and log a notice. 

For example, if you enable discovery on a ``RNodeInterface`` without specifying the mode, Reticulum will automatically set it to ``access_point`` mode.

Security Considerations
-----------------------

When making interfaces discoverable, you are effectively broadcasting an invitation to connect to your system. It is important to understand the security implications of the configuration options you choose.

**Publishing Credentials**

If you enable ``publish_ifac = yes``, your interface's authentication passphrase will be included in the announce. If you are operating a public network and want anyone to connect, this is acceptable. However, if you wish to restrict access to a specific group of users, you **must** enable ``discovery_encrypt = yes``. This ensures that only peers possessing the correct ``network_identity`` can decode the passphrase.

**Topology Exposure**

A discoverable interface announces its presence, location (if configured), and capabilities to the network. Even if the connection details are encrypted, the *fact* that a connectable node exists within a certain network becomes public information. In high-security or scenarios requiring operational secrecy, consider the implications of advertising your infrastructure's existence.

Example Configuration
---------------------

Below is an example configuration for a public backbone gateway. This configuration publishes a high-value, publicly discoverable interface, that anyone can connect to.

.. code:: ini

  [[My Public Gateway]]
    type = BackboneInterface
    mode = gateway
    listen_on = 0.0.0.0
    port = 4242

    # Enable Discovery
    discoverable = yes

    # Interface Details
    discovery_name = Region A Public Entrypoint
    announce_interval = 720

    # Use external script to resolve dynamic IP
    reachable_on = /usr/local/bin/get_external_ip.sh

    # Generate high stamp value
    discovery_stamp_value = 24

    # Optional location data
    latitude = 51.99714
    longitude = -0.74195
    height = 15

The next example create an encrypted discovery-enabled interface, requiring a specific network identity to decode, and includes IFAC credentials for seamless authentication.

.. code:: ini

  [[My Private Gateway]]
    type = BackboneInterface
    mode = gateway
    listen_on = 0.0.0.0
    port = 5858
    network_name = internal_1
    passphrase = Mevpekyafshak5Wr

    # Enable Discovery
    discoverable = yes

    # Interface Details
    discovery_name = Region A Private Backbone
    announce_interval = 720

    # Use external script to resolve dynamic IP
    reachable_on = /usr/local/bin/get_external_ip.sh

    # Target stamp value
    discovery_stamp_value = 22

    # Encrypt announces for our network only
    discovery_encrypt = yes

    # Include credentials so trusted
    # peers can connect automatically
    publish_ifac = yes

    # Optional location data
    latitude = 34.06915
    longitude = -118.44318
    height = 15

In the ``[reticulum]`` section of your configuration, you would define the network identity used for encryption as follows:

.. code:: ini

  [reticulum]
  ...
  # The identity used to sign/encrypt discovery announces
  network_identity = ~/.reticulum/storage/identities/my_network_identity
  ...

With these configuration options applied, your Reticulum instance will actively participate in the network's discovery ecosystem. Other peers running Reticulum with discovery enabled will be able to see your interface, validate its cryptographic stamp, and (depending on their configuration) automatically connect to it.

For information on how to use these discovered interfaces and configure your system to auto-connect to them, refer to the :ref:`Discovering Interfaces` chapter.

.. _interfaces-options:

Common Interface Options
========================

A number of general configuration options are available on most interfaces.
These can be used to control various aspects of interface behaviour.


 * | The ``enabled`` option tells Reticulum whether or not
     to bring up the interface. Defaults to ``False``. For any
     interface to be brought up, the ``enabled`` option
     must be set to ``True`` or ``Yes``.

 * | The ``mode`` option allows selecting the high-level behaviour
     of the interface from a number of options.

     - The default value is ``full``. In this mode, all discovery,
       meshing and transport functionality is available.

     - In the ``access_point`` (or shorthand ``ap``) mode, the
       interface will operate as a network access point. In this
       mode, announces will not be automatically broadcasted on
       the interface, and paths to destinations on the interface
       will have a much shorter expiry time. This mode is useful
       for creating interfaces that are mostly quiet, unless when
       someone is actually using them. An example of this could
       be a radio interface serving a wide area, where users are
       expected to connect momentarily, use the network, and then
       disappear again.

     - See the :ref:`Interface Modes` section
       below for a reference on additional modes.

 * | The ``gravity`` option specifies the pathing affinity of an interface.
     If not set specifically, and unless otherwise configured by
     ``default_gravity`` or ``autoconnect_interface_gravity``,
     it defaults to ``0``. Positive values increase pathing affinity,
     and negative values decrease it.

 * | The ``outgoing`` option sets whether an interface is allowed
     to transmit. Defaults to ``True``. If set to ``False`` or ``No``
     the interface will only receive data, and never transmit.

 * | The ``network_name`` option sets the virtual network name for
     the interface. This allows multiple separate network segments
     to exist on the same physical channel or medium.

 * | The ``passphrase`` option sets an authentication passphrase on
     the interface. This option can be used in conjunction with the
     ``network_name`` option, or be used alone.

 * | The ``ifac_size`` option allows customising the length of the
     Interface Authentication Codes carried by each packet on named
     and/or authenticated network segments. It is set by default to
     a size suitable for the interface in question, but can be set
     to a custom size between 8 and 512 bits by using this option.
     In normal usage, this option should not be changed from the
     default.

 * | The ``announce_cap`` option lets you configure the maximum
     bandwidth to allocate, at any given time, to propagating
     announces and other network upkeep traffic. It is configured at
     2% by default, and should normally not need to be changed. Can
     be set to any value between ``1`` and ``100``.

     *If an interface exceeds its announce cap, it will queue announces
     for later transmission. Reticulum will always prioritise propagating
     announces from nearby nodes first. This ensures that the local
     topology is prioritised, and that slow networks are not overwhelmed
     by interconnected fast networks.*

     *Destinations that are rapidly re-announcing will be down-prioritised
     further. Trying to get "first-in-line" by announce spamming will have
     the exact opposite effect: Getting moved to the back of the queue every
     time a new announce from the excessively announcing destination is received.*

     *This means that it is always beneficial to select a balanced
     announce rate, and not announce more often than is actually necesarry
     for your application to function.*

 * | The ``bitrate`` option configures the interface bitrate.
     Reticulum will use interface speeds reported by hardware, or
     try to guess a suitable rate when the hardware doesn't report
     any. In most cases, the automatically found rate should be
     sufficient, but it can be configured by using the ``bitrate``
     option, to set the interface speed in *bits per second*.


 * | The ``bootstrap_only`` option designates an interface as a temporary
     bridge for initial connectivity. If this option is enabled, the
     interface will be monitored and automatically detached once the
     number of auto-connected interfaces reaches the limit configured by
     ``autoconnect_discovered_interfaces``. This is particularly useful
     for using a slow or expensive connection (such as a single LoRa
     link or a remote TCP tunnel) solely to discover better local
     infrastructure, which then supersedes the bootstrap interface.


 * | The ``recursive_prs`` option allows you to enable recursive path
     discovery on an interface regardless of its configured interface
     mode. When this option is enabled, Reticulum will attempt to
     recursively discover paths for path requests received on this
     interface.


 * | The ``announces_from_internal`` option controls whether any
     announces *received on* an ``internal`` mode interface will
     propagate *out* on the interface this option is set on. Note
     that this controls *announce propagation*; even if announces
     do not propagate out when received, paths to destinations on
     ``internal`` mode interfaces may still be resolvable by means
     of path requests.


 * | To allow an interface that would *otherwise not* propagate
     announces to ``internal`` mode interfaces to do so, you can
     configure the ``announces_to_internal`` option to ``True``.

.. _interfaces-modes:

Interface Modes
===============

The optional ``mode`` setting is available on all interfaces, and allows
selecting the high-level behaviour of the interface from a number of modes.
These modes affect how Reticulum selects paths in the network, how announces
are propagated, how long paths are valid and how paths are discovered.

Configuring modes on interfaces is **not** strictly necessary, but can be useful
when building or connecting to more complex networks. If your Reticulum
instance is not running a Transport Node, it is rarely useful to configure
interface modes, and in such cases interfaces should generally be left in
the default mode.

 * | The default mode is ``full``. In this mode, all discovery,
     meshing and transport functionality is activated.

 * | The ``gateway`` mode (or shorthand ``gw``) also has all
     discovery, meshing and transport functionality available,
     but will additionally try to discover unknown paths on
     behalf of other nodes residing on the ``gateway`` interface.
     If Reticulum receives a path request for an unknown
     destination, from a node on a ``gateway`` interface, it
     will try to discover this path via all other active interfaces,
     and forward the discovered path to the requestor if one is
     found.

   | If you want to allow other nodes to widely resolve paths or connect
     to a network via an interface, it might be useful to put it in this
     mode. By creating a chain of ``gateway`` interfaces, other
     nodes will be able to immediately discover paths to any
     destination along the chain.

   | *Please note!* It is the interface *facing the clients* that
     must be put into ``gateway`` mode for this to work, not
     the interface facing the wider network (for this, the ``boundary``
     mode can be useful, though).

 * | In the ``access_point`` (or shorthand ``ap``) mode, the
     interface will operate as a network access point. In this
     mode, announces will not be automatically broadcasted on
     the interface, and paths to destinations on the interface
     will have a much shorter expiry time. In addition, path
     requests from clients on the access point interface will
     be handled in the same way as the ``gateway`` interface.

   | This mode is useful for creating interfaces that remain
     quiet, until someone actually starts using them. An example
     of this could be a radio interface serving a wide area,
     where users are expected to connect momentarily, use the
     network, and then disappear again.

 * | The ``roaming`` mode should be used on interfaces that are
     roaming (physically mobile), seen from the perspective of
     other nodes in the network. As an example, if a vehicle is
     equipped with an external LoRa interface, and an internal,
     WiFi-based interface, that serves devices that are moving
     *with* the vehicle, the external LoRa interface should be
     configured as ``roaming``, and the internal interface can
     be left in the default mode. With transport enabled, such
     a setup will allow all internal devices to reach each other,
     and all other devices that are available on the LoRa side
     of the network, when they are in range. Devices on the LoRa
     side of the network will also be able to reach devices
     internal to the vehicle, when it is in range. Paths via
     ``roaming`` interfaces also expire faster.

 * | The purpose of the ``boundary`` mode is to specify interfaces
     that establish connectivity with network segments that are
     significantly different than the one this node exists on.
     As an example, if a Reticulum instance is part of a LoRa-based
     network, but also has a high-speed connection to a
     public Transport Node available on the Internet, the interface
     connecting over the Internet should be set to ``boundary`` mode.

 * | The ``internal`` mode designates interfaces that belong to a
     network different from any marked as ``boundary``. Announces from
     a ``boundary`` interface will not propagate to interfaces set as
     ``internal``, but announces *will* propagate from ``internal`` *to*
     ``boundary``. Devices on the ``internal`` side of the network will
     still be able to resolve paths to destinations across the boundary
     when needed, since recursive path requests are enabled for ``internal``
     mode interfaces by default.

For a table describing the impact of all modes on announce propagation,
please see the :ref:`Announce Propagation Rules` section.

.. _interfaces-announcerates:

Announce Rate Control
=====================

The built-in announce control mechanisms and the default ``announce_cap``
option described above are sufficient most of the time, but in some cases,
especially on fast interfaces, or when connecting to large public networks,
it may be useful to control the target announce rate.

Using the ``announce_rate_target``, ``announce_rate_grace`` and ``announce_rate_penalty``
options, this can be done on a per-interface basis, or by setting instance-wide defaults.
When configured, this moderates the *rate at which received announces are
re-broadcasted to other interfaces*.

 * | The ``announce_rate_target`` option sets the minimum amount of time,
     in seconds, that should pass between received announces, for any one
     destination. As an example, setting this value to ``3600`` means that
     announces *received* on this interface will only be re-transmitted and
     propagated to other interfaces once every hour, no matter how often they
     are received.

 * | The optional ``announce_rate_grace`` defines the number of times a destination
     can violate the announce rate before the target rate is enforced.

 * | The optional ``announce_rate_penalty`` configures an extra amount of
     time that is added to the normal rate target. As an example, if a penalty
     of ``7200`` seconds is defined, once the rate target is enforced, the
     destination in question will only have its announces propagated every
     3 hours, until it lowers its actual announce rate to within the target.

You can also configure default announce rate parameters for all interfaces that
do not have these parameters set explicitly by setting the ``default_ar_target``
``default_ar_penalty`` and ``default_ar_grace`` options in the ``[reticulum]``
section of the configuration file. If any of these options are set, they will
automatically be applied to any interface if transport is enabled, and the
interface does not have the parameters set explicitly.

For auto-connected interfaces, sensible default announce rate control parameters
will **always** be set, even if the defaults are not configured explicitly, but
if you set the defaults, auto-connected interfaces will adhere to these as well.

These mechanisms, in conjunction with the ``annouce_cap`` mechanisms mentioned
above means that it is essential to select a balanced announce strategy for
your destinations. The more balanced you can make this decision, the easier
it will be for your destinations to make it into slower networks, or networks that
are many hops away.

Statistics and information about announce rates can be viewed using the
``rnpath -r`` and ``rnstatus -A`` commands.

It is important to note, that while there is no one right or wrong way to set up announce
rates, it should generally not be necessary to announce any kind of destination.
more often than once every few hours. Most applications can announce simply when
the application starts, and then only once every 6 hours or so.

If you're designing an application where you think you need to annonuce more
often than once an hour, you're most likely doing something wrong.

Slower networks will naturally tend towards using less frequent announces to
conserve bandwidth, while very fast networks can support applications that
need more frequent announces. Reticulum implements these mechanisms to ensure
that a large span of network types can seamlessly *co-exist* and interconnect.

.. _interfaces-ingress-control:

New Destination Rate Limiting
=============================

On public interfaces, where anyone may connect and announce new destinations,
it can be useful to control the rate at which announces for *new*  destinations are
processed.

If a large influx of announces for newly created or previously unknown destinations
occur within a short amount of time, Reticulum will place these announces on hold,
so that announce traffic for known and previously established destinations can
continue to be processed without interruptions.

After the burst subsides, and an additional waiting period has passed, the held
announces will be released at a slow rate, until the hold queue is cleared. This
also means, that should a node decide to connect to a public interface, announce
a large amount of bogus destinations, and then disconnect, these destination will
never make it into path tables and waste network bandwidth on retransmitted
announces.

.. note::
   It's important to remember that the ingress control works at the level of *individual
   sub-interfaces*. As an example, this means that one client on a :ref:`TCP Server Interface`
   cannot disrupt processing of incoming announces for other connected clients on the same
   :ref:`TCP Server Interface`. All other clients on the same interface
   will still have new announces processed without interruption.

By default, Reticulum will handle this automatically, and ingress announce
control will be enabled on interface where it is sensible to do so. It should
generally not be neccessary to modify the ingress control configuration,
but all the parameters are exposed for configuration if needed.

 * | The ``ingress_control`` option tells Reticulum whether or not
     to enable ingress control on the interface. Defaults to ``True``.

 * | The ``ic_new_time`` option configures how long (in seconds) an
     interface is considered newly spawned. Defaults to ``2*60*60`` seconds. This
     option is useful on publicly accessible interfaces that spawn new
     sub-interfaces when a new client connects. 

 * | The ``ic_burst_freq_new`` option sets the maximum announce ingress
     frequency for newly spawned interfaces. Defaults to ``3.5``
     announces per second.

 * | The ``ic_burst_freq`` option sets the maximum announce ingress
     frequency for other interfaces. Defaults to ``12`` announces
     per second.

     *If an interface exceeds its burst frequency, incoming announces
     for unknown destinations will be temporarily held in a queue, and
     not processed until later.*

 * | The ``ic_max_held_announces`` option sets the maximum amount of
     unique announces that will be held in the queue. Any additional
     unique announces will be dropped. Defaults to ``256`` announces.

 * | The ``ic_burst_hold`` option sets how much time (in seconds) must
     pass after the burst frequency drops below its threshold, for the
     announce burst to be considered cleared. Defaults to ``60``
     seconds.

 * | The ``ic_burst_penalty`` option sets how much time (in seconds) must
     pass after the burst is considered cleared, before held announces can
     start being released from the queue. Defaults to ``5*60``
     seconds.

 * | The ``ic_held_release_interval`` option sets how much time (in seconds)
     must pass between releasing each held announce from the queue. Defaults
     to ``30`` seconds.

All of the above settings can be configured both as instance-wide defaults
under the ``[reticulum]`` section of the configuration file, or on a per-
interface basis under the relevant interface configuration section.


Path Request Burst Control
==========================

In addition the announce controls for newly created destination, Reticulum will also 
monitor incoming path request activity, and enforce burst controls if per-client rates
exceed configured limits. Once path request burst control is activated on an
interface, path requests will no longer be propagated further on the network.
As with announce burst control, this happens on a per sub-interface basis. One
client connecting to a public gateway will not be able to disrupt path request
processing for other clients.

.. warning::
   Applications that send large amounts of unnecessary path requests will very
   quickly get rate limited by transport nodes, and the entire system they are
   running on will not be able to resolve any paths on the network, until the
   burst subsides and hold period expires. **Do not** write applications like
   this. Only request paths for destinations you need to communicate with.

By default, Reticulum will handle this automatically, and ingress path request
control will be enabled on interface where it is sensible to do so. It should
generally not be neccessary to modify the ingress control configuration,
but all the parameters are exposed for configuration if needed.

 * | The ``ingress_control`` option tells Reticulum whether or not
     to enable ingress control on the interface. Defaults to ``True``.

 * | The ``ic_new_time`` option configures how long (in seconds) an
     interface is considered newly spawned. Defaults to ``2*60*60`` seconds. This
     option is useful on publicly accessible interfaces that spawn new
     sub-interfaces when a new client connects.

 * | The ``ic_pr_burst_freq_new`` option sets the maximum path request
     ingress frequency for newly spawned interfaces. Defaults to ``3``
     path requests per second.

 * | The ``ic_pr_burst_freq`` option sets the maximum path request
     ingress frequency for other interfaces. Defaults to ``8`` path requests
     per second.

     *If an interface exceeds its burst frequency, incoming path requests
     from that system will not traverse the network further.*

 * | The ``egress_control`` option enables hard-limiting path request egress
     control per-interface. Defaults to ``False``

 * | The ``ec_pr_freq`` option sets the hard limit for outbound path requests
     per second on a given interface.

All of the above settings can be configured both as instance-wide defaults
under the ``[reticulum]`` section of the configuration file, or on a per-
interface basis under the relevant interface configuration section.

---

## File: docs/source/networks.rst

.. _networks-main:

*****************
Building Networks
*****************

This chapter will provide you with the high-level knowledge needed to build networks with
Reticulum. It will not, however tell you all you need to know to succesfully
design and configure every kind of network you can imagine. For this, you will
most likely need to read this manual in its entirity, invest significant time
into experimenting with the stack, and learning functionality intuitively.

Still, after reading this chapter, you should be well equipped to *start* that
journey. While Reticulum is **fundamentally different** compared to other
networking technologies, it can often be easier than using traditional stacks.
If you've built networks before, you will probably have to forget, or at least
temporarily ignore, a lot of things at this point. It will all makes sense in
the end though. Hopefully.

If you're used to protocols like IP, let's at least start with some relief:
You don't have to worry about coordinating addresses, subnets and routing for an
entire network that you might not know how will evolve in the future. With
Reticulum, you can simply add more segments to your network when it becomes
necessary, and Reticulum will handle the convergence of the entire network
automatically. There's plenty more neat aspects like that to Reticulum, but
we're getting ahead of ourselves. Let's cover the basics first.

Concepts & Overview
--------------------

Before you start building your own networks, it's important to understand the
fundamental principles that distinguish Reticulum networks from traditional
networking approaches. These principles shape how you design your network,
what trade-offs you encounter, and what capabilities you can rely on.

Reticulum is not a single network you "join", it is a toolkit for *creating* networks.
You decide what mediums to use, how nodes connect, what trust boundaries exist,
and what the network's purpose is. Reticulum provides the cryptographic foundation,
the transport mechanisms, and the convergence algorithms that make your design
workable. You provide the intent and the structure.

This approach offers tremendous flexibility, but it requires thinking in terms of
different abstractions than those used in conventional networking.

Introductory Considerations
^^^^^^^^^^^^^^^^^^^^^^^^^^^

There are important points that need to be kept in mind when building networks
with Reticulum:

 * | In a Reticulum network, any node can autonomously generate as many addresses
     (called *destinations* in Reticulum terminology) as it needs, which become
     globally reachable to the rest of the network. There is no central point of
     control over the address space.

 * | Reticulum was designed to handle both very small, and very large networks.
     While the address space can support billions of endpoints, Reticulum is
     also very useful when just a few devices needs to communicate.

 * | Low-bandwidth networks, like LoRa and packet radio, can interoperate and
     interconnect with much larger and higher bandwidth networks without issue.
     Reticulum automatically manages the flow of information to and from various
     network segments, and when bandwidth is limited, local traffic is prioritised.
     You will, however, need to configure your interfaces correctly. If you tell
     Reticulum to pass all announce traffic from a gigabit link to a LoRa interfaces,
     it will try as best as possible to comply with this, while still respecting
     bandwidth limits, but you *will* waste a lot of precious bandwidth and airtime,
     and your LoRa network will not work very well.

 * | Reticulum provides sender/initiator anonymity by default. There is no way
     to filter traffic or discriminate it based on the source of the traffic.

 * | All traffic is encrypted using ephemeral keys generated by an Elliptic Curve
     Diffie-Hellman key exchange on Curve25519. There is no way to inspect traffic
     contents, and no way to prioritise or throttle certain kinds of traffic.
     All transport and routing layers are thus completely agnostic to traffic type,
     and will pass all traffic equally.

 * | Reticulum can function both with and without infrastructure. When *transport
     nodes* are available, they can route traffic over multiple hops for other
     nodes, and will function as a distributed cryptographic keystore. When there
     is no transport nodes available, all nodes that are within communication range
     can still communicate.

 * | Every node can become a transport node, simply by enabling it in it's
     configuration, but there is no need for every node on the network to be a
     transport node. Letting every node be a transport node will in most cases
     degrade the performance and reliability of the network.

     *In general terms, if a node is stationary, well-connected and kept running
     most of the time, it is a good candidate to be a transport node. For optimal
     performance, a network should contain the amount of transport nodes that
     provides connectivity to the intended area / topography, and not many more
     than that.*

 * | Reticulum is designed to work reliably in open, trustless environments. This
     means you can use it to create open-access networks, where participants can
     join and leave in a free and unorganised manner. This property allows an
     entirely new, and so far, mostly unexplored class of networked applications,
     where networks, and the information flow within them can form and dissolve
     organically.

 * | You can just as easily create closed networks, since Reticulum allows you to
     add authentication to any interface. This means you can restrict access on
     any interface type, even when using legacy devices, such as modems. You can
     also mix authenticated and open interfaces on the same system. See the
     :ref:`Common Interface Options` section of the :ref:`Interfaces`
     chapter of this manual for information on how to set up interface authentication.


Reticulum allows you to mix very different kinds of networking mediums into a
unified mesh, or to keep everything within one medium. You could build a "virtual
network" running entirely over the Internet, where all nodes communicate over TCP
and UDP "channels". You could also build such a network using other already-established
communications channels as the underlying carrier for Reticulum.

However, most real-world networks will probably involve either some form of
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
located at ``~/.reticulum/config``. See the :ref:`Supported Interfaces`
chapter of this manual for interface configuration examples.

Any number of interfaces can be configured, and Reticulum will automatically
decide which are suitable to use in any given situation, depending on where
traffic needs to flow.

Destinations, Not Addresses
^^^^^^^^^^^^^^^^^^^^^^^^^^^

In traditional networking, addresses are allocated from a managed space. If you want to
communicate with another node, you need to know its address, and that address
must be unique within the network segment. This requires coordination, either
through manual assignment, DHCP servers, or other allocation mechanisms.

Reticulum replaces addresses with **destinations**. A destination is identified by a 16-byte
hash (128 bits) derived from a SHA-256 hash of the destination's identifying
characteristics. This hash serves as the address on the network. On the network, it
is represented in binary, but when displayed to human users, it will usually look something like
this ``<13425ec15b621c1d928589718000d814>``.

The critical difference is that *any node can generate as many destinations as it
needs, without coordination*. A destination's uniqueness is guaranteed by the
collision resistance of SHA-256 and the inclusion of the node's public key in the
hash calculation. Two nodes can both use the destination name
``messenger.user.inbox``, but they will have different destination hashes because
their public keys differ. Both can coexist on the same network without conflict.

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.


Transport Nodes and Instances
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Reticulum distinguishes between two types of nodes: **Instances**
and **Transport Nodes**. Every node running Reticulum is an Instance, but not
every Instance is a Transport Node.

A **Reticulum Instance** is any system running the Reticulum stack. It can create
destinations, send and receive packets, establish links, and communicate with
other nodes. It can also host destinations that are connectable for *anyone* else
in the network. This means you can easily host globally available services from
any location, including your home or office. Network-wide, global connectivity
for all destinations is guaranteed, as long as there is *some* physical way to
actually transport the packets. Instances are the default state and are appropriate for most end-user devices,
such as phones, laptops, sensors, or any device that primarily consumes network services.

A **Transport Node** is an Instance that has been explicitly configured to
participate in network-wide transport. Transport nodes forward packets across
hops, propagate announces, maintain path tables, and serve path requests on
behalf of other nodes. When a destination sends an announce, Transport Nodes
receive it, remember the path, and rebroadcast it to other interfaces. When a node
needs to reach a destination it doesn't have a path for, Transport Nodes help
resolve the path through the network.

Even devices hosting services or serving content should probably just be configured
as instances, and themselves connect to wider networks via a Transport Node.
In some situations, this may not be practical though, and as an example, it is
entirely viable to host a personal Transport Node on a Raspberry Pi, while it
is at the same time running an LXMF propagation node, and hosting your personal
site or files over Reticulum.

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.

In practice, a network typically has a relatively small number of Transport Nodes
strategically placed to provide coverage and connectivity. End-user devices run
as Instances, connecting through nearby Transport Nodes to reach the wider network.
This pattern mirrors traditional networking where routers forward traffic while
end hosts simply consume connectivity, but with the crucial difference that any
node *can* become a router if needed, and the decision is yours to make based on
your network's requirements.

Transport nodes also function as distributed cryptographic keystores. When a
destination announces itself, Transport Nodes cache the public key and destination
information. Other nodes can request unknown public keys from the network, and
Transport Nodes respond with the cached information. This eliminates the need for
a central directory service while ensuring that public keys remain available
throughout the network.

Trustless Networking
^^^^^^^^^^^^^^^^^^^^

Traditional network security models assume high levels of trust at
specific layers. You might trust your ISP to deliver packets without inspection,
or trust your VPN provider to handle your traffic, or trust the network
administrator to configure firewalls appropriately. These trust relationships
create vulnerabilities and dependencies.

Reticulum is designed to function in **open, trustless environments**. This
means the protocol makes no assumptions about the trustworthiness of the network
infrastructure, the other participants, or the transport mediums. Every aspect
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
  of virtual private networks on shared mediums.

The trustless design has important consequences for network design:

* **Open-access networks are viable:** You can build networks that anyone can
  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,
  or impersonate legitimate traffic. Redundant paths and multiple Transport Nodes
  mitigate the impact of malicious nodes.

Of course, you can also create closed networks. Interface Access
Codes allow you to restrict participation on specific interfaces. Network
Identities enable you to verify that discovered interfaces belong to trusted
operators. Blackhole management lets you block malicious identities. Reticulum
provides both the tools for open networks and the controls for closed ones. The
choice is yours based on your requirements.


Heterogeneous Connectivity
^^^^^^^^^^^^^^^^^^^^^^^^^^

In conventional networking, mixing different transport mediums typically requires
gateways, translation layers, and careful configuration. A WiFi network doesn't
natively interoperate with a packet radio network without additional infrastructure,
and you can't just download a car over a serial port, or send an encrypted message
in a QR code.

Reticulum treats **heterogeneity as a core premise**. The protocol is designed
to seamlessly mix mediums with vastly different characteristics:

* **Bandwidth:** LoRa links operating at a few hundred bits per second can
  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.

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.

For network designers, this means you are free to use whatever mediums are
available, affordable, or appropriate for your situation. You might use LoRa for
wide-area low-bandwidth coverage, WiFi for local high-capacity links, I2P for
anonymous Internet connectivity, and Ethernet for infrastructure backhauls, all
within the same network. Reticulum handles the translation and coordination
automatically.

The key design consideration is not whether different mediums can work together
(they can), but **how** they should work together based on your goals. A node
with multiple interfaces spanning heterogeneous mediums needs to be configured
with appropriate interface modes so that traffic flows efficiently. A gateway
connecting a slow LoRa segment to a fast Internet backbone should be configured
differently than a mobile device roaming between radio cells.

---

## File: docs/source/reference.rst

:tocdepth: 4

.. _api-main:

*************
API Reference
*************
Communication over Reticulum networks is achieved by using a simple set of classes exposed by the RNS API.
This chapter lists and explains all classes exposed by the Reticulum Network Stack API, along with their method signatures and usage. It can be used as a reference while writing applications that utilise Reticulum, or it can be read in entirity to gain an understanding of the complete functionality of RNS from a developers perspective.

.. _api-reticulum:

.. only:: html

   |start-h3| Reticulum |end-h3|

.. only:: latex

   Reticulum
   ---------

.. autoclass:: RNS.Reticulum
   :members:


.. _api-identity:

.. only:: html

   |start-h3| Identity |end-h3|

.. only:: latex

   Identity
   --------

.. autoclass:: RNS.Identity
   :members:

.. _api-destination:

.. only:: html

   |start-h3| Destination |end-h3|

.. only:: latex

   Destination
   -----------

.. autoclass:: RNS.Destination
   :members:

.. _api-packet:

.. only:: html

   |start-h3| Packet |end-h3|

.. only:: latex

   Packet
   ------

.. autoclass:: RNS.Packet(destination, data, create_receipt = True)
   :members:

.. _api-packetreceipt:

.. only:: html

   |start-h3| Packet Receipt |end-h3|

.. only:: latex

   Packet Receipt
   --------------

.. autoclass:: RNS.PacketReceipt()
   :members:

.. _api-link:

.. only:: html

   |start-h3| Link |end-h3|

.. only:: latex

   Link
   ----

.. autoclass:: RNS.Link(destination, established_callback=None, closed_callback = None)
   :members:

.. _api-requestreceipt:

.. only:: html

   |start-h3| Request Receipt |end-h3|

.. only:: latex

   Request Receipt
   ---------------

.. autoclass:: RNS.RequestReceipt()
   :members:

.. _api-resource:

.. only:: html

   |start-h3| Resource |end-h3|

.. only:: latex

   Resource
   --------

.. autoclass:: RNS.Resource(data, link, advertise=True, auto_compress=True, callback=None, progress_callback=None, timeout=None)
   :members:

.. _api-channel:

.. only:: html

   |start-h3| Channel |end-h3|

.. only:: latex

   Channel
   -------

.. autoclass:: RNS.Channel.Channel()
   :members:

.. _api-messsagebase:

.. only:: html

   |start-h3| MessageBase |end-h3|

.. only:: latex

   MessageBase
   -----------

.. autoclass:: RNS.MessageBase()
   :members:

.. _api-buffer:

.. only:: html

   |start-h3| Buffer |end-h3|

.. only:: latex

   Buffer
   ------

.. autoclass:: RNS.Buffer
   :members:

.. _api-rawchannelreader:

.. only:: html

   |start-h3| RawChannelReader |end-h3|

.. only:: latex

   RawChannelReader
   ----------------

.. autoclass:: RNS.RawChannelReader
   :members: __init__, add_ready_callback, remove_ready_callback

.. _api-rawchannelwriter:

.. only:: html

   |start-h3| RawChannelWriter |end-h3|

.. only:: latex

   RawChannelWriter
   ----------------

.. autoclass:: RNS.RawChannelWriter
   :members: __init__

.. _api-transport:

.. only:: html

   |start-h3| Transport |end-h3|

.. only:: latex

   Transport
   ---------

.. autoclass:: RNS.Transport
   :members:

.. |start-h3| raw:: html

     <h3>

.. |end-h3| raw:: html

     </h3>

---

## File: docs/source/support.rst

.. _support-main:

*****************
Support Reticulum
*****************
You can help support the continued development of open, free and private communications
systems by donating, providing feedback and contributing code and learning resources.

Donations
=========
Donations are gratefully accepted via the following channels:


.. code:: text

    Monero:
    84FpY1QbxHcgdseePYNmhTHcrgMX4nFfBYtz2GKYToqHVVhJp8Eaw1Z1EedRnKD19b3B8NiLCGVxzKV17UMmmeEsCrPyA5w

    Bitcoin:
    bc1pgqgu8h8xvj4jtafslq396v7ju7hkgymyrzyqft4llfslz5vp99psqfk3a6

    Ethereum:
    0x91C421DdfB8a30a49A71d63447ddb54cEBe3465E
    
    Liberapay:
    https://liberapay.com/Reticulum/

    Ko-Fi:
    https://ko-fi.com/markqvist

Are certain features in the development roadmap are important to you or your
organisation? Make them a reality quickly by sponsoring their implementation.

.. raw:: latex

    \newpage

Provide Feedback
================
Feedback on the usage, functioning and potential dysfunctioning of any and
all components of the system is very valuable to the continued development and
improvement of Reticulum. But...

.. warning::
  
  **Think before you speak**. As time has shown, over 80% of the "feedback",
  "bug reports" and "advice" the Reticulum project has received has been
  irrelevant noise, stemming from erroneous assumptions, misunderstanding the
  foundational functionality or philosophy behind the system, or simply
  the malinformed (but overly opinionated) personal preferences of individual
  drive-by architects. This wastes the time of everyone involved.

  The Reticulum project is not a public teahouse for serving the attention
  needs of random bypassers, but a highly complex system engineered and
  refined over more than a decade, designed to provide communication and
  connectivity guarantees in highly adversarial environments.

  If you want to voice your opinion, it better be well-informed, and we
  expect you to have a comprehensive and solid foundation for your points
  of view. Everything else will be ignored.

Absolutely no automated analytics, telemetry, error
reporting or statistics is collected and reported by Reticulum under any
circumstances, so we rely on old-fashioned human feedback.