The FRP transport
How the embedded FRP client carries traffic, and why tunnelctl forks frp.
Under the hood, tunnelctl moves traffic with FRP (fast
reverse proxy). What's unusual is that the FRP client is embedded in the CLI — there's
no separate frpc process to install or configure, and no .toml file is written to
disk. The CLI builds the client config in memory and runs the FRP service in-process.
The path of a request
wss on port 443.<slug>.tunnelctl.eu) using the tunnel's connection token.host:port.Tuning
A couple of up flags map onto FRP behaviour:
--pool-countpre-allocates work connections so the first requests don't pay a connection-setup cost.--host-header-rewriterewrites the outgoingHostheader, which matters for local apps that route by virtual host.
Why a fork
Upstream frpc exposes no signal for control-channel connect/disconnect events.
tunnelctl maintains a small fork that adds a login-state callback, so the per-tunnel
daemon can detect when the control channel drops and transition to Reconnecting without
polling. The fork tracks upstream closely and is published under the
git.nubeo.eu/microservices/frp module path.
Daemon state from FRP
The connect/disconnect callback is what drives the Connected ↔ Reconnecting states
you see in tunnelctl status.