Skip to content

Commit f77b248

Browse files
Ryanmello07claude
andcommitted
fix(flatpak): pin libdir=lib; deb depends on nftables; require the rpm again
flatpak: the gtkmm stack built into /app/lib64 while flatpak-builder's default PKG_CONFIG_PATH covers /app/lib/pkgconfig only. libsigc++ compiled and installed perfectly, then glibmm reported "Run-time dependency sigc++-3.0 found: NO", fell back to its meson wrap, and tried to `git clone` libsigcplusplus inside a build sandbox with no network. The reported error names git and glibmm and says nothing about libdir or about the module that misplaced its .pc file. Pinned --libdir=lib on the six meson modules individually rather than globally, because nlohmann-json is cmake and would choke on it, and pinned rather than widening PKG_CONFIG_PATH because the runtime loader searches /app/lib too. deb: declare nftables. main.cpp's preflight marks `nft` required=true and the tunnel needs it for the egress self-exclusion, the IPv6 and DNS floors and the kill switch -- but only the rpm declared it. On a minimal Debian/Ubuntu the package installed cleanly, the service started cleanly, and the first Connect failed on a missing tool instead of apt saying what was needed. Declaring dependencies is the entire reason to ship a native package. UR_REQUIRE_RPM back to "true": v2026.8.16-1020748320-beta is the first release that published an rpm, SELinux policy module built on the jammy container included -- which is what the flag was held open for. 5 assets now. Also: --revert now warns that it restores /etc/resolv.conf, so nobody runs it as a "cleanup" against a live session on a host where tier 3 holds DNS; --help and the recovery text say the same; and ControlProtocol's dns_detail comment no longer claims the field is empty on success (it always carries a line now). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01MAXFxG1EK4jTxQ1iW73BUr
1 parent 21869ec commit f77b248

5 files changed

Lines changed: 47 additions & 17 deletions

File tree

.github/workflows/beta-build.yml

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -173,17 +173,16 @@ env:
173173
# and the release publishes the other assets. It must go back to "true" --
174174
# a silent-missing-rpm mode is exactly how the .deb would have quietly
175175
# stopped shipping.
176-
# CURRENTLY "false" FOR EXACTLY ONE REASON, AND IT IS TEMPORARY: the .rpm has
177-
# never been built by CI. It builds on a Fedora host (verified end to end:
178-
# exit 0, ~15 MB, 123 payload entries), but jammy's SELinux tooling split is
179-
# different and the build-host .pp has never been produced there. Until one
180-
# green run proves it, an rpm problem must not be able to take the four
181-
# already-contracted assets (tarball, .deb, AppImage, .zsync) off the
182-
# release -- turning a missing fifth asset into a release of nothing is a
183-
# strictly worse outcome than shipping four.
184-
# FLIP BACK TO "true" the moment a run publishes an .rpm. A silent-missing-rpm
185-
# mode left on permanently is exactly how the .deb would quietly stop shipping.
186-
UR_REQUIRE_RPM: "false"
176+
# Back to "true" as of v2026.8.16-1020748320-beta, which is the first release
177+
# that actually PUBLISHED an rpm (5 assets: tarball, .deb, .rpm, AppImage,
178+
# .zsync) with the SELinux policy module compiled on the jammy container --
179+
# the thing this was held open for. A silent-missing-rpm mode left on
180+
# permanently is exactly how the .deb would quietly stop shipping.
181+
#
182+
# It was briefly "false" while the rpm was landing, and that is the right
183+
# move again if the rpm ever breaks: a new package that cannot build must not
184+
# take the four already-contracted assets off the release with it.
185+
UR_REQUIRE_RPM: "true"
187186
# The Flatpak has NO equivalent knob here on purpose: a job-level `if:`
188187
# cannot read the `env` context (only github/needs/vars/inputs), so its kill
189188
# switch is the repository VARIABLE `UR_BUILD_FLATPAK` -- set it to "false"

