summaryrefslogtreecommitdiff
path: root/internal/namespace
diff options
context:
space:
mode:
Diffstat (limited to 'internal/namespace')
-rw-r--r--internal/namespace/namespace.go18
-rw-r--r--internal/namespace/ops.go80
2 files changed, 89 insertions, 9 deletions
diff --git a/internal/namespace/namespace.go b/internal/namespace/namespace.go
index b05dea2..a50f70a 100644
--- a/internal/namespace/namespace.go
+++ b/internal/namespace/namespace.go
@@ -6,15 +6,15 @@
// scheduler, and to maintain encrypted UDP socket connectivity over the host's network,
// wg-wrap employs an advanced bootstrap loop:
//
-// 1. Host-Bound Socket Creation: During the initial host-level start, a UDP socket is opened
-// on 0.0.0.0:0 on the host, and its FD is stored in the environment (WG_WRAP_HOST_SOCKET_FD).
-// 2. Helper Deployment: An embedded single-threaded C launcher is used to bridge the transition.
-// 3. Namespace Transition: The process replaces itself with the C launcher via syscall.Exec.
-// 4. Isolation: The launcher performs the unshare(CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWNET)
-// sequence to isolate Mount, User, and Network environments.
-// 5. Re-entry: The launcher then execvp's the original wg-wrap binary.
-// 6. FDBind Tunnel Initialization: The second instance of wg-wrap wraps the host socket FD
-// inside a custom FDBind struct to initialize wireguard-go.
+// 1. Host-Bound Socket Creation: During the initial host-level start, a UDP socket is opened
+// on 0.0.0.0:0 on the host, and its FD is stored in the environment (WG_WRAP_HOST_SOCKET_FD).
+// 2. Helper Deployment: An embedded single-threaded C launcher is used to bridge the transition.
+// 3. Namespace Transition: The process replaces itself with the C launcher via syscall.Exec.
+// 4. Isolation: The launcher performs the unshare(CLONE_NEWUSER | CLONE_NEWNS | CLONE_NEWNET)
+// sequence to isolate Mount, User, and Network environments.
+// 5. Re-entry: The launcher then execvp's the original wg-wrap binary.
+// 6. FDBind Tunnel Initialization: The second instance of wg-wrap wraps the host socket FD
+// inside a custom FDBind struct to initialize wireguard-go.
//
// User Namespace Sequence:
// To create a network namespace without root, wg-wrap follows the sequence:
diff --git a/internal/namespace/ops.go b/internal/namespace/ops.go
new file mode 100644
index 0000000..b2b5e10
--- /dev/null
+++ b/internal/namespace/ops.go
@@ -0,0 +1,80 @@
+package namespace
+
+import (
+ "os"
+
+ "git.theodohertyfamily.com/wg-wrap/internal/paths"
+)
+
+// Ops defines the set of operations required by the Manager to handle
+// namespace isolation, lifecycle, and synchronization.
+type Ops interface {
+ IsIsolated() bool
+ Bootstrap() error
+ BootstrapJoin(pid int) error
+ RegisterProcess(pm *paths.PathManager, profile string) error
+ UnregisterProcess(pm *paths.PathManager, profile string) error
+ PruneStalePids(pm *paths.PathManager, profile string) error
+ IsLastProcess(pm *paths.PathManager, profile string) (bool, error)
+ PinNamespace(pm *paths.PathManager, profile string) error
+ UnpinNamespace(pm *paths.PathManager, profile string) error
+ FindActiveProfilePid(pm *paths.PathManager, profile string) (int, error)
+ AcquireProfileLock(pm *paths.PathManager, profile string) (*os.File, error)
+ ReleaseProfileLock(file *os.File)
+}
+
+// linuxOps is the concrete implementation of Ops for Linux systems.
+type linuxOps struct{}
+
+// NewLinuxOps returns a new instance of the Linux-specific namespace operations.
+func NewLinuxOps() Ops {
+ return &linuxOps{}
+}
+
+func (l *linuxOps) IsIsolated() bool {
+ return IsIsolated()
+}
+
+func (l *linuxOps) Bootstrap() error {
+ return Bootstrap()
+}
+
+func (l *linuxOps) BootstrapJoin(pid int) error {
+ return BootstrapJoin(pid)
+}
+
+func (l *linuxOps) RegisterProcess(pm *paths.PathManager, profile string) error {
+ return RegisterProcess(pm, profile)
+}
+
+func (l *linuxOps) UnregisterProcess(pm *paths.PathManager, profile string) error {
+ return UnregisterProcess(pm, profile)
+}
+
+func (l *linuxOps) PruneStalePids(pm *paths.PathManager, profile string) error {
+ return PruneStalePids(pm, profile)
+}
+
+func (l *linuxOps) IsLastProcess(pm *paths.PathManager, profile string) (bool, error) {
+ return IsLastProcess(pm, profile)
+}
+
+func (l *linuxOps) PinNamespace(pm *paths.PathManager, profile string) error {
+ return PinNamespace(pm, profile)
+}
+
+func (l *linuxOps) UnpinNamespace(pm *paths.PathManager, profile string) error {
+ return UnpinNamespace(pm, profile)
+}
+
+func (l *linuxOps) FindActiveProfilePid(pm *paths.PathManager, profile string) (int, error) {
+ return FindActiveProfilePid(pm, profile)
+}
+
+func (l *linuxOps) AcquireProfileLock(pm *paths.PathManager, profile string) (*os.File, error) {
+ return AcquireProfileLock(pm, profile)
+}
+
+func (l *linuxOps) ReleaseProfileLock(file *os.File) {
+ ReleaseProfileLock(file)
+}