There were 3 problems currently on main, one on the tests and the actual bug. ## Test problem The routes were kept in a `BTreeSet` that when a new route was added it was `insert`ed into and when it was removed it was `remove`d from using the address of the route. The problem is if there were overlapping route added twice in a row and then a single one of those resources is removed the test would believe the route no longer exists. ## Test solution Keep the routes in a `BTreeMap` which maps the id to the ip and then we calculate the routes based on that combined with the default routes, that way we just remove the ID and the routes are kept in the correct expected state. ## Real bug So fixing this revealed a similar bug in connlib, since we kept things in a similar struct, `active_cidr_resources` using `IpNetworkTable`. To fix this I re-calculate the whole table each time we add/remove a resource. Note that this really doesn't properly fixes overlapping routes, this is just helpful to fix the test, to fix them we need #4789 Furthermore, fixing these issues revealed an additional problem, whenever we add an overlapping CIDR resource the old resource might be overridden, causing the connection to be lost, furthermore this happened in a non-deterministic(it's deterministic really but not explicit) way causing the tests to fail. To fix this we always sort resources by ID(it's an arbitrary order to keep consistency with the proptests) and then we don't replace the routing for resources that already had a connection. Sadly, to model this in the test I had to almost copy exactly how we calculate resources in connlib. Fixes #6721 --------- Signed-off-by: Gabi <gabrielalejandro7@gmail.com> Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
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
benchprofile. sudo perf 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.