Skip to main content

Hosts

Struct Hosts 

Source
pub struct Hosts { /* private fields */ }

Implementations§

Source§

impl Hosts

Source

pub fn hats(&self) -> Result<Vec<HatRecord>>

Every hat of the owner, oldest first.

Source

pub fn hat(&self, hat_id: &str) -> Result<Option<HatRecord>>

Source

pub fn default_hat_for_new_hosts(&self) -> Result<String>

The hat newly paired hosts get as their default.

Source

pub fn create_hat( &self, name: &str, colour: Option<&str>, now: i64, ) -> Result<HatChange>

A new hat, colour defaulting to DEFAULT_COLOUR.

Source

pub fn update_hat( &self, hat_id: &str, name: Option<&str>, colour: Option<&str>, default_for_new_hosts: Option<bool>, ) -> Result<HatChange>

Rename a hat, change its colour, or make it the one new hosts get. A hat stops being that default only by another taking its place, so default_for_new_hosts is Some(true) or absent.

Source

pub fn path_rules(&self, host_id: &str) -> Result<Option<Vec<PathRule>>>

A host’s path rules, longest prefix first; None for an unknown host.

Source

pub fn replace_path_rules( &self, host_id: &str, rules: &[NewRule], ) -> Result<RulesChange>

Replace a host’s path rules with rules, in one transaction (kernel spec §8: the full set). Each prefix must already be canonical and each hat the owner’s; no two rules share a prefix. / is refused: it is what the host’s default hat is for (the review’s O2). So is a prefix with an invisible format character, which could display as another path (O6). A rule whose prefix was there before keeps its id.

Source

pub fn resolve_hat( &self, host_id: &str, path: &str, ) -> Result<Option<Resolution>>

The hat path resolves to on host_id (kernel spec §5.2), from one read of the host’s default hat and its rules; None for an unknown host. path must be canonical: anything else is an error, never a guess.

Source

pub fn session_hat( &self, host_id: &str, path: &str, ) -> Result<Option<SessionHat>>

The hat a session whose canonical cwd is path gets on host_id (umbrella §8.2), unless a rule that misses only by case makes it ambiguous (near_miss); None for an unknown host. path must be canonical. The host’s default hat and its rules are read in one transaction, so a rules change or a default change committed in between cannot mix the old one with the new (plan 5a’s final review).

Source

pub fn rules_name_other_hats(&self, host_id: &str) -> Result<bool>

Whether one of the host’s rules names a hat other than its default: rules only. This is half of whether the host is mixed (umbrella §8.5), which the gateway’s fallback needs; the other half is a live session of another hat than the default (a default changed since it started), which only the sessions module knows (the review’s A1). false for an unknown host.

Source

pub fn update_host( &self, host_id: &str, name: Option<&str>, default_hat_id: Option<&str>, ) -> Result<HostChange>

Rename a host, or change its default hat (kernel spec §4.3), in one transaction. The hat must be the owner’s.

Source

pub fn is_default_hat(&self, hat_id: &str) -> Result<bool>

Whether hat_id is the hat new hosts get or a host’s default hat, a revoked host’s included (plan 9c decision 10a): what a purge refuses.

Source

pub fn is_frozen(&self, hat_id: &str) -> Result<bool>

Whether a purge of hat_id began (plan 9c decision 10c): from then on nothing starts, resumes or moves in or out of it, and it is no hat for a rule or a host’s default. Stays true once the purge is done (A7).

Source

pub fn begin_purge(&self, hat_id: &str, now: i64) -> Result<PurgeStart>

Freeze hat_id for its purge (kernel spec §5.5; plan 9c decision 10c), in one transaction that re-checks it is no default (A2): record it in purged_hats, unless a purge before did, and delete every rule that names it, on every host. Again on a frozen hat it freezes again, and takes any rule that names it, so a purge that stopped resumes from here.

Source

pub fn finish_purge(&self, hat_id: &str) -> Result<bool>

The last step of hat_id’s purge (plan 9c decision 10e): delete the hat’s row, only while it is frozen; its project recents go with it (ON DELETE CASCADE). Its purged_hats row stays (A7). false if there was no frozen hat to delete. Whatever still references the hat (a rule, a host’s default, a module’s row) fails it, by its foreign key: the hooks ran first.

Source

pub fn purged_hats(&self) -> Result<Vec<String>>

Every hat the owner purged or is purging, the oldest purge first: what forget_hat tells a host after its handshake (plan 9c decision 12, A7).

Source

pub fn purge_counts(&self, hat_id: &str) -> Result<(u64, u64)>

How many path rules name hat_id, and how many project recents it has, on every host: what a purge would delete of the kernel’s (plan 9c decision 11).

Source§

impl Hosts

Source

pub fn open(path: &Path) -> Result<Self>

Open the kernel’s tables in hennery.db (shared with the sessions store; each migrates only its own tables).

Source

pub fn open_in_memory() -> Result<Self>

Source

pub fn owner_id(&self) -> &str

The owner whose hosts and codes these are.

Source

pub fn mint_pairing_code(&self, now: i64) -> Result<PairingCode>

