Connection

Struct Connection 

Source
pub struct Connection<State: ConnectionState = HandshakeCompleted> { /* private fields */ }
Expand description

A QUIC connection.

If all references to a connection (including every clone of the Connection handle, streams of incoming streams, and the various stream types) have been dropped, then the connection will be automatically closed with an error_code of 0 and an empty reason. You can also close the connection explicitly by calling Connection::close.

Closing the connection immediately abandons efforts to deliver data to the peer. Upon receiving CONNECTION_CLOSE the peer may drop any stream data not yet delivered to the application. Connection::close describes in more detail how to gracefully close a connection without losing application data.

May be cloned to obtain another handle to the same connection.

Implementations§

Source§

impl<T: ConnectionState> Connection<T>

Source

pub fn open_uni(&self) -> OpenUni<'_> ⓘ

Initiates a new outgoing unidirectional stream.

A unidirectional stream can only transmit data from the endpoint which opens the stream, the endpoint accepting the stream can not send any data back on the same stream.

§QUIC streams

QUIC can multiplex many streams onto a single connection. Streams can be short or long lived and may be opened and closed without incurring any extra cost. The data sent in each stream is delivered strictly ordered, yet multiple streams will be transmitted interleaved and packet loss on one stream will not delay other streams. Thus streams do not suffer head-of-line blocking.

§Opening streams

Both peers of a connection can open streams at any time. Opening a new stream does not incur any extra overhead compared to sending data on an existing stream. However only once some data has been transmitted on the stream, will the peer become aware of the newly opened stream.

§Accepting streams

Each stream needs to be accepted by the peer, using either Self::accept_uni or Self::accept_bi depending on the stream type. Repeated accept call will yield a new stream whenever the peer opens a new stream.

Note that opening a stream is not sufficient for the accept call to yield a new stream. Data must be sent on a stream before the respective accept call at the peer will yield a RecvStream.

§Stream priorities

Streams can have different priorities set using SendStream::set_priority. Data of streams with a higher priority will be transmitted to the peer before data from streams with a lower priority.

§Stream limits

The number of streams which can be open concurrently defaults to QuicTransportConfigBuilder::max_concurrent_uni_streams and QuicTransportConfigBuilder::max_concurrent_bidi_streams. While the connection is open these limits can be changed using Self::set_max_concurrent_uni_streams and Self::set_max_concurrent_bi_streams.

Each stream has a receive window of a maximum number of bytes that may be in-flight before the sender is blocked from transmitting more. This is configured in QuicTransportConfigBuilder::stream_receive_window. There is also a QuicTransportConfigBuilder::receive_window which applies to all streams combined and can be changed during a connection using Self::set_receive_window.

The protocol limits the total number of streams during the lifetime of a connection to 2**62, this limit applies to the sum of uni- and bi-directional streams. For most practical purposes this is essentially unlimited.

Source

pub fn open_bi(&self) -> OpenBi<'_> ⓘ

Initiates a new outgoing bidirectional stream.

Bidirectional streams allows both peers to send as well as receive data. They act as a pair of related unidirectional streams.

See Self::open_uni for a detailed description of how streams work.

Source

pub fn accept_uni(&self) -> AcceptUni<'_> ⓘ

Accepts the next incoming uni-directional stream.

See Self::open_uni for a detailed description of how streams work.

Source

pub fn accept_bi(&self) -> AcceptBi<'_> ⓘ

Accepts the next incoming bidirectional stream.

See Self::open_uni for a detailed description of how streams work.

Source

pub fn read_datagram(&self) -> ReadDatagram<'_> ⓘ

Receives an application datagram.

Source

pub fn read_many_datagrams<'a, 'b>( &'a self, out: &'b mut [Bytes], ) -> ReadManyDatagrams<'a, 'b> ⓘ

Receives a batch of application datagrams into out, in arrival order.

