Bumps
[docker/build-push-action](https://github.com/docker/build-push-action)
from 6.11.0 to 6.13.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/docker/build-push-action/releases">docker/build-push-action's
releases</a>.</em></p>
<blockquote>
<h2>v6.13.0</h2>
<ul>
<li>Bump <code>@docker/actions-toolkit</code> from 0.51.0 to 0.53.0 in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1308">docker/build-push-action#1308</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v6.12.0...v6.13.0">https://github.com/docker/build-push-action/compare/v6.12.0...v6.13.0</a></p>
<h2>v6.12.0</h2>
<ul>
<li>Bump <code>@docker/actions-toolkit</code> from 0.49.0 to 0.51.0 in
<a
href="https://redirect.github.com/docker/build-push-action/pull/1300">docker/build-push-action#1300</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/docker/build-push-action/compare/v6.11.0...v6.12.0">https://github.com/docker/build-push-action/compare/v6.11.0...v6.12.0</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="ca877d9245"><code>ca877d9</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1308">#1308</a>
from docker/dependabot/npm_and_yarn/docker/actions-t...</li>
<li><a
href="d2fe919bb5"><code>d2fe919</code></a>
chore: update generated content</li>
<li><a
href="f0fc9ece82"><code>f0fc9ec</code></a>
chore(deps): Bump <code>@docker/actions-toolkit</code> from 0.51.0 to
0.53.0</li>
<li><a
href="67a2d409c0"><code>67a2d40</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1300">#1300</a>
from docker/dependabot/npm_and_yarn/docker/actions-t...</li>
<li><a
href="0b1b1c9c43"><code>0b1b1c9</code></a>
chore: update generated content</li>
<li><a
href="b6a7c2c4ee"><code>b6a7c2c</code></a>
chore(deps): Bump <code>@docker/actions-toolkit</code> from 0.49.0 to
0.51.0</li>
<li><a
href="31ca4e5d51"><code>31ca4e5</code></a>
Merge pull request <a
href="https://redirect.github.com/docker/build-push-action/issues/1296">#1296</a>
from crazy-max/bake-v6</li>
<li><a
href="e613db9d5a"><code>e613db9</code></a>
update bake-action to v6</li>
<li>See full diff in <a
href="b32b51a8ed...ca877d9245">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>
Bumps
[taiki-e/install-action](https://github.com/taiki-e/install-action) from
2.47.11 to 2.47.30.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/releases">taiki-e/install-action's
releases</a>.</em></p>
<blockquote>
<h2>2.47.30</h2>
<ul>
<li>
<p>Support <code>cargo-cyclonedx</code> on x86_64 Linux (musl).</p>
</li>
<li>
<p>Support installing native binary for <code>cargo-cyclonedx</code> on
AArch64 macOS. (Previously x86_64 macOS binary is used as fallback.)</p>
</li>
<li>
<p>Update <code>cargo-cyclonedx@latest</code> to 0.5.7.</p>
</li>
</ul>
<h2>2.47.29</h2>
<ul>
<li>
<p>Support <code>cargo-semver-checks</code> on AArch64 Linux.</p>
</li>
<li>
<p>Support <code>cargo-zigbuild</code> on x86_64 macOS.</p>
</li>
<li>
<p>Support installing native binary for <code>mdbook</code> and
<code>shellcheck</code> on AArch64 macOS. (Previously x86_64 macOS
binary is used as fallback.)</p>
</li>
<li>
<p>Support installing native binary for <code>just</code> and
<code>sccache</code> on AArch64 Windows. (Previously x86_64 Windows
binary is used as fallback.)</p>
</li>
<li>
<p>Update <code>mdbook@latest</code> to 0.4.44.</p>
</li>
<li>
<p>Update <code>cargo-semver-checks@latest</code> to 0.39.0.</p>
</li>
</ul>
<h2>2.47.28</h2>
<p>No change on the <code>install-action</code> itself.</p>
<ul>
<li>
<p>Provide <code>install-action-manifest-schema</code> crate to access
to the <code>install-action</code> manifests from Rust code. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/657">#657</a>,
thanks <a
href="https://github.com/NobodyXu"><code>@NobodyXu</code></a>)</p>
<p>This is being considered for use to speed up
<code>cargo-binstall</code> in the future.</p>
</li>
</ul>
<h2>2.47.27</h2>
<ul>
<li>
<p>Update <code>editorconfig-checker@latest</code> to 3.2.0.</p>
</li>
<li>
<p>Update <code>cargo-lambda@latest</code> to 1.6.3.</p>
</li>
</ul>
<h2>2.47.26</h2>
<ul>
<li>Update <code>wash@latest</code> to 0.38.0.</li>
</ul>
<h2>2.47.25</h2>
<ul>
<li>
<p>Update <code>release-plz@latest</code> to 0.3.114.</p>
</li>
<li>
<p>Update <code>git-cliff@latest</code> to 2.8.0.</p>
</li>
</ul>
<h2>2.47.24</h2>
<ul>
<li>
<p>Update <code>syft@latest</code> to 1.19.0.</p>
</li>
<li>
<p>Update <code>just@latest</code> to 1.39.0.</p>
</li>
</ul>
<h2>2.47.23</h2>
<ul>
<li>Update <code>wasmtime@latest</code> to 29.0.1.</li>
</ul>
<h2>2.47.22</h2>
<ul>
<li>Update <code>trunk@latest</code> to 0.21.7.</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/taiki-e/install-action/blob/main/CHANGELOG.md">taiki-e/install-action's
changelog</a>.</em></p>
<blockquote>
<h1>Changelog</h1>
<p>All notable changes to this project will be documented in this
file.</p>
<p>This project adheres to <a href="https://semver.org">Semantic
Versioning</a>.</p>
<!-- raw HTML omitted -->
<h2>[Unreleased]</h2>
<h2>[2.47.30] - 2025-01-28</h2>
<ul>
<li>
<p>Support <code>cargo-cyclonedx</code> on x86_64 Linux (musl).</p>
</li>
<li>
<p>Support installing native binary for <code>cargo-cyclonedx</code> on
AArch64 macOS. (Previously x86_64 macOS binary is used as fallback.)</p>
</li>
<li>
<p>Update <code>cargo-cyclonedx@latest</code> to 0.5.7.</p>
</li>
</ul>
<h2>[2.47.29] - 2025-01-28</h2>
<ul>
<li>
<p>Support <code>cargo-semver-checks</code> on AArch64 Linux.</p>
</li>
<li>
<p>Support <code>cargo-zigbuild</code> on x86_64 macOS.</p>
</li>
<li>
<p>Support installing native binary for <code>mdbook</code> and
<code>shellcheck</code> on AArch64 macOS. (Previously x86_64 macOS
binary is used as fallback.)</p>
</li>
<li>
<p>Support installing native binary for <code>just</code> and
<code>sccache</code> on AArch64 Windows. (Previously x86_64 Windows
binary is used as fallback.)</p>
</li>
<li>
<p>Update <code>mdbook@latest</code> to 0.4.44.</p>
</li>
<li>
<p>Update <code>cargo-semver-checks@latest</code> to 0.39.0.</p>
</li>
</ul>
<h2>[2.47.28] - 2025-01-28</h2>
<p>No change on the <code>install-action</code> itself.</p>
<ul>
<li>
<p>Provide <code>install-action-manifest-schema</code> crate to access
to the <code>install-action</code> manifests from Rust code. (<a
href="https://redirect.github.com/taiki-e/install-action/pull/657">#657</a>,
thanks <a
href="https://github.com/NobodyXu"><code>@NobodyXu</code></a>)</p>
<p>This is being considered for use to speed up
<code>cargo-binstall</code> in the future.</p>
</li>
</ul>
<h2>[2.47.27] - 2025-01-28</h2>
<ul>
<li>
<p>Update <code>editorconfig-checker@latest</code> to 3.2.0.</p>
</li>
<li>
<p>Update <code>cargo-lambda@latest</code> to 1.6.3.</p>
</li>
</ul>
<h2>[2.47.26] - 2025-01-27</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="afbe5c1715"><code>afbe5c1</code></a>
Release 2.47.30</li>
<li><a
href="6fde044d27"><code>6fde044</code></a>
codegen: Address cargo-cyclonedx 0.5.1 asset change</li>
<li><a
href="544f616845"><code>544f616</code></a>
ci: Remove not triggered manifest_sync workflow</li>
<li><a
href="3b94b1e00e"><code>3b94b1e</code></a>
Release 2.47.29</li>
<li><a
href="f07d824129"><code>f07d824</code></a>
Update .gitattributes</li>
<li><a
href="fc5961fb83"><code>fc5961f</code></a>
codegen: cargo-zigbuild's macOS binary is universal binary</li>
<li><a
href="df3b728223"><code>df3b728</code></a>
codegen: Sort platform</li>
<li><a
href="58e7e8a24b"><code>58e7e8a</code></a>
codegen: Mark go's static-linked linux binaries as musl</li>
<li><a
href="1d9ff62a86"><code>1d9ff62</code></a>
codegen: shellcheck 0.10.0+ provides AArch64 macOS binary</li>
<li><a
href="85a4a5fd84"><code>85a4a5f</code></a>
codegen: sccache 0.8.2+ provides AArch64 Windows binary</li>
<li>Additional commits viewable in <a
href="c87777c316...afbe5c1715">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>
There isn't a good reason why we're using a Makefile instead of regular
Bash script for bumping versions, so this PR fixes that for better
maintainability.
It also reduces then chances for merge conflicts when bumping version
because the versions are longer on adjacent lines.
Fixes: #7904
Recently, we changed that we only upload binaries to the draft releases
when we actively call the workflow. This means that we may potentially
have a drift between:
- The commit that gets tagged as the release.
- The commit from which the binaries got built.
To ensure that this doesn't drift, we only update the draft releases
whenever we actually uploaded new binaries to them. In addition, we
instruct `release-drafter` to set the target of the release to the
commit SHA from when it was triggered. As a result, it is much less
error prone that these may drift apart. I believe the only race
condition here could be if somebody publishes a release between the time
the binaries get uploaded and we update the release draft, i.e. when
GitHub hasn't fully finished CI yet.
---------
Signed-off-by: Jamil <jamilbk@users.noreply.github.com>
Co-authored-by: Jamil <jamilbk@users.noreply.github.com>
In #7795, we optimised our CI pipeline to only test the installation of
the GUI client whenever we actually upload to the draft release. This
trigger has been moved to `workflow_dispatch`, meaning no CI builds
neither from PRs nor `main` perform these steps.
This makes it difficult to test GUI client binaries from PRs because
they also no longer get uploaded to the artifacts of the CI run on the
PR.
To fix this, we split the testing away from the rename script and
unconditionally run the rename script, which allows us to also always
upload the binaries to the CI artifacts.
Finally, uploading to the draft releases is only done when we explicitly
trigger the workflow from `main`. This is a defense-in-depth measure: We
should never publish a code to a release that hasn't been merged to
`main`.
If the PR title violates the length check, editing it and re-running the
job wouldn't fix it because the original title was still referenced.
To fix this, we introduce a trigger for this check that runs
specifically on PR edit.
Similar to the Apple and Android clients, this PR updates the Linux and
Windows GUI clients to upload to the GitHub drafted release on manual
workflow triggers only.
This should save a few minutes off `main` builds as the extra package
testing steps will now be skipped there.
Notably, the Gateway and Headless Client workflows are unchanged because
(a) they are much faster to build / test and (b) we use the release
builds for performance testing connlib, so we need them to run on
`main`.
We try to unit test on each major platform we support in CI to reduce
the possibility a specific OS has issues with our unit tests. Now that
macos-15 is available in GitHub CI, it would be a good idea to add it to
the mix.
To improve supply-chain security, reference all GitHub actions using the
hash of the released tag. GitHub recommends to do this for third-party
actions
(https://docs.github.com/en/actions/security-for-github-actions/security-guides/security-hardening-for-github-actions#using-third-party-actions).
In order to make our CI more deterministic, I opted to do it for all our
actions. This means any change to our workflow configuration requires a
source code change and thus passing CI on our end.
Dependabot will automatically issue PRs for these actions and update the
comment with the new version next to them.
Resolves: #2497.
`sentry-cli debug-files upload` offers no option to exclude certain
files or directories when recursively searching the given path. Thus, we
need to remove this staging directory to prevent it from recursively
walking the directory and inevitably erroring out when it hits a path it
doesn't have access to.
The application-split itself doesn't really warrant having two different
Sentry projects.
1. The location of the panic / log already tells us, which component is
failing.
2. Both of the projects are built with Rust so the same "platform"
setting applies.
3. Reducing the number of Sentry projects makes things easier to manage.
4. The binaries are started as independent processes, so the two Sentry
contexts don't interfere.
What we should keep in mind is that one instance of an application will
now log into Sentry twice using the same DSN. I _think_ this means that
the number of sessions listed in Sentry will be double the number of
actual client-runs. The same is true for the Apple client though and
once we integrate Sentry for Android, the same will apply there so
relative to each other, those numbers still make sense.
- Refactor the way we build download links on the Changelog page to make
them more flexible
- Add Android download redirects
- Update user-facing docs to mention new download options
Bumps
[hashicorp/tfc-workflows-github](https://github.com/hashicorp/tfc-workflows-github)
from 1.3.1 to 1.3.2.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/hashicorp/tfc-workflows-github/releases">hashicorp/tfc-workflows-github's
releases</a>.</em></p>
<blockquote>
<h2>v1.3.2</h2>
<ul>
<li>Bug fixes and enhancements from <a
href="https://github.com/hashicorp/tfc-workflows-tooling/releases/tag/v1.3.2">tfc-workflows-tooling@v1.3.2</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/hashicorp/tfc-workflows-github/blob/main/CHANGELOG.md">hashicorp/tfc-workflows-github's
changelog</a>.</em></p>
<blockquote>
<h1>v1.3.2</h1>
<ul>
<li>Bug fixes and enhancements from <a
href="https://github.com/hashicorp/tfc-workflows-tooling/releases/tag/v1.3.2">tfc-workflows-tooling@v1.3.2</a></li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="8e08d1ba95"><code>8e08d1b</code></a>
Prepare v1.3.2 release (<a
href="https://redirect.github.com/hashicorp/tfc-workflows-github/issues/2981">#2981</a>)</li>
<li><a
href="2a0a556cba"><code>2a0a556</code></a>
[COMPLIANCE] Update MPL-2.0 LICENSE (<a
href="https://redirect.github.com/hashicorp/tfc-workflows-github/issues/2980">#2980</a>)</li>
<li><a
href="b15578fa52"><code>b15578f</code></a>
Merge pull request <a
href="https://redirect.github.com/hashicorp/tfc-workflows-github/issues/2976">#2976</a>
from salilsub/main</li>
<li><a
href="030a2307e5"><code>030a230</code></a>
Adding GITHUB_TOKEN link to README</li>
<li><a
href="833d60e689"><code>833d60e</code></a>
Adding information about setting the GITHUB_TOKEN permissions</li>
<li>See full diff in <a
href="https://github.com/hashicorp/tfc-workflows-github/compare/v1.3.1...v1.3.2">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>
Unfortunately Apple's API doesn't expect to be hit this frequently and
also doesn't respond with obvious errors when we ask too much of it.
Because of this, we move the App Store connect upload back to manual
trigger only, and update the standalone upload to GitHub releases to the
same because it needs to hit Apple's notary service API.
- Attaching the standalone client needs to happen on `main` runs, like
the other clients
- GitHub can't seem to find the release. I suspect the
`GITHUB_REPOSITORY` var is unneeded.
The CI swift workflow needs to be updated to accommodate the macOS
standalone build. This required a decent amount of refactoring to make
the Apple build process more maintainable.
Unfortunately this PR ended up being a giant ball of yarn where pulling
on one thread tended to unravel things elsewhere, since building the
Apple artifacts involve multiple interconnected systems. Combined with
the slow iteration of running in CI, I wasn't able to split this PR into
easier to digest commits, so I've annotated the PR as much as I can to
explain what's changed.
The good news is that Apple release artifacts can now be easily built
from a developer's machine with simply
`scripts/build/macos-standalone.sh`. The only thing needed is the proper
provisioning profiles and signing certs installed.
Since this PR is so big already, I'll save the swift/apple/README.md
updates for another PR.
Standalone distribution requires using a different signing identity
(certificate), set of provisioning profiles, and (annoyingly) requires
the `-systemextension` suffix for our network extension capabilities.
This PR prepares the Xcode environment for building a Standalone app in
CI that will be notarized by matching certificates and provisioning
profiles in our Apple Developer account.
Currently, the Gateway logs all errors that happen when the event-loop
exits on ERROR level. This creates Sentry alerts for things like
"Unauthorized" errors or "404 Not found".
That isn't useful to us. To mitigate this, we polish the code a bit to
only log an ERROR when we actually fail to setup something during
startup (like the TUN device). In all other cases, we now log a more
user-friendly message on INFO but still exit with the appropriate exit
code (0 on CTRL+C, 1 on any other error).
In order to release the new control protocol to users, we need to bump
the versions of the clients to 1.4.0. The portal has a version gate to
only select gateways with version >= 1.4.0 for clients >= 1.4.0. Thus,
bumping these versions can only happen once testing has completed and
the gateway has actually been released as 1.4.0.
Co-authored-by: Jamil Bou Kheir <jamilbk@users.noreply.github.com>
## Context
The Gateway implements a stateful NAT that translates the destination IP
and source protocol of every packet that targets a DNS resource IP. This
is necessary because the IPs for DNS resources are generated on the
client without actually performing a DNS lookup, instead it always
generates 4 IPv4 and 4 IPv6 addresses. On the Gateway, these IPs are
then assigned in a round-robin fashion to the actual IPs that the domain
resolves to, necessitating a NAT64/46 translation in case a domain only
resolves to IPs of one family.
A domain may resolve to a set of IPs but not all of these IPs may be
routable. Whilst an arguably poor practise of the domain administrator,
routing problems can occur for all kinds of reasons and are well handled
on the wider Internet.
When an IP packet cannot be routed further, the current routing node
generates an ICMP error describing the routing failure and sends it back
to the original sender. ICMP is a layer 4 protocol itself, same as TCP
and UDP. As such, sending out a UDP packet may result in receiving an
ICMP response. In order to allow the sender to learn, which packet
failed to route, the ICMP error embeds parts of the original packet in
its payload [0] [1].
The Gateway's NAT table uses parts of the layer 4 protocol as part of
its key; the UDP and TCP source port and the ICMP echo request
identifier (further referred to as "source protocol"). An ICMP error
message doesn't have any of these, meaning the lookup in the NAT table
currently fails and the ICMP error is silently dropped.
A lot of software implements a happy-eyeballs approach and probs for
IPv6 and IPv4 connectivity simulataneously. The absence of the ICMP
errors confuses that algorithm as it detects the packet loss and starts
retransmits instead of giving up.
## Solution
Upon receiving an ICMP error on the Gateway, we now extract the
partially embedded packet in the ICMP error payload. We use the
destination IP and source protocol of _that_ packet for the lookup in
the NAT table. This returns us the original (client-assigned)
destination IP and source protocol. In order for the Gateway's NAT to be
transparent, we need to patch the packet embedded in the ICMP error to
use the original destination and source protocol. We also have to
account for the fact that the original packet may have been translated
with NAT64/46 and translate it back. Finally, we generate an ICMP error
with the appropriate code and embed the patched packet in its payload.
## Test implementation
To test that this works for all kind of combinations, we extend
`tunnel_test` to sample a list of unreachable IPs from all IPs sampled
for DNS resources. Upon receiving a packet for one of these IPs, the
Gateway will send an ICMP error back instead of invoking its regular
echo reply logic. On the client-side, upon receiving an ICMP error, we
extract the originally failed packet from the body and treat it as a
successful response.
This may seem a bit hacky at first but is actually how operating systems
would treat ICMP errors as well. For example, a `TcpSocket::connect`
call (triggering a TCP SYN packet) may fail with an IO error if we
receive an ICMP error packet. Thus, in a way, the original packet got
answered, just not with what we expected.
In addition, by treating these ICMP errors as responses to the original
packet, we automatically perform other assertions on them, like ensuring
that they come from the right IP address, that there are no unexpected
packets etc.
## Test alternatives
It is tricky to solve this in other ways in the test suite because at
the time of generating a packet for a DNS resource, we don't know the
actual IP that is being targeted by a certain proxy IP unless we'd start
reimplementing the round-robin algorithm employed by the Gateway. To
"test" the transparency of the NAT, we'd like to avoid knowing about
these implementation details in the test.
## Future work
In this PR, we currently only deal with "Destination Unreachable" ICMP
errors. There are other ICMP messages such as ICMPv6's `PacketTooBig` or
`ParameterProblem`. We should eventually handle these as well. They are
being deferred because translating those between the different IP
versions is only partially implemented and would thus require more work.
The most pressing need is to translate destination unreachable errors to
enable happy-eyeballs algorithms to work correctly.
Resolves: #5614.
Resolves: #6371.
[0]: https://www.rfc-editor.org/rfc/rfc792
[1]: https://www.rfc-editor.org/rfc/rfc4443#section-3.1