summaryrefslogtreecommitdiff
path: root/AGENTS.md
diff options
context:
space:
mode:
authorJames O'Doherty <james@theodohertyfamily.com>2026-05-29 20:11:07 -0400
committerJames O'Doherty <james@theodohertyfamily.com>2026-05-29 20:11:07 -0400
commit4ddd0d2ffc7073f2d55ffb6777e3a168af0051f0 (patch)
treeaae9afa6681f4366807b0bd70fd8bec00ab0db8d /AGENTS.md
parenta7c7fa9e76c9c7015c31378062aa5d0c17b0f38f (diff)
Refactor rootless namespace joining to use C launcher
Fix an architectural shortfall where concurrent sessions failed to share the target network and mount namespaces. Because the Go runtime is multi-threaded, calling unix.Setns with CLONE_NEWNS from Go always returned EINVAL, silently forcing concurrent runs to fall back to bootstrapping separate isolated namespaces and separate WireGuard connections. This commit resolves the issue by extending the embedded single-threaded C launcher to handle namespace joining, and introducing a host-to-isolated path propagation pattern: 1. Launcher setns Support: The C launcher now checks for WG_WRAP_JOIN_PID in the environment. If present, it joins the User, Mount, and Network namespaces of the active PID in single-threaded mode before executing the Go binary. 2. BootstrapJoin Integration: Implemented namespace.BootstrapJoin to transition joining sessions via the launcher. 3. Path Preservation: Export WG_WRAP_HOST_RUNTIME_BASE_DIR from the host to ensure the isolated instance maps the profile and PID directories to the exact same location. 4. Redundant Tunnel Bypass: Detect joined sessions via WG_WRAP_JOINED=1 in the CLI and bypass starting a duplicate WireGuard tunnel on the occupied tun0. 5. Testing: Added tests/e2e/sharing_test.go to assert namespace ID equality, which now passes successfully. 6. Git Tracking: Fixed .gitignore overmatch to stop ignoring cmd/wg-wrap/.
Diffstat (limited to 'AGENTS.md')
-rw-r--r--AGENTS.md4
1 files changed, 2 insertions, 2 deletions
diff --git a/AGENTS.md b/AGENTS.md
index c6c66df..cafff90 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -83,7 +83,7 @@ We employ a three-tier testing approach to balance speed and reliability:
### 3. Namespace Lifecycle
- **Creation**: `CLONE_NEWUSER` $\rightarrow$ `CLONE_NEWNS` $\rightarrow$ `CLONE_NEWNET` inside an embedded C launcher.
-- **Persistence & Sharing**: Namespaces are pinned and shared rootlessly. Processes record active runs inside a profile's `pids/` directory. Subsequent wrapping calls use `setns` (via `unix.Setns`) to enter the existing namespace context in $\approx 10\text{ms}$.
+- **Persistence & Sharing**: Namespaces are pinned and shared rootlessly. Processes record active runs inside a profile's `pids/` directory. Subsequent wrapping calls discover the active PID and re-execute through our single-threaded C launcher to call `setns` (joining User, Mount, and Network namespaces) in $\approx 10\text{ms}$ before the Go runtime starts, bypassing Go's multi-threaded `CLONE_NEWNS` limitation.
- **Cleanup**: When the last active process registers its exit, the reference counting detects 0 remaining sessions, automatically unpins state files, and releases resources cleanly.
## System Assumptions
@@ -99,4 +99,4 @@ The project assumes the target environment is a modern Linux system configured f
3. **Host Socket Preservation**: Open UDP sockets on the host before isolation and pass them (`WG_WRAP_HOST_SOCKET_FD`) to `wireguard-go` using `FDBind` to bypass kernel security boundaries.
4. **Data Path**: Integrate `wireguard-go` with `tun` devices seamlessly inside the namespace.
5. **Routing**: Automatically build default routing gateway tables in the isolated network namespace.
-6. **Namespace Sharing**: Connect concurrent wrapping runs to the active tunnel rootlessly via `setns`.
+6. **Namespace Sharing**: Connect concurrent wrapping runs to the active tunnel rootlessly via `setns` inside the single-threaded C launcher.