app/src/ControlProtocol.hpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -572,7 +572,7 @@ struct StatusReply {
572572
// starving and the session cannot carry traffic.
573573
bool egress_protected = false;
574574
bool dns_applied = false;
575-
std::string dns_detail; // why DNS is not in force ("" when it is)
575+
std::string dns_detail; // always set: which tier holds DNS, or why none could
576576
KillSwitchState kill_switch = KillSwitchState::Off;
577577
std::string kill_switch_detail; // why it is Failed ("" otherwise)
578578
bool ipv6_blocked = false; // v6 has no tunnel: blocked rather than leaked

app/src/daemon/main.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ void PrintRecovery(const char* argv0) {
143143
" sudo systemctl stop urnetworkd\n"
144144
" sudo %s --revert\n"
145145
"\n"
146-
" --revert removes the firewall table, the policy rules, the capture routes and the\n"
147-
" armed marker, so the next start comes up open. With no systemd and no working\n"
148-
" daemon binary, the firewall half alone is:\n"
146+
" --revert removes the firewall table, the policy rules, the capture routes, any\n"
147+
" /etc/resolv.conf takeover and the armed marker, so the next start comes up open.\n"
148+
" With no systemd and no working daemon binary, the firewall half alone is:\n"
149149
"\n"
150150
" %s\n"
151151
"\n"
@@ -902,7 +902,11 @@ int main(int argc, char** argv) {
902902
std::fprintf(stderr,
903903
"urnetworkd --revert: WARNING — %s still exists, so urnetworkd may still be "
904904
"running. It re-installs its own ruleset within seconds of anything removing "
905-
"it; stop it first (systemctl stop urnetworkd) or this will not stick.\n",
905+
"it; stop it first (systemctl stop urnetworkd) or this will not stick.\n"
906+
" This sweep ALSO restores /etc/resolv.conf if a tunnel took it over. On a "
907+
"host with no systemd-resolved that is how DNS reaches the tunnel, so running "
908+
"this against a LIVE session pulls the tunnel's resolver out from under it "
909+
"and names stop resolving until you reconnect.\n",
906910
urnw::ControlServer::SocketPath().c_str());
907911
}
908912
// Whether the sweep is SUPPOSED to leave a table behind, decided before
@@ -949,7 +953,7 @@ int main(int argc, char** argv) {
949953
" touches no routes, no nftables and no DNS; sends no packet.\n"
950954
" Needs root (bpf() does). Exit 0 = works, 1 = does not,\n"
951955
" 2 = could not be measured\n"
952-
" --revert lift the URnetwork firewall table, policy rules and capture\n"
956+
" --revert lift the URnetwork firewall table, policy rules, capture\n"
953957
" routes, and clear the armed marker; then exit. Run this when\n"
954958
" a machine is stuck blocked. Requires root.\n"
955959
" --revert-unless-armed the same sweep, but a machine that was armed when the daemon\n"

packaging/deb/nfpm.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ depends:
5151
# Tunnel.cpp configures the TUN link and its capture routes with /sbin/ip.
5252
# Minimal Ubuntu/Debian installations do not necessarily include it.
5353
- "iproute2"
54+
# nftables is NOT optional and was missing here while the rpm declared it.
55+
# app/src/daemon/main.cpp's preflight marks `nft` required=true, and the
56+
# tunnel uses it for the egress self-exclusion (without which the daemon's
57+
# OWN sockets fall into its own tunnel -- a measured 3.38 Tb amplification
58+
# loop, not a theoretical one), the IPv6 and DNS leak floors, and the kill
59+
# switch. Debian and Ubuntu do not install it on a minimal system, so the
60+
# package installed cleanly, the service started cleanly, and the first
61+
# Connect failed with a message about a missing tool rather than apt saying
62+
# what was needed. Declared as a dependency, which is the whole reason to
63+
# ship a native package instead of a tarball.
64+
- "nftables"
5465
# The one genuine win of the deb shape (APPIMAGE.md 11d): the GUI AppImage
5566
# needs libfuse2 at runtime and Ubuntu 22.04+ does not ship it by default,
5667
# so every AppImage-only vendor walks users through installing it by hand.

packaging/flatpak/network.ur.urnetwork.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,16 @@ cleanup:
8888
- '*.a'
8989
- '*.la'
9090

91+
# EVERY MESON MODULE BELOW MUST INSTALL INTO /app/lib, NOT /app/lib64.
92+
# meson's default libdir on this SDK resolves to lib64, and flatpak-builder's
93+
# default PKG_CONFIG_PATH covers /app/lib/pkgconfig only. The failure that
94+
# causes is deeply unhelpful: libsigc++ builds and installs perfectly, then
95+
# glibmm reports "Run-time dependency sigc++-3.0 found: NO", falls back to its
96+
# wrap, and tries to `git clone` libsigcplusplus -- inside a build sandbox with
97+
# no network. The error you see names git and glibmm, and says nothing about
98+
# libdir or about the module that actually misplaced its .pc file. The runtime
99+
# loader has the same blind spot (/app/lib is what it searches), so pinning
100+
# libdir is the fix rather than widening PKG_CONFIG_PATH.
91101
modules:
92102
# ---- the gtkmm stack --------------------------------------------------
93103
# org.gnome.Sdk 49 carries GTK 4.20 and libadwaita 1.8 but NO C++ bindings,
@@ -97,6 +107,7 @@ modules:
97107
- name: libsigc++
98108
buildsystem: meson
99109
config-opts:
110+
- --libdir=lib
100111
- -Dbuild-documentation=false
101112
- -Dbuild-examples=false
102113
sources:
@@ -107,6 +118,7 @@ modules:
107118
- name: glibmm
108119
buildsystem: meson
109120
config-opts:
121+
- --libdir=lib
110122
- -Dbuild-documentation=false
111123
- -Dbuild-examples=false
112124
sources:
@@ -119,6 +131,7 @@ modules:
119131
- name: cairomm
120132
buildsystem: meson
121133
config-opts:
134+
- --libdir=lib
122135
- -Dbuild-documentation=false
123136
- -Dbuild-examples=false
124137
- -Dbuild-tests=false
@@ -130,6 +143,7 @@ modules:
130143
- name: pangomm
131144
buildsystem: meson
132145
config-opts:
146+
- --libdir=lib
133147
- -Dbuild-documentation=false
134148
sources:
135149
- type: archive
@@ -139,6 +153,7 @@ modules:
139153
- name: gtkmm
140154
buildsystem: meson
141155
config-opts:
156+
- --libdir=lib
142157
- -Dbuild-documentation=false
143158
- -Dbuild-demos=false
144159
- -Dbuild-tests=false
@@ -162,6 +177,7 @@ modules:
162177
buildsystem: meson
163178
subdir: app
164179
config-opts:
180+
- --libdir=lib
165181
- -Dgui=enabled
166182
# Drops urnetworkd and the four host-integration files that install to
167183
# ABSOLUTE paths (/lib/systemd/system, /etc/urnetwork, /etc/NetworkManager,

0 commit comments

Comments
 (0)