In #3400, a discussion started on what the correct log level would be for the production relay. Currently, the relay logs some stats about each packet on debug, i.e. where it came from, where it is going to and how big it is. This isn't very useful in production though and will fill up our log disk quickly. This PR introduces a stats timer like we already have it in other components. We print the number of allocations, how many channels we have and how much data we relayed over all these channels since we last printed. The interval is currently set to 10 seconds. Here is what this output could look like (captured locally using `relay/run_smoke_test.sh`, although slightly tweaked, printing ever 2s, using release mode and larger packets on the clients): ``` 2024-01-26T05:01:02.445555Z INFO relay: Seeding RNG from '0' 2024-01-26T05:01:02.445580Z WARN relay: No portal token supplied, starting standalone mode 2024-01-26T05:01:02.445827Z INFO relay: Listening for incoming traffic on UDP port 3478 2024-01-26T05:01:02.447035Z INFO Eventloop::poll: relay: num_allocations=0 num_channels=0 throughput=0.00 B/s 2024-01-26T05:01:02.649194Z INFO Eventloop::poll:handle_client_input{sender=127.0.0.1:39092 transaction_id="8f20177512495fcb563c60de" allocation=AID-1}: relay: Created new allocation first_relay_address=127.0.0.1 lifetime=600s 2024-01-26T05:01:02.650744Z INFO Eventloop::poll:handle_client_input{sender=127.0.0.1:39092 transaction_id="6445943a353d5e8c262a821f" allocation=AID-1 peer=127.0.0.1:41094 channel=16384}: relay: Successfully bound channel 2024-01-26T05:01:04.446317Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=631.54 MB/s 2024-01-26T05:01:06.446319Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=698.73 MB/s 2024-01-26T05:01:08.446325Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=708.98 MB/s 2024-01-26T05:01:10.446324Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=690.79 MB/s 2024-01-26T05:01:12.446316Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=715.53 MB/s 2024-01-26T05:01:14.446315Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=706.90 MB/s 2024-01-26T05:01:16.446313Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=712.03 MB/s 2024-01-26T05:01:18.446319Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=717.54 MB/s 2024-01-26T05:01:20.446316Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=690.74 MB/s 2024-01-26T05:01:22.446313Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=705.08 MB/s 2024-01-26T05:01:24.446311Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=700.41 MB/s 2024-01-26T05:01:26.446319Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=717.57 MB/s 2024-01-26T05:01:28.446320Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=688.82 MB/s 2024-01-26T05:01:30.446329Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=696.35 MB/s 2024-01-26T05:01:32.446317Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=724.03 MB/s 2024-01-26T05:01:34.446320Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=713.46 MB/s 2024-01-26T05:01:36.446314Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=716.13 MB/s 2024-01-26T05:01:38.446327Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=687.16 MB/s 2024-01-26T05:01:40.446315Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=708.20 MB/s 2024-01-26T05:01:42.446314Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=689.36 MB/s 2024-01-26T05:01:44.446314Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=698.62 MB/s 2024-01-26T05:01:46.446315Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=696.21 MB/s 2024-01-26T05:01:48.446378Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=696.36 MB/s 2024-01-26T05:01:50.446314Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=709.47 MB/s 2024-01-26T05:01:52.446319Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=714.48 MB/s 2024-01-26T05:01:54.446323Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=690.71 MB/s 2024-01-26T05:01:56.446313Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=692.70 MB/s 2024-01-26T05:01:58.446321Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=687.87 MB/s 2024-01-26T05:02:00.446316Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=682.11 MB/s 2024-01-26T05:02:02.446312Z INFO Eventloop::poll: relay: num_allocations=1 num_channels=1 throughput=700.07 MB/s ```
relay
This crate houses a minimalistic STUN & TURN server.
Features
We aim to support the following feature set:
- STUN binding requests
- TURN allocate requests
- TURN refresh requests
- TURN channel bind requests
- TURN channel data requests
Relaying of data through other means such as DATA frames is not supported.
Building
You can build the relay using: cargo build --release --bin firezone-relay
You should then find a binary in target/release/firezone-relay.
Running
The Firezone Relay supports Linux only. To run the Relay binary on your Linux host:
- Generate a new Relay token from the "Relays" section of the admin portal and save it in your secrets manager.
- Ensure the
FIREZONE_TOKEN=<relay_token>environment variable is set securely in your Relay's shell environment. The Relay expects this variable at startup. - Now, you can start the Firezone Relay with:
firezone-relay
To view more advanced configuration options pass the --help flag:
firezone-relay --help
Ports
The relay listens on port 3478. This is the standard port for STUN/TURN and
not configurable. Additionally, the relay needs to have access to the port range
49152 - 65535 for the allocations.
Portal Connection
When given a token, the relay will connect to the Firezone portal and wait for
an init message before commencing relay operations.
Design
The relay is designed in a sans-IO fashion, meaning the core components do not cause side effects but operate as pure, synchronous state machines. They take in data and emit commands: wake me at this point in time, send these bytes to this peer, etc.
This allows us to very easily unit-test all kinds of scenarios because all inputs are simple values.
The main server runs in a single task and spawns one additional task for each allocation. Incoming data that needs to be relayed is forwarded to the main task where it gets authenticated and relayed on success.