Our idle connection detection works based on incoming and outgoing packets, whichever one happened later. If we have not received or sent packets for longer than `MAX_IDLE`, we transition into idle mode where we configure our ICE agent to only send binding requests every 60 seconds. Our ICE timeout in non-idle mode is just north of 10 seconds (the formula is a bit tricky so don't have the accurate number). This can cause a problem whenever a Gateway disappears. We leave the idle mode as soon as we send a packet through the Gateway. Thus, what we intended to happen is that, as long as you keep trying to connect to the Gateway, we will leave the idle mode, increase our rate of STUN bindings through the ICE agent and detect within ~10s that the Gateway is gone. What actually happens is that, IF whatever resource you are trying to talk to is a DNS resource (which is very likely) and the application starts off with a DNS query, then we will reset the local DNS resource NAT state and ping the Gateway to set up the NAT again (we do this to ensure we don't have stale DNS entries on the Gateway). This message is only sent once and all other packets are buffered. Thus, the connection will go back to idle before the newly sent STUN binding requests can determine that the connection is actually broken. Resolves: #8551
Rust development guide
Firezone uses Rust for all data plane components. This directory contains the Linux and Windows clients, and low-level networking implementations related to STUN/TURN.
We target the last stable release of Rust using rust-toolchain.toml.
If you are using rustup, that is automatically handled for you.
Otherwise, ensure you have the latest stable version of Rust installed.
Reading Client logs
The Client logs are written as JSONL for machine-readability.
To make them more human-friendly, pipe them through jq like this:
cd path/to/logs # e.g. `$HOME/.cache/dev.firezone.client/data/logs` on Linux
cat *.log | jq -r '"\(.time) \(.severity) \(.message)"'
Resulting in, e.g.
2024-04-01T18:25:47.237661392Z INFO started log
2024-04-01T18:25:47.238193266Z INFO GIT_VERSION = 1.0.0-pre.11-35-gcc0d43531
2024-04-01T18:25:48.295243016Z INFO No token / actor_name on disk, starting in signed-out state
2024-04-01T18:25:48.295360641Z INFO null
Benchmarking on Linux
The recommended way for benchmarking any of the Rust components is Linux' perf utility.
For example, to attach to a running application, do:
- Ensure the binary you are profiling is compiled with the
releaseprofile. sudo perf record -g --freq 10000 --pid $(pgrep <your-binary>).- Run the speed test or whatever load-inducing task you want to measure.
sudo perf script > profile.perf- Open profiler.firefox.com and load
profile.perf
Instead of attaching to a process with --pid, you can also specify the path to executable directly.
That is useful if you want to capture perf data for a test or a micro-benchmark.