Skip to main content

Connection

Struct Connection 

pub struct Connection(/* private fields */);
Available on crate features quic and std only.
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. Connection-scoped extensions are shared by all handles and can be accessed through ExtensionsRef::extensions, independently of the transport state lock.

Implementations§

§

impl Connection

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

Initiate a new outgoing unidirectional stream.

Streams are cheap and instantaneous to open unless blocked by flow control. As a consequence, the peer won’t be notified that a stream has been opened until the stream is actually used.

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

Initiate a new outgoing bidirectional stream.

Streams are cheap and instantaneous to open unless blocked by flow control. As a consequence, the peer won’t be notified that a stream has been opened until the stream is actually used. Calling open_bi() then waiting on the RecvStream without writing anything to SendStream will never succeed.

pub fn try_reserve_bi( &self, ) -> Result<Option<BiStreamReservation>, ConnectionError>

Reserve bidirectional stream credit without assigning a stream ID.

Returns None before the handshake completes or while credit is exhausted. Dropping an unused reservation returns its credit without emitting a reset. Ordinary stream opens cannot consume reserved credit.

pub fn stream_budget_watch(&self, dir: Dir) -> Changed<usize>

Subscribe before trying admission to observe newly available stream credit.

Values are change revisions, not capacities. A signal means credit was returned or increased, or the handshake finished; retry reservation or inspect Self::available_streams. Acquisitions do not wake subscribers.

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

Accept the next incoming uni-directional stream

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

Accept the next incoming bidirectional stream

Important Note: The Connection that calls open_bi() must write to its SendStream before the other Connection is able to accept_bi(). Calling open_bi() then waiting on the RecvStream without writing anything to SendStream will never succeed.

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

Receive an application datagram

pub async fn closed(&self) -> ConnectionError

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

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

If the connection is closed, the reason why.

Returns None if the connection is still open.

pub fn close(&self, error_code: impl Into<VarInt>, reason: &[u8])

Close 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, and Endpoint::wait_idle() can be used 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.

pub fn close_transport(&self, error: Error)

Available on crate feature test-utils only.

Send a transport CONNECTION_CLOSE for protocol interoperability tests.

Application shutdown normally uses Self::close. This hook exercises peers which finish with transport NO_ERROR, rather than an application code.

pub async fn handshake_confirmed(&self) -> Result<(), ConnectionError>

Wait for the handshake to be confirmed.

As a server, who must be authenticated by clients, this happens when the handshake completes upon receiving a TLS Finished message from the client. In return, the server send a HANDSHAKE_DONE frame.

As a client, this happens when receiving a HANDSHAKE_DONE frame. At this point, the server has either accepted our authentication, or, if client authentication is not required, accepted our lack of authentication.

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

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

Previously queued datagrams which are still unsent may be discarded to make space for this datagram, in order of oldest to newest.

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

Transmit data as an unreliable, unordered application datagram without waiting or discarding queued datagrams: a full send buffer returns SendDatagramError::Blocked.

See send_datagram() for details.

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

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

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

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

pub fn datagram_receive_enabled(&self) -> bool

Whether this connection accepts QUIC DATAGRAM frames from its peer: this endpoint advertised max_datagram_frame_size (RFC 9221 §3), whatever the peer supports.

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.

pub fn side(&self) -> Side

Which side of the connection this is: the one that opened it, or the one that accepted it.

pub fn remote_address(&self) -> SocketAddr

The peer’s UDP address

If ServerConfig::migration is true, clients may change addresses at will, e.g. when switching to a cellular internet connection.

pub fn local_ip(&self) -> Option<IpAddr>

The local IP address which was used when the peer established the connection

This can be different from the address the endpoint is bound to, in case the endpoint is bound to a wildcard address like 0.0.0.0 or ::.

This will return None for clients, or when the platform does not expose this information. See rama_udp::DatagramCapabilities::receive_local_ip for platform support.

pub fn rtt(&self) -> Duration

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

pub fn min_rtt(&self) -> Duration

Minimum RTT seen on this path, ignoring ack delay

pub fn stats(&self) -> ConnectionStats

Returns connection statistics