This is the batch analogue of read_datagram(). The returned future resolves once at least one datagram is buffered, drains up to out.len() of them into out from the front, and yields the count written. Use this instead of read_datagram() in a loop when forwarding bursts: a whole batch is taken under a single lock hold.

Source

pub async fn closed(&self) -> ConnectionError

Waits for the connection to be closed for any reason.

Despite the return type’s name, closed connections are often not an error condition at the application layer. Cases that might be routine include ConnectionError::LocallyClosed and ConnectionError::ApplicationClosed.

Source

pub fn close_reason(&self) -> Option<ConnectionError>

If the connection is closed, the reason why.

Returns None if the connection is still open.

Source

pub fn close(&self, error_code: VarInt, reason: &[u8])

Closes the connection immediately.

Pending operations will fail immediately with ConnectionError::LocallyClosed. No more data is sent to the peer and the peer may drop buffered data upon receiving the CONNECTION_CLOSE frame.

error_code and reason are not interpreted, and are provided directly to the peer.

reason will be truncated to fit in a single packet with overhead; to improve odds that it is preserved in full, it should be kept under 1KiB.

§Gracefully closing a connection

Only the peer last receiving application data can be certain that all data is delivered. The only reliable action it can then take is to close the connection, potentially with a custom error code. The delivery of the final CONNECTION_CLOSE frame is very likely if both endpoints stay online long enough, calling Endpoint::close will wait to provide sufficient time. Otherwise, the remote peer will time out the connection, provided that the idle timeout is not disabled.

The sending side can not guarantee all stream data is delivered to the remote application. It only knows the data is delivered to the QUIC stack of the remote endpoint. Once the local side sends a CONNECTION_CLOSE frame in response to calling close the remote endpoint may drop any data it received but is as yet undelivered to the application, including data that was acknowledged as received to the local endpoint.

Source

pub fn send_datagram(&self, data: Bytes) -> Result<(), SendDatagramError>

Transmits data as an unreliable, unordered application datagram.

Application datagrams are a low-level primitive. They may be lost or delivered out of order, and data must both fit inside a single QUIC packet and be smaller than the maximum dictated by the peer.

Source

pub fn send_many_datagrams( &self, datagrams: &[Bytes], ) -> Result<usize, SendDatagramError>

Transmits many unreliable, unordered application datagrams in a single call.

This is the batch analogue of send_datagram(): it queues the whole batch under one lock hold and wakes the driver once, reducing the per-datagram overhead of calling send_datagram() repeatedly. Like send_datagram(), older queued datagrams may be dropped to make room.

Returns the number of datagrams queued. The batch is rejected with SendDatagramError::TooLarge if any datagram exceeds the maximum datagram size.

Source

pub fn send_datagram_wait(&self, data: Bytes) -> SendDatagram<'_> ⓘ

Transmits data as an unreliable, unordered application datagram

Unlike send_datagram(), this method will wait for buffer space during congestion conditions, which effectively prioritizes old datagrams over new datagrams.

See send_datagram() for details.

Source

pub fn max_datagram_size(&self) -> Option<usize>

Computes the maximum size of datagrams that may be passed to send_datagram.

Returns None if datagrams are unsupported by the peer or disabled locally.

This may change over the lifetime of a connection according to variation in the path MTU estimate. The peer can also enforce an arbitrarily small fixed limit, but if the peer’s limit is large this is guaranteed to be a little over a kilobyte at minimum.

Not necessarily the maximum size of received datagrams.

Source

pub fn datagram_send_buffer_space(&self) -> usize

Bytes available in the outgoing datagram buffer.

When greater than zero, calling send_datagram with a datagram of at most this size is guaranteed not to cause older datagrams to be dropped.

Source

pub fn rtt(&self, path_id: PathId) -> Option<Duration>

Current best estimate of this connection’s latency (round-trip-time).

Source

pub fn stats(&self) -> ConnectionStats

Returns connection statistics.

Source

pub fn congestion_state(&self, path_id: PathId) -> Option<Box<dyn Controller>>

