From b41595feb96acc0e01dcdc9bb1658cba0aae33df Mon Sep 17 00:00:00 2001 From: Amir Husayn Panahifar Date: Thu, 15 Oct 2026 14:29:19 +0330 Subject: [PATCH] feat(proto): define JSON plan/result wire protocol --- internal/proto/proto.go | 111 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 111 insertions(+) create mode 100644 internal/proto/proto.go diff --git a/internal/proto/proto.go b/internal/proto/proto.go new file mode 100644 index 0000000..4de9b6d --- /dev/null +++ b/internal/proto/proto.go @@ -0,0 +1,111 @@ +// SPDX-License-Identifier: MIT + +// Package proto defines the request/response contract exchanged between the +// unprivileged prx CLI and the privileged prx-helper. +// +// The CLI resolves user configuration and sends a fully validated Plan to the +// helper. The helper never trusts the plan blindly: it re-validates every field +// before touching the system. +package proto + +// Action identifies the operation the helper must perform. +type Action string + +// Supported actions. +const ( + ActionApply Action = "apply" + ActionRemove Action = "remove" + ActionInspect Action = "inspect" + ActionEngine Action = "engine" + ActionInitEngine Action = "init-engine" +) + +// EngineOp identifies a systemd operation for the proxy engine. +type EngineOp string + +// Supported engine operations. +const ( + EngineStart EngineOp = "start" + EngineStop EngineOp = "stop" + EngineReload EngineOp = "reload" + EngineStatus EngineOp = "status" +) + +// Plan is the privileged request sent to the helper. +// +// Network fields are optional overrides; when empty the helper auto-detects the +// default interface and gateway on the host. +type Plan struct { + Action Action `json:"action"` + + // Network overrides (empty => auto-detect). + WANInterface string `json:"wan_interface,omitempty"` + WANGateway4 string `json:"wan_gateway_v4,omitempty"` + WANGateway6 string `json:"wan_gateway_v6,omitempty"` + + // Conntrack mark and policy routing identifiers. + Mark uint32 `json:"mark"` + TableV4 int `json:"table_v4"` + TableV6 int `json:"table_v6"` + PriorityV4 int `json:"priority_v4"` + PriorityV6 int `json:"priority_v6"` + + // Bypass (direct) routing identifiers. + BypassTableV4 int `json:"bypass_table_v4"` + BypassTableV6 int `json:"bypass_table_v6"` + BypassPrioV4 int `json:"bypass_priority_v4"` + BypassPrioV6 int `json:"bypass_priority_v6"` + + // BypassCIDRs are routed directly through the WAN instead of the tunnel. + BypassCIDRs []string `json:"bypass_cidrs,omitempty"` + + // Engine management. + ManageEngine bool `json:"manage_engine"` + ServiceName string `json:"service_name,omitempty"` + EngineConfig string `json:"engine_config,omitempty"` + StopEngineOnOff bool `json:"stop_engine_on_off"` + SkipEngine bool `json:"skip_engine"` + DryRun bool `json:"dry_run"` + + // EngineConfigBody carries a generated engine config for ActionInitEngine. + EngineConfigBody []byte `json:"engine_config_body,omitempty"` + + // HealthProbe is a host:port dialed after applying to confirm connectivity. + // Empty disables the probe. + HealthProbe string `json:"health_probe,omitempty"` + + // StatePath is where the helper records its snapshot (e.g. /run/prx/state.json). + StatePath string `json:"state_path"` + + // EngineOp is used with ActionEngine. + EngineOp EngineOp `json:"engine_op,omitempty"` +} + +// Check is the outcome of a single diagnostic. +type Check struct { + Name string `json:"name"` + OK bool `json:"ok"` + Detail string `json:"detail,omitempty"` + Fatal bool `json:"fatal,omitempty"` + Warn bool `json:"warn,omitempty"` +} + +// StateInfo is a compact snapshot returned for display. +type StateInfo struct { + Enabled bool `json:"enabled"` + WANInterface string `json:"wan_interface,omitempty"` + Gateway4 string `json:"gateway_v4,omitempty"` + Gateway6 string `json:"gateway_v6,omitempty"` + Mark uint32 `json:"mark"` +} + +// Result is the helper response. +type Result struct { + OK bool `json:"ok"` + Action Action `json:"action"` + Changed bool `json:"changed"` + Messages []string `json:"messages,omitempty"` + Checks []Check `json:"checks,omitempty"` + State *StateInfo `json:"state,omitempty"` + Error string `json:"error,omitempty"` +}