Skip to main content

Client

Struct Client 

Source
pub struct Client<R: Read, W: Write> { /* private fields */ }
Expand description

Client side of the wire, exchanging encrypted messages over a byte stream.

Client::connect sends a reset and runs the handshake, returning a Sender for outbound messages. Client::recv decrypts inbound messages.

An empty frame from the server means it holds no session with this client. Client::recv then ends the client’s session and returns Error::SessionReset, after which the caller can reconnect.

Transport checks the shape of the device attestation. A Verifier decides whether to trust the server presenting it.

Implementations§

Source§

impl<R: Read, W: Write> Client<R, W>

Source

pub fn new(stream: Stream<R, W>) -> Self

Creates a client that owns the byte stream and its shutdown operation, without an encrypted session.

Call Client::connect to establish one. Output uses the stream’s configured write timeout. The stream’s Read and Write adapters must enforce deadlines and let shutdown cancel blocked I/O.

Source

pub fn set_handshake_timeout(self, timeout: Duration) -> Self

Sets the budget for each later handshake, counted from the call to Client::connect.

Defaults to DEFAULT_HANDSHAKE_TIMEOUT. Output and peer replies share one deadline; progress and stale frames do not refresh it. Each outgoing frame is also limited by the stream’s write timeout. Waiting for locks and verifier callbacks can extend the call beyond the deadline.

Zero, or a duration too large to add to an Instant, expires attempts immediately.

Source

pub fn closer(&self) -> Closer

Returns a handle that permanently closes the stream from another thread.

Source

pub fn close(&self)

Permanently closes the stream and waits for adapter shutdown.

Senders observe closure through write failure, and buffered messages remain readable. See Closer::close.

Source

pub fn connect<V: Verifier>( &mut self, verifier: &V, ) -> Result<(Sender<W>, V::Info), Error>

Establishes an encrypted session over the stream, ending any previous session first.

Sends a reset and drives the handshake:

1. Client -> Server: HostHello { host_signer, host_crypto }           (plain CBOR)
2. Server -> Client: ArkHello  { ark_attest, ark_crypto, a2h_encap }  (cose::seal)
3. Client -> Server: HostAck   { h2a_encap }                          (cose::seal)

The verifier receives the server’s device attestation. Its accepted info is returned alongside the new sender. That sender belongs to this session and cannot send into a replacement established by a later handshake.

Sends reset and hello before draining old input. The adapter must allow that output to finish without concurrent client reads for this attempt to progress. Backpressure can instead fail an outgoing frame on timeout.

The handshake uses one configured deadline, shared by output and peer waits. A successful ack send within that deadline establishes the session. Waiting for writes already in flight may extend the call. If connecting fails, the client has no session and every sender it issued before is invalid.

§Panics

Panics if signing reads a wall time before the Unix epoch from the stream’s clock.

Source

pub fn recv(&mut self) -> Result<Vec<u8>, Error>

Reads and decrypts the next ark-to-host message.

Invalid or oversized frames end the session, since its encryption sequence may be lost. Decryption failures also end the session. An empty frame means the server dropped the session, which ends here too with Error::SessionReset. Adapter read failures and EOF also end the session, while idle read timeouts are retried internally. Call Self::connect to establish a new session after a failure. Without a session, returns an error without reading the stream.

After decryption, message acceptance is ordered with session ending without waiting for the writer. A concurrent send failure can cause a decrypted message to be discarded before acceptance. An accepted message may reach this caller after another thread ends the session. Returning a receive error does wait for outgoing writes to finish.

Trait Implementations§

Source§

impl<R: Read, W: Write> Debug for Client<R, W>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Shows the session label, whether a session is established and the handshake budget, never the adapters or the encryption contexts.

Source§

impl<R: Read, W: Write> Drop for Client<R, W>

Source§

fn drop(&mut self)

Closes the stream to cancel blocked I/O, then ends the binding before releasing the contexts.

Shutdown must come before waiting for the writer, which a blocked write could otherwise hold until its deadline. Idle senders hold weak references and cannot extend the stream’s lifetime.

Source§

fn pin_drop(self: Pin<&mut Self>)

🔬This is a nightly-only experimental API. (pin_ergonomics)
Execute the destructor for this type, but different to Drop::drop, it requires self to be pinned. Read more

Auto Trait Implementations§

§

impl<R, W> Freeze for Client<R, W>
where FrameReader<R>: Freeze, Arc<Outbound<W>>: Freeze,

§

impl<R, W> RefUnwindSafe for Client<R, W>
where FrameReader<R>: RefUnwindSafe, Arc<Outbound<W>>: RefUnwindSafe,

§

impl<R, W> Send for Client<R, W>
where FrameReader<R>: Send, Arc<Outbound<W>>: Send,

§

impl<R, W> Sync for Client<R, W>
where FrameReader<R>: Sync, Arc<Outbound<W>>: Sync,

§

impl<R, W> Unpin for Client<R, W>
where FrameReader<R>: Unpin, Arc<Outbound<W>>: Unpin,

§

impl<R, W> UnsafeUnpin for Client<R, W>
where FrameReader<R>: UnsafeUnpin, Arc<Outbound<W>>: UnsafeUnpin,

§

impl<R, W> UnwindSafe for Client<R, W>
where FrameReader<R>: UnwindSafe, Arc<Outbound<W>>: UnwindSafe,

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<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<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> 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