mirror of
https://github.com/outbackdingo/firezone.git
synced 2026-01-27 10:18:54 +00:00
91962acb8379a7cf8abd7bdf5d2370268bedda74
2903 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
663f23e9fb |
fix(connlib): classify WireGuard first (#10890)
WireGuard packets can have all kinds of byte-patterns at the very front of the packet. Thus, we need to first check if a payload is a WireGuard packet before attempting to classify it as anything else. This function is currently only used for logging purposes. `snownet` has its own logic for de-multiplexing and classifying packets. |
||
|
|
7e5994b3c6 |
chore: bump to upstream proptest (#10888)
The changes from our fork have been upstreamed successfully. We can therefore switch our dependency back to that. |
||
|
|
ed6e2a4e7d |
feat(connlib): introduce DoHUrl abstraction (#10881)
When connlib processes DoH queries, we need to pass the server's URL around a lot. In order to bootstrap the HTTP client, we need to extract the host part of this URL and resolve it for IP addresses using the system resolver. A regular URL doesn't necessarily have a host: It could be relative. This creates an error path within our code that _should_ never get hit for DoH URLs as those are always absolute. To avoid this error path, we follow the "parse, don't validate" approach typical among strongly typed languages. We create our own type that can only be constructed from absolute URLs. If we receive a URL from the portal that is not absolute, we already fail at the deserialization step. Using data privacy of the encapsulated url, we can then guarantee that the host-part of the URL is always there and can access it in an infallible way. Given that we are now already parsing the URL to begin with, I've also opted to directly implement an optimisation where we create a fast-path for the 4 known DoH providers that we have which allows us to pass them around and copy them without incurring extra allocations. Finally, this custom type also comes with its own Display/Debug implementation, making the log output a bit easier to read. |
||
|
|
c523add895 |
build(deps): bump zip from 5.1.1 to 6.0.0 in /rust (#10829)
Bumps [zip](https://github.com/zip-rs/zip2) from 5.1.1 to 6.0.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/zip-rs/zip2/releases">zip's releases</a>.</em></p> <blockquote> <h2>v6.0.0</h2> <h3><!-- raw HTML omitted -->🐛 Bug Fixes</h3> <ul> <li>panic when reading empty extended-timestamp field (<a href="https://redirect.github.com/zip-rs/zip2/pull/404">#404</a>) (<a href="https://redirect.github.com/zip-rs/zip2/pull/422">#422</a>)</li> <li>Restore original file timestamp when unzipping with <code>chrono</code> (<a href="https://redirect.github.com/zip-rs/zip2/pull/46">#46</a>)</li> </ul> <h3><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h3> <ul> <li>Configure Amazon Q rules (<a href="https://redirect.github.com/zip-rs/zip2/pull/421">#421</a>)</li> </ul> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/zip-rs/zip2/blob/master/CHANGELOG.md">zip's changelog</a>.</em></p> <blockquote> <h2><a href="https://github.com/zip-rs/zip2/compare/v5.1.1...v6.0.0">6.0.0</a> - 2025-10-09</h2> <h3><!-- raw HTML omitted -->🚀 Features</h3> <ul> <li>Add by_index_with_options(), which can be used to ignore encryption in a file's metadata (<a href="https://redirect.github.com/zip-rs/zip2/pull/439">#439</a>) and may be used for other file-specific overrides in the future.</li> </ul> <h3><!-- raw HTML omitted -->⚙️ Miscellaneous Tasks</h3> <ul> <li>[<strong>breaking</strong>] <code>FileOptions::add_extra_data</code> is now generic and accepts any <code>AsRef<[u8]></code>. (<a href="https://redirect.github.com/zip-rs/zip2/issues/435">#435</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
95fdb7f62a |
fix(connlib): sanitize resolvers before re-resolving portal URL (#10880)
In #10817, connlib gained the ability to re-resolve the portal's hostname on WebSocket connection hiccups. The list of upstream servers used for that may contain sentinel DNS server IPs on certain systems if connlib's DNS control is currently active. Connlib filters these servers internally before computing the effective list of upstream servers. The DNS client used by the event-loop contacts all servers in the list but waits for at most 2s before merging all received records together. If there are upstream DNS servers defined in the portal and those are also resources which we are currently not connected to, querying these servers would trigger a message to the portal, forming a circular dependency. This circular dependency is only broken by the 2s timeout. Whilst not fatal for connlib's functionality, it means that in such a situation, reconnecting to the portal always has to wait for this timeout. To fix this, we first apply the system DNS resolvers to connlib and only pass the now returned sanitized list on to the DNS client. Related: #10854 --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: thomaseizinger <5486389+thomaseizinger@users.noreply.github.com> |
||
|
|
33bd31c1eb |
chore(connlib): pass through DoH servers to DNS config (#10872)
This is a follow-up to #10851. In order to be able to use and reason about the DoH servers, we need to deserialize the list and pass the servers into connlib's `DnsConfig`. Right now, they just sit there and we don't do anything with them. Thus, this PR is save to go into `main`, even if we were to make a release before our DoH support is fully finished. To ensure this is the case, we also update the proptests in this PR to randomly sample and apply DoH servers. --------- Signed-off-by: Thomas Eizinger <thomas@eizinger.io> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|
|
d282b641c5 |
refactor(connlib): use anyhow::Error for recursive DNS (#10871)
With the introduction of DoH, we will need a more advanced error type for recursive DNS responses. In particular, a DoH query might fail because the underlying TCP connection got closed. With #10856, the HTTP client no longer supports retries but instead needs to be recreated. In order to accurately detect this failure case, we need `anyhow`'s downcasting abilities. This PR prepares the already existing code for that by switching from `io::Error` to `anyhow::Error`. |
||
|
|
1a5c40bd75 |
refactor(connlib): extract l4-udp-dns-client (#10854)
In order to bootstrap DoH servers, we need a way of reliably resolving the domain of the DoH server to an IP address. Initially, I thought that this would be tricky to do if we have to integrate this into the Client's state machine. Whilst implementing DoH however, I realised that we can instead put this responsibility onto the IO layer of connlib. Similar to other cases, we can reuse external triggers as our retry mechanism in case of failure. In particular, we can simply issue UDP DNS queries for the DoH domain to all system-defined DNS resolvers every time we are told to send a DNS query over DoH but the corresponding client isn't initialized yet. In other words, instead of building a retry mechanism ourselves, we attempt to repair any kind of broken state once per DNS query that we receive. Performing this DNS resolution does require a bit of code. We already started to do something similar in #10817. In order to reuse that code, we extract it into a `l4-udp-dns-client` crate and slightly refactor its semantics. In particular, we now wait for the response of all upstream servers (but at most 2s) and combine the result. The resulting `UdpDnsClient` can now be used inside the Client's event-loop to re-resolve the portal URL and will also be used as part of our DoH implementation to bootstrap the connection to the DoH server. Related: #4668 |
||
|
|
ff3ff93e1a |
fix(dns-types): use base64url encoding without padding (#10875)
According to the DoH spec, the base64url encoded query must not include any padding characters. |
||
|
|
81023dbf52 |
feat(connlib): make parallel requests with HttpClient (#10856)
Our `socket-factory`-aware HttpClient is currently only able to handle a single request at a time. That is a result of the requirement that we wanted to support connections to different domains but also be able to "self-heal" those connections by establishing a new one if the current one failed. As I am learning more about how connlib's DoH support is going to work, it became apparent that we will only ever need to connect to a single domain per instance of the `HttpClient`. In addition, it is quite important to allow for concurrent requests: We don't want to process DoH queries in sequence but instead make full use of the underlying HTTP2 protocol and send multiple requests in parallel. This PR refactors the `HttpClient` (which isn't in use anywhere yet) to only support a single connection per instance. That connection is established when the instance is created. This is also conceptually easier to understand as we only manage a single connection without mutable state. Related: #4668 |
||
|
|
53113c645f |
fix(connlib): don't panic in fallible function (#10874)
Panicking - even though it is unlikely to happen here - is unnecessary because we can simply return an error instead. |
||
|
|
cd650de1f8 |
refactor: prepare client init for upstream DoH servers (#10851)
In order to support multiple different protocols of upstream DNS resolvers, we deprecate the `upstream_dns` field in the client's `init` message and introduce two new fields: - `upstream_do53` - `upstream_doh` For now, only `upstream_do53` is populated and `upstream_doh` is always empty. On the client-side, we for now only introduce the `upstream_do53` field but fall-back to `upstream_dns` if that one is empty. This makes this PR backwards-compatible with the portal version that is currently deployed in production. Thus, this PR can be merged even prior to deploying the portal. Internally, we prepare connlib's abstractions to deal with different kinds of upstreams by renaming all existing "upstream DNS" references to `upstream_do53`: DNS over port 53. That includes UDP as well as TCP DNS resolution. Resolves: #10791 --------- Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com> |
||
|
|
4bd768aed5 |
build(deps): bump @types/node from 24.5.2 to 24.7.2 in /rust/gui-client (#10834)
Bumps [@types/node](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/node) from 24.5.2 to 24.7.2. <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/node">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> |
||
|
|
8af8978ad5 |
chore(connlib): include "packet kind" in decapsulation errors (#10867)
When looking at error logs from Gateways or Clients, it can be useful to know, what kind of packet we failed to process. |
||
|
|
ee38ccc120 |
chore(connlib): log index of failed connections (#10866)
Logging the peer index of a failed connection makes it easier to correlate it with logs when we receive packets for an unknown connection. |
||
|
|
32e1c088e7 |
chore(gateway): include domain in "not allowed" log (#10863)
The resource could be a wildcard DNS resource. It is useful to know, which particular domain the client tried to access. |
||
|
|
5f61eaf8f2 |
feat(connlib): encode and decode DoH messages (#10857)
In order to support DoH, we need to be able to encode and decode DNS queries and responses from and to HTTP requests and responses. We therefore extend your `dns-types` crate with the required functionality. The [RFC8484](https://datatracker.ietf.org/doc/html/rfc8484) provides us with two test vectors that we can test against. Related: #4668 --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com> Co-authored-by: thomaseizinger <5486389+thomaseizinger@users.noreply.github.com> |
||
|
|
cf14a8694c |
fix(connlib): use system DNS resolvers to re-resolve portal URL (#10853)
In #10817, we landed a fix that allows Clients to re-resolve the portal URL every time the WebSocket connection fails. Currently, we use the active upstream resolvers for this. This can lead to a kind of deadlock in case the upstream resolver is a CIDR resource that we are not yet connected to. In that case, we'd need a connection to the portal to establish a connection to the Gateway. By always using the system resolvers for this, we avoid this circular dependency. |
||
|
|
3e849ae852 |
fix(gui-client): use Wayland rendering backend on Linux (#10849)
Previously, we opted into the X11 GTK backend when rendering the GUI Client's window. This is causing issues on newer Linux distributions such as Fedora 43 where Wayland is now the only available compositor. Removing the X11 GTK requires us to draw our own CSDs such as titlebars and a close button. This PR does exactly that by adding a minimalistic title bar. To make better use of the space, we move the section headers into there. |Before|After| |---|---| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-11" src="https://github.com/user-attachments/assets/9439a69b-65ba-41d6-b1f8-4448e0f80728" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-40-55" src="https://github.com/user-attachments/assets/7884b2cc-3d9c-4b47-9a1e-c6462aef36ab" />| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-16" src="https://github.com/user-attachments/assets/2cfea825-5c08-45a5-873c-5afcbc1dbf16" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-40-58" src="https://github.com/user-attachments/assets/43ddd7c9-ce65-42f7-b972-28c6b172b70d" />| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-19" src="https://github.com/user-attachments/assets/446873a7-9023-4266-9377-ea7b8b4353ee" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-41-01" src="https://github.com/user-attachments/assets/64439383-f33f-461d-9b4a-6b4138bd675b" />| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-22" src="https://github.com/user-attachments/assets/6c39e06c-1d77-471f-91f1-32a78b90a21c" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-41-04" src="https://github.com/user-attachments/assets/b56912cb-9c85-4b5a-9295-dae6139b25c6" />| |<img width="1900" height="1174" alt="Screenshot From 2025-11-11 11-14-26" src="https://github.com/user-attachments/assets/5a5d638c-15bf-4523-8466-2e0977a03e22" />|<img width="1800" height="1000" alt="Screenshot From 2025-11-11 11-41-06" src="https://github.com/user-attachments/assets/ed169b52-ef86-4dc4-8f25-852da622eaa1" />| |
||
|
|
0008539b65 |
refactor(connlib): use dedicated UDP DNS client (#10850)
By default, DNS queries are sent over UDP by most systems. UDP is an easy to understand protocol because each packet stands by itself and at least as far as UDP is concerned, the payload is contained within a single packet. In Firezone, we receive all DNS traffic on the TUN device as IP packets. Processing the UDP packets is trivial as each query is contained within a single IP packet. For TCP, we first need to assemble the TCP stream before we can read the entire query. In case a DNS query is not for a Firezone DNS resource, we want to forward it to the specified upstream resolver, either directly from the system or - in case the specified upstream resolver is an IP resource - through the tunnel as an IP packet. Specifically, the forwarding of UDP DNS packets through the tunnel currently happens like this: IP packet -> read UDP payload -> parse DNS query -> mangle original destination IP to new upstream -> send through tunnel For TCP DNS queries, it is not quite as easy as we have to decode the incoming TCP stream first before we can parse the DNS query. Thus, when we want to then forward the query, we need to open our own TCP stream to the upstream resolver and encode the DNS query onto that stream, sending each IP packet from the TCP client through the tunnel. The difference in these designs makes several code paths in connlib hard to follow. Therefore - and despite the simplicity of DNS over UDP - we already created our own "Layer 3 UDP DNS"-client. This PR now integrates this client into the tunnel. Using this new client, we can simplify the processing of UDP DNS queries because we never have to "go back" to the original IP packet. Instead, when a DNS query needs to be forwarded to an usptream resolver through the tunnel, we simply tell the Layer 3 UDP DNS client to make a new DNS query. The processing of the resulting IP packet then happens in a different place, right next to where we also process the IP packets of the TCP DNS client. That simplifications unlocks further refactorings where we now only process DNS queries in a single place and the transport we received it over is a simple function parameter with the control flow for both of them being identical. Related: #4668 |
||
|
|
de7d3bff89 |
fix(connlib): re-resolve portal host on WS hiccup (#10817)
Currently, the DNS records for the portal's hostname are only resolved during startup. When the WebSocket connection fails, we try to reconnect but only with the IPs that we have previously resolved. If the local IP stack changed since then or the hostname now points to different IPs, we will run into the reconnect-timeout configured in `phoenix-channel`. To fix this, we re-resolve the portal's hostname every time the WebSocket connection fails. For the Gateway, this is easy as we can simply reuse the already existing `TokioResolver` provided by hickory. For the Client, we need to write our own DNS client on top of our socket factory abstraction to ensure we don't create a routing loop with the resulting DNS queries. To simplify things, we only send DNS queries over UDP. Those are not guaranteed to succeed but given that we do this on every "hiccup", we already have a retry mechanism. We use the currently configured upstream DNS servers for this. Resolves: #10238 |
||
|
|
a9058c7f55 |
build(deps): bump known-folders from 1.3.1 to 1.4.0 in /rust (#10831)
Bumps [known-folders](https://github.com/artichoke/known-folders-rs) from 1.3.1 to 1.4.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/artichoke/known-folders-rs/releases">known-folders's releases</a>.</em></p> <blockquote> <h2>v1.4.0</h2> <h2>What's Changed</h2> <ul> <li>Bump thor from 1.3.2 to 1.4.0 by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/artichoke/known-folders-rs/pull/85">artichoke/known-folders-rs#85</a></li> <li>Bump rubocop from 1.77.0 to 1.79.1 in the bundler-deps group by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/artichoke/known-folders-rs/pull/86">artichoke/known-folders-rs#86</a></li> <li>Bump the gha-deps group with 3 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/artichoke/known-folders-rs/pull/87">artichoke/known-folders-rs#87</a></li> <li>Use zizmor audit action by <a href="https://github.com/lopopolo"><code>@lopopolo</code></a> in <a href="https://redirect.github.com/artichoke/known-folders-rs/pull/88">artichoke/known-folders-rs#88</a></li> <li>Bump rubocop from 1.79.1 to 1.81.1 in the bundler-deps group by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/artichoke/known-folders-rs/pull/89">artichoke/known-folders-rs#89</a></li> <li>Bump the gha-deps group with 5 updates by <a href="https://github.com/dependabot"><code>@dependabot</code></a>[bot] in <a href="https://redirect.github.com/artichoke/known-folders-rs/pull/91">artichoke/known-folders-rs#91</a></li> <li>Relax windows-sys version requirement, prepare for v1.4.0 release by <a href="https://github.com/lopopolo"><code>@lopopolo</code></a> in <a href="https://redirect.github.com/artichoke/known-folders-rs/pull/92">artichoke/known-folders-rs#92</a></li> </ul> <p><strong>Full Changelog</strong>: <a href="https://github.com/artichoke/known-folders-rs/compare/v1.3.1...v1.4.0">https://github.com/artichoke/known-folders-rs/compare/v1.3.1...v1.4.0</a></p> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
e9fcb20564 |
build(deps): bump nu-ansi-term from 0.50.1 to 0.50.3 in /rust (#10830)
Bumps [nu-ansi-term](https://github.com/nushell/nu-ansi-term) from 0.50.1 to 0.50.3. <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/nushell/nu-ansi-term/commits">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> |
||
|
|
6e85638360 |
chore(connlib): silence hickory_resolver (#10848)
Logs from the `hickory_resolver` module are a bit noisy, so filter those out from our logs. |
||
|
|
5ae2707719 | chore: publish gateway 1.4.18 (#10823) | ||
|
|
3022c019e1 |
chore(connlib): set user.account_slug for Sentry logs (#10815)
By default, the Sentry SDK doesn't include custom user attributes when it sends logs. To make viewing logs easier, we add the `account_slug` attribute to all logs that are posted to Sentry. |
||
|
|
166b0d1573 |
feat(linux): compute device ID from /etc/machine-id (#10805)
All of our Linux applications have a soft-dependency on systemd. That is, in the default configuration, we expect systemd to be present on the machine. The only exception here are the docker containers for Headless Client and Gateway. For the GUI client in particular, systemd is a hard-dependency in order to control DNS on the system which we do via `systemd-resolved`. To secure the communication between the GUI client and its tunnel process, we automatically create a group called `firezone-client` to which the user gets added. All members of the group are allowed to access the unix socket which is used for IPC between the two processes. Membership in this group is also a prerequisite for accessing any of the configuration files. On the first launch of the GUI client on a Linux system, this presents a problem. For group membership changes to take the effect, the user needs to reboot. We say that in the documentation but it is unclear whether all users will read that thoroughly enough. To help the user, the GUI client checks for membership of the current user in the group and alerts the user via a dialog box if that isn't the case. This would all be fine if it would actually work. Unfortunately, that check ends up being too late in the process. If we aren't a member of the group, we cannot read the device ID and bail early, thus never reaching the check and terminating the process without any dialog box or user-visible error. We could attempt to fix this by shuffling around some of the startup init code. That is a sub-optimal solution however because it a) may get broken again in the future and b) it means we have to delay initialisation of telemetry until a much later point. Given that this is only a problem on Linux, a better solution is to simply not rely on the disk-based device ID at all. Instead, we can integrate with systemd and deterministically derive a device ID from the unique machine ID and a randomly chosen "app ID". For backwards-compatibility reasons, the disk-based device ID is still prioritised. For all new installs however, we will use the one based on `/etc/machine-id`. |
||
|
|
8651413a95 |
chore(gateway): downgrade warning if peer not found (#10814)
Logging this on WARN appears to be a bit excessive and there is not really anything we can do about it. Resolves: #10813 |
||
|
|
f4216710e0 |
fix(telemetry): don't append duplicate attributes in Sentry log (#10819)
When we are building the log message that is sent to Sentry, we append several attributes to mimic the formatting that we get from `tracing_subscriber::fmt`. To do that, we strip the span name from the attribute which can result in us processing the same attribute such as `cid` twice: Once from a span and once from the actual log message. In order to not append the same message twice, we check for its presence in the attributes map first. This avoids having message in Sentry such as: ``` Sampled relay cid=c18e1da8-8ef8-4e11-a325-28d6b387d503 rid=3af15c76-9e84-46a6-90e1-63ecb2bc9f80 cid=c18e1da8-8ef8-4e11-a325-28d6b387d503 ``` |
||
|
|
bc95a1f425 |
chore(snownet): log connection state on failure (#10820)
When investigating, why a connection fails it is useful to know right away, what the last connection state was, including the kind of connection, such as `PeerToPeer`, `RelayToPeer` etc. |
||
|
|
123c5a5d97 |
chore(connlib): always include wire::api as Sentry breadcrumb (#10821)
Sentry appends "breadcrumbs" to every error that gets sent to the backend. By default, those include the last 500 DEBUG logs. Our `phoenix_channel` module logs the incoming and outgoing messages on TRACE using the `wire::api::send` and `wire::api::recv` targets. To make debugging these easier, we always include anything on `wire::api` in the breadcrumbs. |
||
|
|
74bd28d25a |
ci(gui-client): fix .deb test installation (#10816)
The current test installation fails because it is operating in a headless environment without a display user. Some more testing of the `who` command showed that we can simply take the first user. That avoids `grep` which was previously failing with an exit code of 1, aborting the installation because our `postinst` script has `pipefail` set. |
||
|
|
3eead925fe |
chore(gui-client): tidy up postinst script (#10804)
Specifying `sudo` in the script is unnecessary as it already runs as root. Additionally, only executing `systemd-sysusers` for our config file is better because it narrows the scope of what should be done. |
||
|
|
f98c4dd428 |
fix(gateway): declare hard-dependency on systemd (#10803)
Several aspects of the Gateway's Debian package depend on `systemd` being present. Without it, we don't have the necessary users and files in place for the Gateway to function. With that specified, we can fail the `postinst` script (and therefore the installation) if anything in there goes wrong. |
||
|
|
839cc4b7b3 |
build(deps): bump parking_lot from 0.12.4 to 0.12.5 in /rust (#10780)
Bumps [parking_lot](https://github.com/Amanieu/parking_lot) from 0.12.4 to 0.12.5. <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/Amanieu/parking_lot/blob/master/CHANGELOG.md">parking_lot's changelog</a>.</em></p> <blockquote> <h2><code>parking_lot</code> - <a href="https://github.com/Amanieu/parking_lot/compare/parking_lot-v0.12.4...parking_lot-v0.12.5">0.12.5</a> - 2025-09-30</h2> <ul> <li>Bumped MSRV to 1.71</li> <li>Fixed Miri when the <code>hardware-lock-elision</code> feature is enabled (<a href="https://redirect.github.com/Amanieu/parking_lot/issues/491">#491</a>)</li> <li>Added missing <code>into_arc(_fair)</code> methods (<a href="https://redirect.github.com/Amanieu/parking_lot/issues/472">#472</a>)</li> <li>Fixed <code>RawRwLock::bump_*()</code> not releasing lock when there are multiple readers (<a href="https://redirect.github.com/Amanieu/parking_lot/issues/471">#471</a>)</li> </ul> <h2><code>parking_lot_core</code> - <a href="https://github.com/Amanieu/parking_lot/compare/parking_lot_core-v0.9.11...parking_lot_core-v0.9.12">0.9.12</a> - 2025-09-30</h2> <ul> <li>Bumped MSRV to 1.71</li> <li>Switched from <code>windows-targets</code> to <code>windows-link</code>. (<a href="https://redirect.github.com/Amanieu/parking_lot/issues/493">#493</a>)</li> <li>Replaced <code>thread-id</code> dependency with <code>std::thread::ThreadId</code> (<a href="https://redirect.github.com/Amanieu/parking_lot/issues/483">#483</a>)</li> <li>Added SGX implementation for <code>ThreadParker.park_until</code> (<a href="https://redirect.github.com/Amanieu/parking_lot/issues/481">#481</a>)</li> </ul> <h2><code>lock_api</code> - <a href="https://github.com/Amanieu/parking_lot/compare/lock_api-v0.4.13...lock_api-v0.4.14">0.4.14</a> - 2025-09-30</h2> <ul> <li>Fixed use of <code>doc_cfg</code> when building on docs.rs.</li> <li>Bumped MSRV to 1.71</li> <li>Added <code>#[track_caller]</code> where locking implementations could feasibly need to panic</li> <li>Added <code>try_map_or_err</code> to various mutex guards (<a href="https://redirect.github.com/Amanieu/parking_lot/issues/480">#480</a>)</li> <li>Removed unnecessary build script and <code>autocfg</code> dependency (<a href="https://redirect.github.com/Amanieu/parking_lot/issues/474">#474</a>)</li> <li>Added missing <code>into_arc(_fair)</code> methods (<a href="https://redirect.github.com/Amanieu/parking_lot/issues/472">#472</a>)</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
89f0af3fd7 | fix(gateway): remove exclamation mark from sysusers.conf (#10802) | ||
|
|
024b1864b4 |
feat(linux): automatically add user to firezone-client group (#10787)
By checking various environment variables, we can automatically add the current user to the `firezone-client` group which allows them to connect to the IPC socket of the tunnel process. Unfortunately, they still have to create a new login session / reboot for that to be reflected. The docs update for this will follow once we have cut a release with this code in it. --------- Signed-off-by: Thomas Eizinger <thomas@eizinger.io> Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com> |
||
|
|
602844ae4a |
fix(gateway): always update translation table from DNS response (#10796)
For DNS resources, the Gateway maintains a per-peer NAT table from the client-assigned proxy IPs to the real IPs of the domain. Whenever the Client re-queries a DNS resource domain locally, we asynchronously ping the Gateway to also re-query said domain. This allows us to detect changes in the DNS records of DNS resources. To avoid breaking existing connections, the mapping between proxy IPs and real IPs is currently not updated if there are any active UDP or TCP flows for a proxy IP. This logic turns out to be unnecessarily restrictive as TCP flows can linger around for up to 2h before they timeout if they are not closed with a TCP RST. What we really need to do is always update the mapping of proxy IP <> real IP but honor existing NAT table entries when we route packets before creating new ones. This ensures that an existing connection to a previously resolved IP remains intact, even if a later DNS response for the same domain updates the mapping. At the same time, new connections (i.e. with a different source port) will immediately use the new destination IP. |
||
|
|
72dd7187f4 |
revert: specify systemd-resolved dependency (#10798)
I can't make the CI smoke install work with this change. Reverts firezone/firezone#10783 |
||
|
|
bae38ec345 |
feat(connlib): add HTTP2 client with pluggable sockets (#10788)
Firezone's ability to tunnel all traffic on a particular Client (i.e. the Internet Resource) means we have to ensure that traffic originating from within the Firezone process does not get routed back into the tunnel. On MacOS and iOS, this is automatically taken care of for us. On all other platforms, we need to take steps to prevent these routing loops. This functionality is abstracted away using our `SocketFactory`. A socket created with such a factory is guaranteed to route its traffic outside of the tunnel. These sockets are used for the WebSocket connection to the portal, as well as for recursive UDP and TCP DNS queries. In order to support DoH, we need to also be able to send HTTPS requests without causing packet loops. This PR adds a new crate `http-client` that does exactly that. It composes together `hyper` and `rustls` such that the configured `SocketFactory` is used to create the TCP socket for the underlying HTTP2 connection. Consequently, HTTPS requests made with this library will automatically be routed outside of the tunnel, assuming the `SocketFactory` is adequately configured. Right now, this crate just stands by itself. It will be integrated into connlib at a later point. Resolves: #10774 Related: #4668 Related: #10272 |
||
|
|
352a83bbb0 |
refactor(connlib): allow creating multiple layer 4 DNS servers (#10763)
Within Firezone, there are multiple components that deal with DNS queries. Two of those components are the `l4-udp-dns-server` and `l4-tcp-dns-server`. Both of them are responsible for receiving DNS queries on layer 4, i.e. UDP or TCP. In other words, they do _not_ operate on an IP level (which would be layer 3) but instead use `UdpSocket` and `TcpListener` to receive queries and sent back responses. Right now, the interfaces of these crates are designed for the usecase of receiving forwarded DNS queries from the CLient on the Gateway's TUN device. This is a special-case of DNS resolution. When receiving a TXT or SRV query for a domain that is covered by a DNS resources, Firezone Client's will forward that query to the corresponding Gateway and resolve it in its network context. SRV and TXT records are commonly used for service discovery and as such, should be resolved in the network context of the service, i.e. the site that assigned to the resource. For that usecase, it made sense to allow each DNS server to listen on 1 IPv4 and 1 IPv6 address. Since then, our event-loop has evolved a bit, being able to handle multiple inputs at once. As such, we can simplify the API of these crates to only listen on a single address and instead create multiple instances of them inside `Io`. Depending on how the design of our DNS implementation for the Clients evolves, this may be used to listen on multiple IPs later (e.g. from the `127.0.0.0/8` subnet). Related: #8263 |
||
|
|
804ef7a3fb |
fix(connlib): retain order of system/upstream DNS servers (#10773)
Right now, connlib hands out a `BiMap` of sentinel IPs <> upstream servers whenever it emits a `TunInterfaceUpdated` event. This `BiMap` internally uses two `HashMap`s. The iteration order of `HashMap`s is non-deterministic and therefore, we lose the order in which the upstream / system resolvers have been passed to us originally. To prevent that, we now emit a dedicated `DnsMapping` type that does not expose its internal data structure but only getters for retrieving the sentinel and upstream servers. Internally, it uses a `Vec` to store this mapping and thus retains the original order. This is asserted as part of our proptests by comparing the resulting `Vec`s. This fix is preceded by a few refactorings that encapsulate the code for creating and updating this DNS mapping. Resolves: #8439 |
||
|
|
1b7313622a |
feat(connlib): introduce l3-udp-dns-client (#10764)
With #8263, we will stop receiving UDP and TCP DNS queries on the tunnel but use regular sockets instead. This means that for UDP DNS queries that need to be sent _through_ the tunnel, we actually need to make new IP packets again. For TCP, we already have a crate that does this for us because there, we need to manage an entire TCP stack. For UDP, the story is a bit simpler but there are still a few things involved. In particular, we need to set a source address for the packets and we need to sample a new random port for each query. The crate added in this PR does exactly that. It is not yet used anywhere but split out into a separate PR to reduce the reviewing burden of the larger refactor. Related: #8263 Related: #10758 |
||
|
|
9e33e514c4 |
chore(linux): specify systemd-resolved dependency (#10783)
On Ubuntu, this should be the default anyway and already be installed but to be correct, we should list this dependency in the `depends` section of our `.deb`. That way, it will automatically get installed again if a user chooses to install the GUI client from our repository and doesn't have `systemd-resolved` installed. |
||
|
|
b5c420bd5b |
build(deps): bump serde_with from 3.14.0 to 3.15.0 in /rust (#10777)
Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.14.0 to 3.15.0. <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/jonasbb/serde_with/releases">serde_with's releases</a>.</em></p> <blockquote> <h2>serde_with v3.15.0</h2> <h3>Added</h3> <ul> <li> <p>Added error inspection to <code>VecSkipError</code> and <code>MapSkipError</code> by <a href="https://github.com/michelhe"><code>@michelhe</code></a> (<a href="https://redirect.github.com/jonasbb/serde_with/issues/878">#878</a>) This allows interacting with the previously hidden error, for example for logging. Checkout the newly added example to both types.</p> </li> <li> <p>Allow documenting the types generated by <code>serde_conv!</code>. The <code>serde_conv!</code> macro now acceps outer attributes before the optional visibility modifier. This allow adding doc comments in the shape of <code>#[doc = "..."]</code> or any other attributes, such as lint modifiers.</p> <pre lang="rust"><code>serde_conv!( #[doc = "Serialize bools as string"] #[allow(dead_code)] pub BoolAsString, bool, |x: &bool| ::std::string::ToString::to_string(x), |x: ::std::string::String| x.parse() ); </code></pre> </li> <li> <p>Add support for <code>hashbrown</code> v0.16 (<a href="https://redirect.github.com/jonasbb/serde_with/issues/877">#877</a>)</p> <p>This extends the existing support for <code>hashbrown</code> v0.14 and v0.15 to the newly released version.</p> </li> </ul> <h3>Changed</h3> <ul> <li>Bump MSRV to 1.76, since that is required for <code>toml</code> dev-dependency.</li> </ul> <h2>serde_with v3.14.1</h2> <h3>Fixed</h3> <ul> <li>Show macro expansion in the docs.rs generated rustdoc. Since macros are used to generate trait implementations, this is useful to understand the exact generated code.</li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
6d60653bac |
build(deps): bump gat-lending-iterator from 0.1.6 to 0.1.7 in /rust (#10776)
Bumps [gat-lending-iterator](https://github.com/Crazytieguy/gat-lending-iterator) from 0.1.6 to 0.1.7. <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/Crazytieguy/gat-lending-iterator/commits/v0.1.7">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> |
||
|
|
9016ffc9dc |
build(rust): bump to Rust 1.91.0 (#10767)
Rust 1.91 has been released and brings with it a few new lints that we need to tidy up. In addition, it also stabilizes `BTreeMap::extract_if`: A really nifty std-lib function that allows us to conditionally take elements from a map. We need that in a bunch of places. |
||
|
|
21846b81e5 |
build(deps): bump vite from 7.1.7 to 7.1.11 in /rust/gui-client in the npm_and_yarn group across 1 directory (#10769)
Bumps the npm_and_yarn group with 1 update in the /rust/gui-client directory: [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite). Updates `vite` from 7.1.7 to 7.1.11 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/vitejs/vite/releases">vite's releases</a>.</em></p> <blockquote> <h2>v7.1.11</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v7.1.11/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> <h2>v7.1.10</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v7.1.10/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> <h2>v7.1.9</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v7.1.9/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> <h2>v7.1.8</h2> <p>Please refer to <a href="https://github.com/vitejs/vite/blob/v7.1.8/packages/vite/CHANGELOG.md">CHANGELOG.md</a> for details.</p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md">vite's changelog</a>.</em></p> <blockquote> <h2><!-- raw HTML omitted --><a href="https://github.com/vitejs/vite/compare/v7.1.10...v7.1.11">7.1.11</a> (2025-10-20)<!-- raw HTML omitted --></h2> <h3>Bug Fixes</h3> <ul> <li><strong>dev:</strong> trim trailing slash before <code>server.fs.deny</code> check (<a href="https://redirect.github.com/vitejs/vite/issues/20968">#20968</a>) (<a href=" |
||
|
|
1ac1bb044a |
build(deps): bump the sentry group in /rust with 2 updates (#10727)
Bumps the sentry group in /rust with 2 updates: [sentry](https://github.com/getsentry/sentry-rust) and [sentry-tracing](https://github.com/getsentry/sentry-rust). Updates `sentry` from 0.42.0 to 0.43.0 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/getsentry/sentry-rust/releases">sentry's releases</a>.</em></p> <blockquote> <h2>0.43.0</h2> <h3>Breaking changes</h3> <ul> <li>ref(tracing): rework tracing to Sentry span name/op conversion (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/887">#887</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li>The <code>tracing</code> integration now uses the tracing span name as the Sentry span name by default.</li> <li>Before this change, the span name would be set based on the <code>tracing</code> span target (<code><module>::<function></code> when using the <code>tracing::instrument</code> macro).</li> <li>The <code>tracing</code> integration now uses <code><span target>::<span name></code> as the default Sentry span op (i.e. <code><module>::<function></code> when using <code>tracing::instrument</code>).</li> <li>Before this change, the span op would be set based on the <code>tracing</code> span name.</li> <li>Read below to learn how to customize the span name and op.</li> <li>When upgrading, please ensure to adapt any queries, metrics or dashboards to use the new span names/ops.</li> </ul> </li> <li>ref(tracing): use standard code attributes (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/899">#899</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li>Logs now carry the attributes <code>code.module.name</code>, <code>code.file.path</code> and <code>code.line.number</code> standardized in OTEL to surface the respective information, in contrast with the previously sent <code>tracing.module_path</code>, <code>tracing.file</code> and <code>tracing.line</code>.</li> </ul> </li> <li>fix(actix): capture only server errors (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/877">#877</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li>The Actix integration now properly honors the <code>capture_server_errors</code> option (enabled by default), capturing errors returned by middleware only if they are server errors (HTTP status code 5xx).</li> <li>Previously, if a middleware were to process the request after the Sentry middleware and return an error, our middleware would always capture it and send it to Sentry, regardless if it was a client, server or some other kind of error.</li> <li>With this change, we capture errors returned by middleware only if those errors can be classified as server errors.</li> <li>There is no change in behavior when it comes to errors returned by services, in which case the Sentry middleware only captures server errors exclusively.</li> </ul> </li> <li>fix: send trace origin correctly (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/906">#906</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li><code>TraceContext</code> now has an additional field <code>origin</code>, used to report which integration created a transaction.</li> </ul> </li> </ul> <h3>Behavioral changes</h3> <ul> <li>feat(tracing): send both breadcrumbs and logs by default (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/878">#878</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li>If the <code>logs</code> feature flag is enabled, and <code>enable_logs: true</code> is set on your client options, the default Sentry <code>tracing</code> layer now sends logs for all events at or above INFO.</li> </ul> </li> </ul> <h3>Features</h3> <ul> <li> <p>ref(tracing): rework tracing to Sentry span name/op conversion (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/887">#887</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a></p> <ul> <li>Additional special fields have been added that allow overriding certain data on the Sentry span: <ul> <li><code>sentry.op</code>: override the Sentry span op.</li> <li><code>sentry.name</code>: override the Sentry span name.</li> <li><code>sentry.trace</code>: given a string matching a valid <code>sentry-trace</code> header (sent automatically by client SDKs), continues the distributed trace instead of starting a new one. If the value is not a valid <code>sentry-trace</code> header or a trace is already started, this value is ignored.</li> </ul> </li> <li><code>sentry.op</code> and <code>sentry.name</code> can also be applied retroactively by declaring fields with value <code>tracing::field::Empty</code> and then recorded using <code>tracing::Span::record</code>.</li> <li>Example usage: <pre lang="rust"><code>#[tracing::instrument(skip_all, fields( sentry.op = "http.server", sentry.name = "GET /payments", sentry.trace = headers.get("sentry-trace").unwrap_or(&"".to_owned()), ))] async fn handle_request(headers: std::collections::HashMap<String, String>) { // ... } </code></pre> </li> <li>Additional attributes are sent along with each span by default: <ul> <li><code>sentry.tracing.target</code>: corresponds to the <code>tracing</code> span's <code>metadata.target()</code></li> <li><code>code.module.name</code>, <code>code.file.path</code>, <code>code.line.number</code></li> </ul> </li> </ul> </li> <li> <p>feat(core): add Response context (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/874">#874</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a></p> <ul> <li>The <code>Response</code> context can now be attached to events, to include information about HTTP responses such as headers, cookies and status code.</li> </ul> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/getsentry/sentry-rust/blob/master/CHANGELOG.md">sentry's changelog</a>.</em></p> <blockquote> <h2>0.43.0</h2> <h3>Breaking changes</h3> <ul> <li>ref(tracing): rework tracing to Sentry span name/op conversion (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/887">#887</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li>The <code>tracing</code> integration now uses the tracing span name as the Sentry span name by default.</li> <li>Before this change, the span name would be set based on the <code>tracing</code> span target (<code><module>::<function></code> when using the <code>tracing::instrument</code> macro).</li> <li>The <code>tracing</code> integration now uses <code><span target>::<span name></code> as the default Sentry span op (i.e. <code><module>::<function></code> when using <code>tracing::instrument</code>).</li> <li>Before this change, the span op would be set based on the <code>tracing</code> span name.</li> <li>Read below to learn how to customize the span name and op.</li> <li>When upgrading, please ensure to adapt any queries, metrics or dashboards to use the new span names/ops.</li> </ul> </li> <li>ref(tracing): use standard code attributes (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/899">#899</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li>Logs now carry the attributes <code>code.module.name</code>, <code>code.file.path</code> and <code>code.line.number</code> standardized in OTEL to surface the respective information, in contrast with the previously sent <code>tracing.module_path</code>, <code>tracing.file</code> and <code>tracing.line</code>.</li> </ul> </li> <li>fix(actix): capture only server errors (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/877">#877</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li>The Actix integration now properly honors the <code>capture_server_errors</code> option (enabled by default), capturing errors returned by middleware only if they are server errors (HTTP status code 5xx).</li> <li>Previously, if a middleware were to process the request after the Sentry middleware and return an error, our middleware would always capture it and send it to Sentry, regardless if it was a client, server or some other kind of error.</li> <li>With this change, we capture errors returned by middleware only if those errors can be classified as server errors.</li> <li>There is no change in behavior when it comes to errors returned by services, in which case the Sentry middleware only captures server errors exclusively.</li> </ul> </li> <li>fix: send trace origin correctly (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/906">#906</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li><code>TraceContext</code> now has an additional field <code>origin</code>, used to report which integration created a transaction.</li> </ul> </li> </ul> <h3>Behavioral changes</h3> <ul> <li>feat(tracing): send both breadcrumbs and logs by default (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/878">#878</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a> <ul> <li>If the <code>logs</code> feature flag is enabled, and <code>enable_logs: true</code> is set on your client options, the default Sentry <code>tracing</code> layer now sends logs for all events at or above INFO.</li> </ul> </li> </ul> <h3>Features</h3> <ul> <li> <p>ref(tracing): rework tracing to Sentry span name/op conversion (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/887">#887</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a></p> <ul> <li>Additional special fields have been added that allow overriding certain data on the Sentry span: <ul> <li><code>sentry.op</code>: override the Sentry span op.</li> <li><code>sentry.name</code>: override the Sentry span name.</li> <li><code>sentry.trace</code>: given a string matching a valid <code>sentry-trace</code> header (sent automatically by client SDKs), continues the distributed trace instead of starting a new one. If the value is not a valid <code>sentry-trace</code> header or a trace is already started, this value is ignored.</li> </ul> </li> <li><code>sentry.op</code> and <code>sentry.name</code> can also be applied retroactively by declaring fields with value <code>tracing::field::Empty</code> and then recorded using <code>tracing::Span::record</code>.</li> <li>Example usage: <pre lang="rust"><code>#[tracing::instrument(skip_all, fields( sentry.op = "http.server", sentry.name = "GET /payments", sentry.trace = headers.get("sentry-trace").unwrap_or(&"".to_owned()), ))] async fn handle_request(headers: std::collections::HashMap<String, String>) { // ... } </code></pre> </li> <li>Additional attributes are sent along with each span by default: <ul> <li><code>sentry.tracing.target</code>: corresponds to the <code>tracing</code> span's <code>metadata.target()</code></li> <li><code>code.module.name</code>, <code>code.file.path</code>, <code>code.line.number</code></li> </ul> </li> </ul> </li> <li> <p>feat(core): add Response context (<a href="https://redirect.github.com/getsentry/sentry-rust/pull/874">#874</a>) by <a href="https://github.com/lcian"><code>@lcian</code></a></p> </li> </ul> <!-- raw HTML omitted --> </blockquote> <p>... (truncated)</p> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |
||
|
|
a426ee2608 |
build(deps): bump the react group in /rust/gui-client with 2 updates (#10722)
Bumps the react group in /rust/gui-client with 2 updates: [@types/react](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/react) and [react-router](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router). Updates `@types/react` from 19.1.13 to 19.1.15 <details> <summary>Commits</summary> <ul> <li>See full diff in <a href="https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/react">compare view</a></li> </ul> </details> <br /> Updates `react-router` from 7.9.1 to 7.9.3 <details> <summary>Release notes</summary> <p><em>Sourced from <a href="https://github.com/remix-run/react-router/releases">react-router's releases</a>.</em></p> <blockquote> <h2>v7.9.3</h2> <p>See the changelog for release notes: <a href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v793">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v793</a></p> <h2>v7.9.2</h2> <p>See the changelog for release notes: <a href="https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v792">https://github.com/remix-run/react-router/blob/main/CHANGELOG.md#v792</a></p> </blockquote> </details> <details> <summary>Changelog</summary> <p><em>Sourced from <a href="https://github.com/remix-run/react-router/blob/main/packages/react-router/CHANGELOG.md">react-router's changelog</a>.</em></p> <blockquote> <h2>7.9.3</h2> <h3>Patch Changes</h3> <ul> <li> <p>Do not try to use <code>turbo-stream</code> to decode CDN errors that never reached the server (<a href="https://redirect.github.com/remix-run/react-router/pull/14385">#14385</a>)</p> <ul> <li>We used to do this but lost this check with the adoption of single fetch</li> </ul> </li> <li> <p>Fix Data Mode regression causing a 404 during initial load in when <code>middleware</code> exists without any <code>loader</code> functions (<a href="https://redirect.github.com/remix-run/react-router/pull/14393">#14393</a>)</p> </li> </ul> <h2>7.9.2</h2> <h3>Patch Changes</h3> <ul> <li> <ul> <li>Update client-side router to run client <code>middleware</code> on initial load even if no loaders exist (<a href="https://redirect.github.com/remix-run/react-router/pull/14348">#14348</a>)</li> <li>Update <code>createRoutesStub</code> to run route middleware <ul> <li>You will need to set the <code><RoutesStub future={{ v8_middleware: true }} /></code> flag to enable the proper <code>context</code> type</li> </ul> </li> </ul> </li> <li> <p>Update Lazy Route Discovery manifest requests to use a singular comma-separated <code>paths</code> query param instead of repeated <code>p</code> query params (<a href="https://redirect.github.com/remix-run/react-router/pull/14321">#14321</a>)</p> <ul> <li>This is because Cloudflare has a hard limit of 100 URL search param key/value pairs when used as a key for caching purposes</li> <li>If more that 100 paths were included, the cache key would be incomplete and could produce false-positive cache hits</li> </ul> </li> <li> <p>[UNSTABLE] Add <code>fetcher.unstable_reset()</code> API (<a href="https://redirect.github.com/remix-run/react-router/pull/14206">#14206</a>)</p> </li> <li> <p>Made useOutlet element reference have stable identity in-between route chages (<a href="https://redirect.github.com/remix-run/react-router/pull/13382">#13382</a>)</p> </li> <li> <p>feat: enable full transition support for the rsc router (<a href="https://redirect.github.com/remix-run/react-router/pull/14362">#14362</a>)</p> </li> <li> <p>In RSC Data Mode, handle SSR'd client errors and re-try in the browser (<a href="https://redirect.github.com/remix-run/react-router/pull/14342">#14342</a>)</p> </li> <li> <p>Support <code>middleware</code> prop on <code><Route></code> for usage with a data router via <code>createRoutesFromElements</code> (<a href="https://redirect.github.com/remix-run/react-router/pull/14357">#14357</a>)</p> </li> <li> <p>Handle encoded question mark and hash characters in ancestor splat routes (<a href="https://redirect.github.com/remix-run/react-router/pull/14249">#14249</a>)</p> </li> <li> <p>Fail gracefully on manifest version mismatch logic if <code>sessionStorage</code> access is blocked (<a href="https://redirect.github.com/remix-run/react-router/pull/14335">#14335</a>)</p> </li> </ul> </blockquote> </details> <details> <summary>Commits</summary> <ul> <li><a href=" |