pub trait Ipc: Sealed {
type Listener: IpcListener<Stream = Self::Stream>;
type Stream: AsyncRead + AsyncWrite + Send + Unpin + 'static;
const LEAVES_STALE_ARTIFACT: bool;
// Required methods
fn bind_private(&self, id: &str) -> Result<Self::Listener>;
fn connect(
&self,
id: &str,
) -> impl Future<Output = Result<Self::Stream>> + Send;
fn authenticate_peer(&self, stream: &Self::Stream) -> Result<(), PeerReject>;
fn liveness(&self, id: &str) -> Liveness;
fn list_live(&self) -> Vec<String>;
fn artifact_path(&self, id: &str) -> Option<PathBuf>;
}Expand description
A private, same-user, local-only session endpoint.
CONTRACT: bind_private returns an endpoint reachable
only by the current user, and that restriction is applied at bind, not
after. The authorization boundary is the OS object’s own access control —
the 0600 mode on Unix, the DACL on Windows.
authenticate_peer is defence in depth and is
never the only check.
Required Associated Constants§
Sourceconst LEAVES_STALE_ARTIFACT: bool
const LEAVES_STALE_ARTIFACT: bool
Whether a dead server leaves an artifact that must be swept.
Unix: true — a socket file, hence the caller’s unlink guard. Windows:
false, because a named pipe is a kernel object that vanishes with its
last handle. The const says so, so the guard is a documented no-op
rather than dead machinery ported for symmetry.
Required Associated Types§
type Listener: IpcListener<Stream = Self::Stream>
type Stream: AsyncRead + AsyncWrite + Send + Unpin + 'static
Required Methods§
fn bind_private(&self, id: &str) -> Result<Self::Listener>
fn connect(&self, id: &str) -> impl Future<Output = Result<Self::Stream>> + Send
Sourcefn authenticate_peer(&self, stream: &Self::Stream) -> Result<(), PeerReject>
fn authenticate_peer(&self, stream: &Self::Stream) -> Result<(), PeerReject>
Reject a peer that is not the current user.
Unix: SO_PEERCRED via peer_cred(). Windows:
ImpersonateNamedPipeClient + EqualSid + RevertToSelf, which is the
correct analogue because it captures the client’s token as of the
connection.
Not GetNamedPipeClientProcessId + OpenProcess. That is the
obvious-looking answer and it is racy — the pid can be reused between
the connect and the lookup, where SO_PEERCRED cannot. Written down
because someone will propose it.
Sourcefn liveness(&self, id: &str) -> Liveness
fn liveness(&self, id: &str) -> Liveness
Is a server listening on id?
Tri-state on purpose. A two-state bool is how the Windows port ships a
bug: ERROR_PIPE_BUSY means a server exists and all its instances
are busy — i.e. LIVE. Reading it as dead makes hotl steal a running
session’s pipe name.
fn list_live(&self) -> Vec<String>
Sourcefn artifact_path(&self, id: &str) -> Option<PathBuf>
fn artifact_path(&self, id: &str) -> Option<PathBuf>
The on-disk artifact for id, when the platform has one. None on
Windows, where there is nothing to unlink.
Dyn Compatibility§
This trait is not dyn compatible.
In older versions of Rust, dyn compatibility was called "object safety".