We already use `vite` as a bundling tool but only to rollup some of the
pre-built files. This setup (and therefore our buildscripts) can be
massively simplified by instructing `vite` to also build our TypeScript
code and compile tailwind.
This makes it much easier to develop locally because one only needs to
run `pnpm vite build --watch` to keep everything up to date.
Currently, one machines that have multiple routable egress interfaces,
`connlib` may bounce between the two instead of settling on one. This
happens because we have a dedicated `CandidateSet` that we use to filter
out "duplicate" candidates of the same type. Doing that is important
because if the other party is behind a symmetric NAT, they will send us
many server-reflexive candidates that all only differ by their port,
none of them will actually be routable though.
To prevent sending many of these candidates to the remote, we first
gather them locally in our `CandidateSet` and de-duplicate them.
This link repeatedly returns a 403 in our CI link checker, despite being
available.
Fixes: #9140Fixes: #9120
Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
If the user tries to start the tunnel from system settings without
launching the GUI after upgrading to >= 1.4.15, the new configuration
will be empty, and we'll fail to set the accountSlug, preventing the
tunnel from starting.
To fix this, we add a simple convenience function that returns the
legacy configuration, and we use this configuration to start the tunnel
in case the GUI hasn't started.
Once the GUI starts, the legacy configuration is migrated and deleted,
so this is more of an edge case. Still, given the hundreds/thousands of
Apple device installations we have, someone is bound to hit it, and it
would be better to spend a few minutes saving potentially man-hours of
troubleshooting later.
On macOS, the token is saved in the system keychain so that the `root`
user is able to manage it. `secd`, the daemon that responds to Keychain
requests, is very strict about which binaries can access Keychain items
created by other binaries.
In development, the Firezone system extension runs from an unprivileged
directory, and isn't release-signed, which means it is not able to
manage the Keychain token for the release binary, and vice-versa.
To fix this, we isolate the Keychain items from each other with
different labels for `debug` and `release`, where the latter is
unchanged.
This is only an issue on debug, so a Changelog entry is not created.
Fixes#8917Fixes#8642
Exposes a configuration toggle to connect on start, allowing it to be
overridden by MDM. Currently we assume this to be true.
Will need to refactor the settings soon to a dedicated
`ObservableObject` in the ViewModel to make these validations and field
checks less verbose.
related: #4505
Bumps the aya group in /rust with 5 updates:
| Package | From | To |
| --- | --- | --- |
| [aya](https://github.com/aya-rs/aya) | ``583709f`` | ``f74a157`` |
| [aya-build](https://github.com/aya-rs/aya) | ``583709f`` | ``f74a157``
|
| [aya-ebpf](https://github.com/aya-rs/aya) | ``583709f`` | ``f74a157``
|
| [aya-log](https://github.com/aya-rs/aya) | ``583709f`` | ``f74a157`` |
| [aya-log-ebpf](https://github.com/aya-rs/aya) | ``583709f`` |
``f74a157`` |
Updates `aya` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
Updates `aya-build` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
Updates `aya-ebpf` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
Updates `aya-log` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
Updates `aya-log-ebpf` from `583709f` to `f74a157`
<details>
<summary>Commits</summary>
<ul>
<li><a
href="f74a157907"><code>f74a157</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1262">#1262</a> from
dave-tucker/stabilize-links</li>
<li><a
href="7dba5a41ad"><code>7dba5a4</code></a>
feat(aya): Make LinkInfo and loaded_links public</li>
<li><a
href="92c73a72e7"><code>92c73a7</code></a>
Merge pull request <a
href="https://redirect.github.com/aya-rs/aya/issues/1263">#1263</a> from
aya-rs/dependabot/cargo/cargo-crates-b22b264ef4</li>
<li><a
href="95c03e6600"><code>95c03e6</code></a>
build(deps): update nix requirement in the cargo-crates group</li>
<li><a
href="33c9f2b2b2"><code>33c9f2b</code></a>
aya: uprobe: use PathBuf for
ResolveSymbolError::DebuglinkAccessError</li>
<li><a
href="90d5604877"><code>90d5604</code></a>
aya: uprobe attach: use mmap instead of reading whole binaries to
memory</li>
<li><a
href="647100faa7"><code>647100f</code></a>
aya: clean up resolve_symbol a bit</li>
<li><a
href="3aded0e0a5"><code>3aded0e</code></a>
aya: move Mmap struct to aya::util</li>
<li>See full diff in <a
href="583709f6a0...f74a157907">compare
view</a></li>
</ul>
</details>
<br />
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
To simulate varying network conditions in our tests, each `Host` in our
test network has an "inbox" that contains all incoming network packets
with an added latency. When another hosts sends a packet, the packet
gets added to the inbox. Internally, the inbox has a binary heap that
sorts incoming `Transmits` by their latency and only delivers them to
the node when that delay is up.
Currently, this delivery doesn't always happen because we fail to take
into account the timestamp as when the next `Transmit` is due when we
figure out what to do next.
Instead of just looking at the inner state via `poll_transmit`, we now
also consult the inbox of messages as to when the next message is due
and wake up at the correct time.
Not doing this caused our state machine to think that packets got
dropped because `REFRESH` messages to the relays were timing out.
Resolves: #9118
Now that configuration is persisted in a more reasonable fashion, we can
expose a new `General` section to the Settings, allowing the user to
configure an account slug.
This field will automatically be populated upon the first sign in, so
that subsequent sign-ins will take the user directly to the account sign
in page.
Fixes#5119
Related #8919
---------
Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
In the UI, we need to use Strings to bind to the text inputs.
In the configuration dictionaries, we need to use Strings to save the
URLs.
It makes no sense to convert these to URLs in between. Instead, we can
validate upon save and then use them as Strings throughout.
All the MDM configuration to shadow the `internetResourceEnabled` state.
Related: #4505
---------
Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Why:
* During the account sign up flow, the email of the first admin was not
being populated in the `email` column on the auth_identities table. This
was due to atoms being passed in the attrs instead of strings to the
`create_identity` function. A migration was also created to backfill the
missing emails in the `auth_identities` table.
In order to harvest some of the fruits of our lobbying efforts upstream,
we bump `moka` to latest `main` whilst they are still preparing the next
release.
This removes several dependencies from our dependency tree & lockfile.
Related: https://github.com/moka-rs/moka/pull/509
As part of going through the changes since the last Client and Gateway
relies, I noticed that for several of the things we fixed, it might be
worth adding changelog entries.
To send UDP DNS queries to upstream DNS servers, we have a
`UdpSocket::handshake` function that turns a UDP socket into a
single-use object where exactly one datagram is expected from the
address we send a message to. The way this is enforced is via an
equality check.
It appears that this equality check fails if users run an upstream DNS
server on a link-local IPv6 address within a setup that utilises IPv6
scopes. At the time when we receive the response, the packet has already
been successfully routed back to us so we should accept it, even if we
didn't specify a scope as the destination address.
In order to avoid routing loops on Windows, our UDP and TCP sockets in
`connlib` embed a "source IP resolver" that finds the "next best"
interface after our TUN device according to Windows' routing metrics.
This ensures that packets don't get routed back into our TUN device.
Currently, errors during this process are only logged on TRACE and
therefore not visible in Sentry. We fix this by moving around some of
the function interfaces and forward the error from the source IP
resolver together with some context of the destination IP.
If `authURL`, `apiURL`, or `logFilter` are set in the managed
configuration, we disable each of these fields respectively from user
editing.
If all of them are overridden, we disable the `Apply` and `Reset to
Defaults` buttons.
Related #4505
As part of launching the Tauri GUI client, we need to observe a specific
initialisation order. In particular, we need to wait until Tauri sends
us a `RunEvent::Ready` before we can initialise things like the tray
menu.
To make this more convenient, Tauri offers a so-called "setup hook" that
can be set on the app builder. Unfortunately, Tauri internally panics if
this provided setup-hook returns an `Err`. Removing this is tracked
upstream: https://github.com/tauri-apps/tauri/issues/12815.
Until this is fixed, we stop using this "setup hook" and instead spawn
our own task that performs this work. This task needs to wait until
Tauri is ready. To achieve that, we introduce an additional mpsc channel
that sends a notification every time we receive a `RunEvent::Ready`.
That should only happen once. We only read from the receiver once, which
is why we ignore the error on the sending side in case the receiver has
already been dropped.
Resolves: #9101
When this crate is compiled by itself, these features are required. This
doesn't show up in CI because there we compile the entire workspace and
some crate somewhere already activates these features then.
One simple way we can tell the GUI app which configuration fields have
been overridden by MDM is to specify an `overriddenKeys` string array.
If provided, this will disable the relevant configuration from being set
/ editable in the GUI app and communicate to the user as such.
Related: #4505
---------
Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Similar to how we fetch new resources, we add a Configuration poller
that fetches new configuration every 1s. If the configuration is
unchanged, we respond to the caller with a cached copy to avoid needing
to serialize the data over IPC.
Related: #4505
Bumps [divan](https://github.com/nvzqz/divan) from 0.1.17 to 0.1.21.
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/nvzqz/divan/blob/main/CHANGELOG.md">divan's
changelog</a>.</em></p>
<blockquote>
<h2>[0.1.21] - 2025-04-09</h2>
<h3>Fixed</h3>
<ul>
<li><code>Divan::skip_exact</code> behaved incorrectly in
<code>v0.1.19</code>.</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Improved handling of internal code around filters and those
responsible for
sacking the people who have just been sacked have been sacked.</li>
</ul>
<h2>[0.1.20] - 2025-04-09</h2>
<h3>Fixed</h3>
<ul>
<li><code>Divan::skip_regex</code> accidentally dropped
<a
href="https://docs.rs/regex-lite/latest/regex_lite/struct.Regex.html"><code>regex_lite::Regex</code></a>
and behaved incorrectly in <code>v0.1.19</code>.</li>
</ul>
<h2>[0.1.19] - 2025-04-09</h2>
<h3>Fixed</h3>
<ul>
<li>[<code>cargo-nextest</code>] no longer skips benchmarks with
argument parameters (<a
href="https://redirect.github.com/nvzqz/divan/issues/75">#75</a>).</li>
</ul>
<h3>Changed</h3>
<ul>
<li>Organized positive and negative filters into a split buffer.</li>
</ul>
<h2>[0.1.18] - 2025-04-05</h2>
<h3>Added</h3>
<ul>
<li>
<p>Support for [<code>cargo-nextest</code>] running benchmarks as
tests.</p>
</li>
<li>
<p>[<code>prelude</code>] module for simplifying imports of
[<code>#[bench]</code>][bench_attr],
[<code>#[bench_group]</code>][bench_group_attr],
[<code>black_box</code>], [<code>black_box_drop</code>],
[<code>AllocProfiler</code>], [<code>Bencher</code>], and
[<code>Divan</code>].</p>
</li>
<li>
<p>Support <code>wasi</code> and <code>emscripten</code> targets.</p>
</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="52f9d4983e"><code>52f9d49</code></a>
Release v0.1.21</li>
<li><a
href="5afb095486"><code>5afb095</code></a>
Fix broken <code>Divan::skip_exact</code></li>
<li><a
href="e4d112ccbc"><code>e4d112c</code></a>
Release v0.1.20</li>
<li><a
href="1d74108bbe"><code>1d74108</code></a>
Fix broken <code>Divan::skip_regex</code></li>
<li><a
href="58988fc304"><code>58988fc</code></a>
Release v0.1.19</li>
<li><a
href="f43a742d0f"><code>f43a742</code></a>
docs: Change "changes" to "changed" in
changelog</li>
<li><a
href="f348769fb4"><code>f348769</code></a>
docs: List most recent changes in changelog</li>
<li><a
href="07111fb6f8"><code>07111fb</code></a>
Abstract filters into <code>FilterSet</code></li>
<li><a
href="2c865cdf24"><code>2c865cd</code></a>
docs: Add link to <code>prelude</code> module in changelog</li>
<li><a
href="9075b9e0ed"><code>9075b9e</code></a>
fix nextest support for parameterized benches</li>
<li>Additional commits viewable in <a
href="https://github.com/nvzqz/divan/compare/v0.1.17...v0.1.21">compare
view</a></li>
</ul>
</details>
<br />
[](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.
[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)
---
<details>
<summary>Dependabot commands and options</summary>
<br />
You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot merge` will merge this PR after your CI passes on it
- `@dependabot squash and merge` will squash and merge this PR after
your CI passes on it
- `@dependabot cancel merge` will cancel a previously requested merge
and block automerging
- `@dependabot reopen` will reopen this PR if it is closed
- `@dependabot close` will close this PR and stop Dependabot recreating
it. You can achieve the same result by closing it manually
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
</details>
Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
For at least 1 user, the threads shut down correctly, but we didn't seem
to have exited the loop. In
https://firezone-inc.sentry.io/issues/6335839279/events/c11596de18924ee3a1b64ced89b1fba2/?project=4508008945549312,
we can see that both flags are marked as `true` yet we still emitted the
message.
The only way how I can explain this is that the thread shut down in
between the two times we've called the `is_finished` function. To ensure
this doesn't happen, we now only read it once.
This however also shows that 5s may not be enough time for WinTUN to
shutdown. Therefore, we increase the grace period to 10s.
This can easily happen if we are briefly disconnected from the portal.
It is not the end of the world and not worth creating Sentry alerts for.
Originally, this was intended to be a way of detecting "bad
connectivity" but that didn't really work.
Our DNS over TCP implementation uses `smoltcp` which requires us to
manage sockets individually, i.e. there is no such thing as a listening
socket. Instead, we have to create multiple sockets and rotate through
them.
Whenever we receive new DNS servers from the host app, we throw away all
of those sockets and create new ones.
The way we refer to these sockets internally is via `smoltcp`'s
`SocketHandle`. These are just indices into a `Vec` and this access can
panic when it is out of range. Normally that doesn't happen because such
a `SocketHandle` is only created when the socket is created and
therefore, each `SocketHandle` in existence should be valid.
What we overlooked is that these sockets get destroyed and re-created
when we call `set_listen_addresses` which happens when the host app
tells us about new DNS servers. In that case, sockets that we had just
received a query on and are waiting for a response have their handles
stored in a temporary `HashMap`. Attempting to send back a response for
one of those queries will then either fail with an error that the socket
is not in the right state or - worse - panic with an out of bounds error
if the previously had more listen addresses than we have now.
To fix this, we need to clear this map of pending queries every time we
call `set_listen_addresses`.
When calculating the maximum size of the UDP payload we can send in a
single syscall, we need to take into account the overhead of the IP and
UDP headers.