Mint a single-use pairing code valid for PAIRING_CODE_TTL_SECS. Only its hash is stored. Spent and expired codes are deleted first, even when the mint is then refused (TooManyPairingCodes) because MAX_LIVE_PAIRING_CODES are live, so the table stays bounded.

Source

pub fn mint_local_pairing_code(&self, now: i64) -> Result<PairingCode>

mint_pairing_code for hennery up’s own host, once at start: not capped, so live codes minted by the operator can never stop the all-in-one from pairing its host (a host that cannot pair ends up). Spent and expired codes are still deleted.

Source

pub fn enroll( &self, code: &str, enrollment: &Enrollment, now: i64, ) -> Result<EnrollOutcome>

Pair a host with a code (kernel spec §4.1): check the code, create the host with a fresh id, and use the code up, in one transaction. A wrong code changes nothing, so other outstanding codes stay valid.

The spend at the end repeats the same guard as the read at the start (used_at IS NULL AND expires_at > now), so a second writer that raced past the read still cannot double-spend the code: whichever commits first wins, and the loser’s UPDATE matches zero rows and is rolled back along with the host it tentatively inserted. Today the per-Hosts mutex already serializes every call through one connection, so this only matters across two Hosts instances (or connections) open on the same file — which is already possible (the sessions store opens its own) — and matters more once §1’s single writer thread is not the only thing standing between two writers.

Source

pub fn register( &self, host_id: &str, enrollment: &Enrollment, now: i64, ) -> Result<Registered>

Store a host under a known id, without a code: what enroll does once the code checks out. Also how tests pair a host under a fixed id.

Source

pub fn check_hello( &self, host_id: &str, nonce: &[u8], protocol_version: &str, proof: &str, ) -> Result<HelloCheck>

Check a hello (ACP core §3.5). The proof is verified before the revocation is looked at, so revoked is only ever told to the holder of the key.

Source

pub fn record_hello( &self, host_id: &str, host_version: &str, capabilities: &Capabilities, now: i64, ) -> Result<()>

Update what an accepted hello reports (kernel spec §4.3).

host_version is checked against the same shape enrollment requires (kernel spec §4.1) before it is stored. The host is authenticated at this point, but its self-reported version string is still its own words, not ours: a host misbehaving or compromised after pairing should not be able to overwrite a good version with an oversized one or one hiding characters, the same way a name could (decision 5). A hello failing only this check is not otherwise refused — the signature is genuine, capabilities and last_seen_at still move — the least surprising reading of a hello that is real but reports a version nobody should have to display.

Source

pub fn record_mcp_isolation( &self, host_id: &str, isolation: &AgentIsolation, ) -> Result<()>

Store the per-agent MCP isolation of an accepted hello (plan 8e decision E7), for the host list while the host is away. The host’s own words, bounded as the other reported fields are: at most MAX_AGENTS agents, each id displayable and at most 64 bytes; others are left out.

Source

pub fn record_workspace_roots( &self, host_id: &str, reported: &[String], ) -> Result<()>

Store the workspace roots a reconciled connection of host_id reported (decision 7): the first MAX_ROOTS that is_displayable_path accepts. Only a reconciled connection’s count: hennery host join’s probe sends a hello that knows nothing of host run’s flags.

Source

pub fn is_revoked(&self, host_id: &str) -> Result<bool>

Source

pub fn revoke(&self, host_id: &str, now: i64) -> Result<Revoke>

Mark a host revoked (kernel spec §4.3). Its future hellos get revoked; closing its connection and parking its sessions is the caller’s part.

The read above try_revoke is only ever a hint, not a guarantee: unlike enroll’s check-then-spend, this is two separate statements on an autocommit connection, not one transaction, so nothing but try_revoke’s own guard stops a second writer that already read “not revoked” from overwriting a revoke that has since landed. If it matches nothing for that reason, that is exactly AlreadyRevoked — a repeated revoke is harmless either way.

Source

pub fn host(&self, host_id: &str) -> Result<Option<HostRecord>>

Source

pub fn list(&self) -> Result<Vec<HostRecord>>

Every paired host, revoked ones included, oldest first.

Source§

impl Hosts

hat_id’s logo, if the owner has that hat and it has one.

Give hat_id logo, replacing any it had: Done with the hat as it is now; NotFound; or Purging for a hat frozen for its purge, which keeps the logo it had. The freeze is checked in the statement that would set it (plan 9c decision 10c).

Take hat_id’s logo away, if it has one: Done with the hat as it is now, or NotFound. A frozen hat’s logo goes too: that is the purge’s own direction (the review’s A6).

Source§

impl Hosts

Source

