gglib_core/ports/remote_gateway.rs
1//! The proxy's view of the remote tunnel.
2//!
3//! `gglib-app-services` owns the tunnel (ADR 0012) and `gglib-proxy` cannot
4//! depend on it — the dependency runs the other way. What the proxy needs
5//! from the tunnel is small and fits a port: say whether `/mcp` may be
6//! reached from outside, and be told that a request arrived through the
7//! tunnel at all. Pairing is not part of it: the tunnel edge answers a
8//! pairing request itself and never forwards it. Everything else about the
9//! tunnel stays where it lives.
10//!
11//! # Design Rules
12//!
13//! - No iroh or modelpipe types: the proxy learns what it is told and never
14//! what the transport is.
15//! - Synchronous. Every implementation is a lock and a counter, and a port
16//! that forces an `await` on the request path for that would be paying
17//! for nothing.
18//! - `Debug` is a supertrait because the config that carries this derives
19//! it.
20
21/// What the proxy may ask the tunnel's owner.
22pub trait RemoteGatewayPort: Send + Sync + std::fmt::Debug {
23 /// Whether requests arriving through the tunnel may reach `/mcp`.
24 fn mcp_allowed(&self) -> bool;
25
26 /// A request marked as tunnelled reached the proxy. Counted, and the
27 /// peer remembered, for the status surface; never the request itself.
28 ///
29 /// `device` is the named token the edge says admitted it, when it named
30 /// one. Absent means a client that reached the proxy directly forged the
31 /// markers, since the edge names a device on everything it forwards,
32 /// which is why nothing is ever granted on the strength of it.
33 fn note_tunnelled_request(&self, peer: Option<&str>, device: Option<&str>);
34}