Current state of the congestion control algorithm, for debugging purposes.

Source

pub fn handshake_data(&self) -> Option<Box<dyn Any>>

Parameters negotiated during the handshake.

Guaranteed to return Some on fully established connections or after Connecting::handshake_data() succeeds. See that method’s documentations for details on the returned value.

Source

pub fn peer_identity(&self) -> Option<Box<dyn Any>>

Cryptographic identity of the peer.

The dynamic type returned is determined by the configured Session. For the default rustls session, the return value can be downcast to a Vec<[rustls::pki_types::CertificateDer]>

Source

pub fn stable_id(&self) -> usize

A stable identifier for this connection.

Peer addresses and connection IDs can change, but this value will remain fixed for the lifetime of the connection.

Source

pub fn export_keying_material( &self, output: &mut [u8], label: &[u8], context: &[u8], ) -> Result<(), ExportKeyingMaterialError>

Derives keying material from this connection’s TLS session secrets.

When both peers call this method with the same label and context arguments and output buffers of equal length, they will get the same sequence of bytes in output. These bytes are cryptographically strong and pseudorandom, and are suitable for use as keying material.

See RFC5705 for more information.

Source

pub fn set_max_concurrent_uni_streams(&self, count: VarInt)

Modifies the number of unidirectional streams that may be concurrently opened.

No streams may be opened by the peer unless fewer than count are already open. Large counts increase both minimum and worst-case memory consumption.

Source

pub fn set_receive_window(&self, receive_window: VarInt)

Sets the connection-level flow control receive window.

See QuicTransportConfigBuilder::receive_window.

Source

pub fn set_max_concurrent_bi_streams(&self, count: VarInt)

Modifies the number of bidirectional streams that may be concurrently opened.

No streams may be opened by the peer unless fewer than count are already open. Large counts increase both minimum and worst-case memory consumption.

Source§

impl Connection<HandshakeCompleted>

Source

pub fn alpn(&self) -> &[u8] ⓘ

Extracts the ALPN protocol from the peer’s handshake data.

Source

pub fn remote_id(&self) -> EndpointId

Returns the EndpointId from the peer’s TLS certificate.

The PublicKey of an endpoint is also known as an EndpointId. This PublicKey is included in the TLS certificate presented during the handshake when connecting. This function allows you to get the EndpointId of the remote endpoint of this connection.

Source

pub fn paths(&self) -> PathList<'_>

Returns the currently open network paths for this connection.

A connection typically has one path via the relay server and, once holepunching succeeds, a direct path. The returned PathList is a snapshot taken at call time: it does not reflect later changes, and it does not include paths that have already closed.

To observe changes over time, see Connection::paths_stream for a stream of PathList snapshots and Connection::path_events for individual PathEvents.

Source

pub fn paths_stream(&self) -> PathListStream<'_>

Returns a stream of PathList snapshots for this connection.

Yields the current snapshot on the first poll, and a fresh snapshot whenever the open paths or the selected path change. Ends when the connection closes.

The stream borrows this Connection. To consume it from a spawned task, move a Connection clone into the task and call this method inside.

Source

pub fn path_events(&self) -> PathEventStream

Returns a stream of PathEvents for this connection.

Each event reports one of: a path opened, a path closed (with final per-path statistics), the selected transmission path changed, or the consumer fell behind. The stream ends when the connection closes. It does not borrow this Connection and may be moved into a spawned task.

If the consumer does not poll fast enough, the stream yields a single PathEvent::Lagged; the current state of the open paths and the selected path remains recoverable via Connection::paths.

Source

pub fn side(&self) -> Side

Returns the side of the connection (client or server).

Source

pub fn weak_handle(&self) -> WeakConnectionHandle

Returns a WeakConnectionHandle for this connection.

A WeakConnectionHandle does not keep the connection alive. It can be used to wait for the connection to be closed via WeakConnectionHandle::closed and to attempt to upgrade back to a strong Connection via WeakConnectionHandle::upgrade.