pub fn subscribe( &self, new: &NewSubscription<'_>, auth_session: &str, now: i64, ) -> Result<Subscribed>

Store the subscription new, made by the signed-in session auth_session at now. An endpoint the owner has already is replaced (Subscribed::Replaced), not counted twice, and keeps its label unless new names one. The session must still be live when the row is written (Subscribed::SignedOut; Task 1’s review): ending it removes its subscriptions, so one stored after would outlive it.

Source

pub fn rotate( &self, old_endpoint: &str, new: &NewSubscription<'_>, now: i64, ) -> Result<Subscribed>

Replace the subscription of old_endpoint with new (a push service rotating a subscription, which the browser reports to its service worker; the review’s A1). It keeps its id, created_at and the session that made it, and its label unless new names one. Only an endpoint the owner has is rotated (Subscribed::NotFound): the API never shows endpoints, so knowing one is holding that browser.

Source

pub fn subscriptions(&self) -> Result<Vec<Subscription>>

Every subscription of the owner’s, oldest first.

Source

pub fn unsubscribe(&self, id: &str) -> Result<bool>

Remove the subscription id. Whether there was one.

Source

pub fn unsubscribe_endpoint(&self, endpoint: &str) -> Result<bool>

Remove the subscription of endpoint: a browser unsubscribing itself, which knows its endpoint and not its id. Whether there was one.

Source

pub fn record_push_success( &self, id: &str, endpoint: &str, now: i64, ) -> Result<()>

Record that a push to endpoint reached its push service at now, clearing the subscription id’s last error (plan 10b-ii).

Source

pub fn record_push_error( &self, id: &str, endpoint: &str, error: &str, ) -> Result<()>

Record why a push to the subscription id at endpoint failed: a short reason of delivery’s own, never the endpoint or the service’s answer (plan 10a’s review, O2).

Source

pub fn remove_gone_subscription(&self, id: &str, endpoint: &str) -> Result<bool>

Remove the subscription id its push service says is gone, if it still has the endpoint the push went to (plan 10b-ii).

Source

pub fn prune_expired_subscriptions(&self, now: i64) -> Result<usize>

Remove the subscriptions whose expirationTime has passed at now (plan 10b-ii): how many.

Source

pub fn push_policies(&self) -> Result<Vec<(String, PushPolicy)>>

Every hat’s push policy, the hats oldest first: the default for a hat that never had one set.

Source

pub fn push_policy(&self, hat_id: &str) -> Result<PushPolicy>

The push policy of hat_id: the default for a hat with none set, and for a hat that does not exist (a session from before hats has none).

Source

pub fn set_push_policy(&self, hat_id: &str, policy: PushPolicy) -> Result<bool>

Set the push policy of hat_id. false, and nothing stored, when the owner has no such hat.

Source§

impl Hosts

Source

pub fn remember( &self, host_id: &str, hat_id: &str, path: &str, now: i64, ) -> Result<bool>

Remember that a session of hat_id started or resumed in path on host_id at now, keeping the newest KEPT of that host and hat. false, and nothing remembered, for a path that is not canonical or cannot be shown: until the host resolves a session’s cwd (hats 5b), it is what its client sent.

Source

pub fn recents( &self, host_id: &str, hat_id: &str, limit: usize, ) -> Result<Vec<Recent>>

The newest limit recents of host_id whose path resolves to hat_id now (kernel spec §5.3; the review’s A1): resolved against the host’s current rules and default hat, not the hat stored when each was remembered, which a rule or a default changed since leaves stale. Empty for an unknown host.

Source§

impl Hosts

Source

pub fn session_defaults( &self, hat: &str, agent: &str, ) -> Result<Option<HatSessionDefaults>>

Source

pub fn put_session_defaults( &self, hat: &str, agent: &str, request: &PutHatSessionDefaults, auth: &Authenticated, ) -> Result<DefaultsChange>

Auto Trait Implementations§

§

impl !Freeze for Hosts

§

impl RefUnwindSafe for Hosts

§

impl Send for Hosts

§

impl Sync for Hosts

§

impl Unpin for Hosts

§

impl UnsafeUnpin for Hosts

§

impl UnwindSafe for Hosts

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<'a, T, E> AsTaggedExplicit<'a, E> for T
where T: 'a,

Source§

fn explicit(self, class: Class, tag: u32) -> TaggedParser<'a, Explicit, Self, E>

Source§

impl<'a, T, E> AsTaggedImplicit<'a, E> for T
where T: 'a,

Source§

fn implicit( self, class: Class, constructed: bool, tag: u32, ) -> TaggedParser<'a, Implicit, Self, E>

Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<A, B, T> HttpServerConnExec<A, B> for T
where B: Body,

Source§

impl<T> Instrument for T

Source§

fn instrument(self, span: Span) -> Instrumented<Self> ⓘ

Instruments this type with the provided Span, returning an Instrumented wrapper. Read more
Source§

fn in_current_span(self) -> Instrumented<Self> ⓘ

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> PolicyExt for T
where T: ?Sized,

Source§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow only if self and other return Action::Follow. Read more
Source§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: Sized + Policy<B, E>, P: Policy<B, E>,

Create a new Policy that returns Action::Follow if either self or other returns Action::Follow. Read more
Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = !

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, !>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

Source§

fn vzip(self) -> V

Source§

impl<T> WithSubscriber for T

Source§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self> ⓘ
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a WithDispatch wrapper. Read more
Source§

fn with_current_subscriber(self) -> WithDispatch<Self> ⓘ

Attaches the current default Subscriber to this type, returning a WithDispatch wrapper. Read more