pub fn version(&self) -> Version

The QUIC version this connection runs in: the client’s first flight version, or the compatible version the server moved it to (RFC 9368).

pub fn original_version(&self) -> Version

The QUIC version of the client’s first flight, which differs from Self::version only after compatible version negotiation moved the connection (RFC 9368 §2.3).

pub fn handshake_data(&self) -> Option<NegotiatedTlsParameters>

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.

pub fn peer_identity(&self) -> Option<Vec<CertificateDer<'static>>>

The certificate chain the peer presented, leaf first, if it presented one.

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.

pub fn force_key_update(&self) -> bool

Update traffic keys now, without waiting for the usage limit that would force one.

Answers whether an update was started. Nothing changes and the answer is false when the connection is not established, when the handshake is not confirmed yet (RFC 9001 §6.1 forbids initiating an update before then, which for a client means after HANDSHAKE_DONE), or when an update is already in flight (§6 allows one at a time). ConnectionStats::key_updates counts the updates this connection has made, whichever side asked for them.

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

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

Two peers calling this with the same label, the same context and output buffers of equal length get the same bytes. The bytes are cryptographically strong and pseudorandom, suitable as keying material. A different label or a different context gives different bytes.

TLS 1.3 defines this exporter in RFC 8446 §7.5; RFC 5705 defined the earlier one it replaces.

pub fn driver_stats(&self) -> DriverStats

Socket and receive-queue statistics counted by the driver for this connection.

What the protocol engine counts is Connection::stats.

pub fn set_max_concurrent_uni_streams(&self, count: impl Into<VarInt>)

Modify the number of remotely initiated unidirectional streams that may be concurrently open

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.

pub fn max_concurrent_streams(&self, dir: Dir) -> u64

How many remotely initiated streams of dir may be open at once, as this side has allowed them.

Lowering the target with set_max_concurrent_streams does not take effect at once: the number falls by one as each open stream of that direction closes.

pub fn available_streams(&self, dir: Dir) -> u64

Unreserved streams that can be opened immediately under peer credit.

pub fn remote_stream_limit(&self, dir: Dir) -> u64

Exclusive cumulative stream-index limit advertised to the peer for dir.

This is the initial transport limit or the latest transmitted MAX_STREAMS value. A remote stream is within the advertised limit when its index (stream_id / 4) is smaller than this value. Unlike the concurrency target, it includes streams that have already closed.

pub fn remote_open_streams(&self, dir: Dir) -> u64

How many remotely initiated streams of dir are open, including those this side has not accepted yet. They count against max_concurrent_streams.

pub fn initial_local_id(&self) -> ConnectionId

The connection ID this endpoint’s generator made for the handshake, from the generator EndpointConfig::set_cid_generator installed.

A connection issues further identifiers as it runs and retires this one in time, so several may be usable at once and this is not “the one in use”. It stays the same for the life of the connection, which is what makes it worth reporting.

pub fn trace_id(&self) -> ConnectionId

The connection ID that names this connection in a qlog trace: the destination the client chose for its first Initial, which both ends know and neither changes.

pub fn qlog_control(&self) -> Option<ConnectionQlogControl>

Control this connection’s configured qlog sink. The handle can outlive the connection and can be inserted into Rama extensions for an application-level trigger. Returns None when no qlog sink was configured before creating the connection.

pub fn path_changed(&self)

Tell the connection its network path changed, so the congestion controller, the round-trip estimate and MTU discovery start again from the transport configuration.

Use it when something outside QUIC says the path is a different one, such as a change of interface. The connection detects a peer’s own move on its own.

pub fn set_send_window(&self, send_window: u64)

Set the maximum data this connection keeps in flight, as TransportConfig::set_send_window does before it is established.

pub fn set_receive_window(&self, receive_window: impl Into<VarInt>)

Set the flow control window this connection advertises, as TransportConfig::set_receive_window does before it is established.

pub fn set_max_concurrent_bi_streams(&self, count: impl Into<VarInt>)

Modify the number of remotely initiated bidirectional streams that may be concurrently open

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.

Trait Implementations§

§

impl Clone for Connection

§

fn clone(&self) -> Connection

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

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

