Previously, we required the user to specify a `LISTEN_IP4_ADDR` and/or a `LISTEN_IP6_ADDR` parameter. This is cumbersome because dynamically fetching the address of the local interface is not trivial in all environments. We remove this parameter in exchange for listening on all interfaces. This is a trade-off. The relay will now listen on all interfaces, even the ones not exposed to the public internet. This is true for the main socket on port 3478 and for all created allocations. Actually relaying data relies on the 4-tuple of a "connection", i.e. the source and destination address and port. Technically, I think it is possible with this change to send traffic to a relay via an interface that was not intended to be used for that. I think this will still require spoofing the source address which is a known and accepted problem. It is still recommended that operators put appropriate firewall rules in place to not allow ingress traffic on any interface other than the one intended for relaying. I've tested locally that we are correctly using the `IPV6_ONLY` flag. In other words, a relay listening on the `0.0.0.0` wildcard interface will not accept IPv6 traffic and vice versa. Resolves #1886.
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 server using: cargo build --release --bin relay
Running
For an up-to-date documentation on the available configurations options and a detailed help text, run cargo run --bin relay -- --help.
All command-line options can be overridden using environment variables.
Those variables are listed in the --help output at the bottom of each command.
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 portal endpoint, the relay will connect to it 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.