microsandbox_control_client/dialer.rs
1//! Identity continuity is supplied by the runtime owner, never inferred from a path.
2
3use std::sync::Arc;
4
5use microsandbox_protocol_client::{BoxFuture, BoxTransport, Connector};
6use tokio::time::Instant;
7
8use crate::ControlClientResult;
9
10//--------------------------------------------------------------------------------------------------
11// Types
12//--------------------------------------------------------------------------------------------------
13
14/// A connector that binds every returned stream to one verified runtime.
15///
16/// Implementations must verify the connected peer's process identity and stable
17/// OS birth token on every dial, not merely check a PID or endpoint path. The
18/// backend owns database/run identity and keeps any required OS process handles.
19pub trait VerifiedControlConnector: Send + Sync {
20 /// Open a stream and verify its connected peer before returning ownership.
21 /// Peer replacement is `RuntimeChanged`, distinct from a transport failure.
22 fn connect(&self, deadline: Instant) -> BoxFuture<'_, ControlClientResult<BoxTransport>>;
23
24 /// Recheck the active run and process identity immediately before admitting
25 /// an operation. Return `RuntimeChanged` if continuity no longer holds.
26 fn verify_session(&self, deadline: Instant) -> BoxFuture<'_, ControlClientResult<()>>;
27}
28
29#[derive(Clone)]
30pub(crate) enum Dialer {
31 Unverified(Arc<dyn Connector>),
32 Verified(Arc<dyn VerifiedControlConnector>),
33}
34
35//--------------------------------------------------------------------------------------------------
36// Methods
37//--------------------------------------------------------------------------------------------------
38
39impl Dialer {
40 pub(crate) fn verified(&self) -> bool {
41 matches!(self, Self::Verified(_))
42 }
43
44 pub(crate) async fn connect(&self, deadline: Instant) -> ControlClientResult<BoxTransport> {
45 Ok(match self {
46 Self::Unverified(connector) => connector.connect(deadline).await?,
47 Self::Verified(connector) => connector.connect(deadline).await?,
48 })
49 }
50
51 pub(crate) async fn verify(&self, deadline: Instant) -> ControlClientResult<()> {
52 match self {
53 Self::Unverified(_) => Ok(()),
54 Self::Verified(connector) => connector.verify_session(deadline).await,
55 }
56 }
57}