Source§

impl Connection<IncomingZeroRtt>

Source

pub fn alpn(&self) -> Option<Vec<u8>>

Extracts the ALPN protocol from the peer’s handshake data.

Source

pub async fn handshake_completed(&self) -> Result<Connection, ConnectingError>

Waits until the full handshake occurs and then returns a Connection.

This may fail with ConnectingError::ConnectionError, if there was some general failure with the connection, such as a network timeout since we accepted the connection.

This may fail with ConnectingError::HandshakeFailure, if the other side doesn’t use the right TLS authentication, which usually every iroh endpoint uses and requires.

Thus, those errors should only occur if someone connects to you with a modified iroh endpoint or with a plain QUIC client.

Source

pub fn remote_id(&self) -> Result<EndpointId, RemoteEndpointIdError>

Returns the EndpointId from the peer’s TLS certificate.

The PublicKey of an endpoint is also known as an EndpointId. This PublicKey is included in the TLS certificate presented during the handshake when connecting. This function allows you to get the EndpointId of the remote endpoint of this connection.

Source§

impl Connection<OutgoingZeroRtt>

Source

pub fn alpn(&self) -> Option<Vec<u8>>

Extracts the ALPN protocol from the peer’s handshake data.

Source

pub async fn handshake_completed( &self, ) -> Result<ZeroRttStatus, ConnectingError>

Waits until the full handshake occurs and returns a ZeroRttStatus.

If ZeroRttStatus::Accepted is returned, then any streams created before the handshake has completed can still be used.

If ZeroRttStatus::Rejected is returned, then any streams created before the handshake will error and any data sent should be re-sent on a new stream.

This may fail with ConnectingError::ConnectionError, if there was some general failure with the connection, such as a network timeout since we initiated the connection.

This may fail with ConnectingError::HandshakeFailure, if the other side doesn’t use the right TLS authentication, which usually every iroh endpoint uses and requires.

Thus, those errors should only occur if someone connects to you with a modified iroh endpoint or with a plain QUIC client.

Source

pub fn remote_id(&self) -> Result<EndpointId, RemoteEndpointIdError>

Returns the EndpointId from the peer’s TLS certificate.

The PublicKey of an endpoint is also known as an EndpointId. This PublicKey is included in the TLS certificate presented during the handshake when connecting. This function allows you to get the EndpointId of the remote endpoint of this connection.

Trait Implementations§

Source§

impl<State: Clone + ConnectionState> Clone for Connection<State>
where State::Data: Clone,

Source§

fn clone(&self) -> Connection<State>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<State: Debug + ConnectionState> Debug for Connection<State>
where State::Data: Debug,

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

impl<State> Freeze for Connection<State>
where <State as ConnectionState>::Data: Freeze,

§

impl<State> RefUnwindSafe for Connection<State>
where <State as ConnectionState>::Data: RefUnwindSafe,

§

impl<State> Send for Connection<State>
where <State as ConnectionState>::Data: Send,

§

impl<State> Sync for Connection<State>
where <State as ConnectionState>::Data: Sync,

§

impl<State> Unpin for Connection<State>
where <State as ConnectionState>::Data: Unpin,

§

impl<State> UnwindSafe for Connection<State>
where <State as ConnectionState>::Data: 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
§

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

§

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

§

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

§

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<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> FromRef<T> for T
where T: Clone,

§

fn from_ref(input: &T) -> T

Converts to this type from a reference to the input type.
§

impl<T> Instrument for T

§

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

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

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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
§

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

§

fn and<P, B, E>(self, other: P) -> And<T, P>
where T: 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
§

fn or<P, B, E>(self, other: P) -> Or<T, P>
where T: 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> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

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

Source§

type Error = Infallible

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

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

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

impl<T> WithSubscriber for T

§

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
§

fn with_current_subscriber(self) -> WithDispatch<Self>

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

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

§

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

§

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