Performs copy-assignment from source. Read more
§

impl Debug for Connection

§

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

Formats the value using the given formatter. Read more
§

impl ExtensionsRef for Connection

§

fn extensions(&self) -> &Extensions

Get reference to the underlying Extensions store
§

impl<S, Response> Service<Connection> for HttpService<Config, S>
where S: Service<Request, Output = Response, Error = !> + Clone, Response: IntoResponse + Send + 'static,

§

type Output = ()

The type of the output returned by the service.
§

type Error = Box<dyn Error + Sync + Send>

The type of error returned by the service.
§

async fn serve( &self, connection: Connection, ) -> Result<(), Box<dyn Error + Sync + Send>>

Serve an output or an error for the given input
§

fn boxed(self) -> BoxService<Input, Self::Output, Self::Error>

Box this service to allow for dynamic dispatch.

Auto Trait Implementations§

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
§

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,

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
§

impl<T> ForwardedClientExt for T
where T: ExtensionsRef + ?Sized,

§

fn forwarded_client(&self) -> Option<&ForwardedElement>

The element describing the client.
§

fn forwarded_client_ip(&self) -> Option<IpAddr>

The client’s IP, from its for node.
§

fn forwarded_client_socket_addr(&self) -> Option<SocketAddress>

The client’s IP and port, from its for node.
§

fn forwarded_client_host(&self) -> Option<&ForwardedAuthority>

The host the client asked for.
§

fn forwarded_client_proto(&self) -> Option<ForwardedProtocol>

The protocol the client used.
§

fn forwarded_client_version(&self) -> Option<ForwardedVersion>

The HTTP version the client used.
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> FutureExt for T

§

fn with_context(self, otel_cx: Context) -> WithContext<Self> ⓘ

Attaches the provided Context to this type, returning a WithContext wrapper. Read more
§

fn with_current_context(self) -> WithContext<Self> ⓘ

Attaches the current Context to this type, returning a WithContext wrapper. Read more
§

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

§

fn into_request(self) -> Request<T>

Wrap the input message T in a rama_grpc::Request
§

impl<L> LayerExt<L> for L

§

fn named_layer<S>(&self, service: S) -> Layered<<L as Layer<S>>::Service, S>
where L: Layer<S>,

Applies the layer to a service and wraps it in Layered.
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
§

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

§

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
§

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
§

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

§

fn rama_from(value: T) -> U

§

impl<T, U, CrateMarker> RamaInto<U, CrateMarker> for T
where U: RamaFrom<T, CrateMarker>,

§

fn rama_into(self) -> U

§

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

§

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

§

fn rama_try_from(value: T) -> Result<U, <U as RamaTryFrom<T>>::Error>

§

impl<T, U, CrateMarker> RamaTryInto<U, CrateMarker> for T
where U: RamaTryFrom<T, CrateMarker>,

§

type Error = <U as RamaTryFrom<T, CrateMarker>>::Error

§

fn rama_try_into(self) -> Result<U, <U as RamaTryFrom<T, CrateMarker>>::Error>

§

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

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

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

§

fn vzip(self) -> V

§

impl<V, F> ValueFormatter<&V> for F
where F: ValueFormatter<V> + ?Sized, V: ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &&V)

Write value to writer
§

impl<V, F> ValueFormatter<Arc<V>> for F
where F: ValueFormatter<V> + ?Sized, V: ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &Arc<V>)

Write value to writer
§

impl<V, F> ValueFormatter<Box<V>> for F
where F: ValueFormatter<V> + ?Sized, V: ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &Box<V>)

Write value to writer
§

impl<V, F> ValueFormatter<Cow<'_, V>> for F
where V: ToOwned + ?Sized, F: ValueFormatter<V> + ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &Cow<'_, V>)

Write value to writer
§

impl<V, F> ValueFormatter<Option<V>> for F
where F: ValueFormatter<V> + ?Sized,

§

const SHAPE: FieldShape<'static>

Available on non-metrique_require_explicit_impls only.
The shape of values produced by this formatter. Read more
§

fn format_value(writer: impl ValueWriter, value: &Option<V>)

Write value to writer
§

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