mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 18:18:55 +00:00
refactor: minor tweak to sans-io intro to be more conservative (#5709)
Signed-off-by: Thomas Eizinger <thomas@eizinger.io> Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
This commit is contained in:
@@ -1,14 +1,14 @@
|
||||
import Image from "next/image";
|
||||
import Alert from "@/components/DocsAlert";
|
||||
|
||||
At Firezone, we build secure remote access that scales, be it from your Android
|
||||
phone, MacOS computer or Linux server. At the core of each app sits a
|
||||
connectivity library — aptly named
|
||||
At Firezone, we use Rust[^1] to build secure remote access that scales, be it
|
||||
from your Android phone, MacOS computer or Linux server. At the core of each app
|
||||
sits a connectivity library — aptly named
|
||||
[`connlib`](https://www.github.com/firezone/firezone/tree/main/rust/connlib)
|
||||
— that manages network connections and WireGuard tunnels to secure your
|
||||
traffic. After several iterations, we’ve landed on a design that we are
|
||||
extremely happy with. It gives us blazingly fast and exhaustive tests, deep
|
||||
customisation and overall high assurance that it does what we want it to do.
|
||||
extremely happy with. It gives us fast and exhaustive tests, deep customisation
|
||||
and overall high assurance that it does what we want it to do.
|
||||
|
||||
`connlib` is built in Rust and the design we are talking about is known as
|
||||
sans-IO. Rust's premise of speed and memory-safety makes it a great choice for
|
||||
@@ -453,7 +453,7 @@ event loop are: `handle_timeout`, `handle_input`, `poll_transmit` and
|
||||
protocols can be implemented with these or some variation of them. As a result,
|
||||
it is very easy to compose these state machines together: want to query 5 STUN
|
||||
servers for your public IP? No problem. Just make 5 `StunBinding`s and call them
|
||||
in order[^3].
|
||||
in order[^4].
|
||||
|
||||
In the case of Firezone, you can see this in the example of
|
||||
[`snownet`](https://github.com/firezone/firezone/tree/main/rust/connlib/snownet),
|
||||
@@ -461,7 +461,7 @@ a library that combines ICE and WireGuard and thereby exposes "magic" IP tunnels
|
||||
that work in any network setup to the rest of the application.
|
||||
|
||||
`snownet` builds on top of `str0m`, a sans-IO WebRTC library and `boringtun`, an
|
||||
(almost[^2]) sans-IO WireGuard implementation. We don’t need the majority of the
|
||||
(almost[^3]) sans-IO WireGuard implementation. We don’t need the majority of the
|
||||
WebRTC stack though. The only thing we are interested in is the `IceAgent` which
|
||||
implements [RFC 8445](https://datatracker.ietf.org/doc/html/rfc8445). ICE uses a
|
||||
clever algorithm that ensures two agents, deployed into arbitrary network
|
||||
@@ -572,7 +572,7 @@ is sound. In comparison, `async` Rust and `&mut` almost feel somewhat at odds
|
||||
with each other.
|
||||
|
||||
In Rust, `async` functions are just syntax sugar for a data structure that
|
||||
implements `Future`. Spawning a `Future` into a runtime[^1] like `tokio`
|
||||
implements `Future`. Spawning a `Future` into a runtime[^2] like `tokio`
|
||||
requires this data structure to be `'static` and therefore, it cannot contain
|
||||
any references, including `&mut`. To mutate state that isn't local to the
|
||||
`Future`, you basically have two options:
|
||||
@@ -644,12 +644,16 @@ Many thanks to [@algesten](https://github.com/algesten) for providing feedback
|
||||
on drafts of this post.
|
||||
|
||||
[^1]:
|
||||
Technically, a thread-per-core runtime could allow non-`'static` `Future`s.
|
||||
For more details on Firezone's tech stack, see
|
||||
[this article](/kb/architecture/tech-stack) in our architecture docs.
|
||||
|
||||
[^2]:
|
||||
Technically, a thread-per-core runtime could allow non-`'static` `Future`s.
|
||||
|
||||
[^3]:
|
||||
`boringtun` does call `Instant::now` internally and is thus unfortunately
|
||||
partly impure, see https://github.com/cloudflare/boringtun/issues/391.
|
||||
|
||||
[^3]:
|
||||
[^4]:
|
||||
Be sure to implement proper multiplexing of STUN messages at this point.
|
||||
Hint: Use the `TransactionId` and/or the server's address.
|
||||
|
||||
@@ -57,6 +57,12 @@ These manage the control path and hot paths of the Client, respectively. They
|
||||
interact through a thin software layer to exchange WireGuard keys and STUN
|
||||
information between the control plane API and the TUN interface.
|
||||
|
||||
<Alert color="warning">
|
||||
For a deep dive into Firezone's data plane architecture and its sans-IO
|
||||
design, we recommend reading [sans-IO: The secret to effective Rust for
|
||||
network services](/blog/sans-io).
|
||||
</Alert>
|
||||
|
||||
Here's a high-level diagram of the various software components used in the
|
||||
Client applications:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user