pub struct Connection(_);

Implementations

Accepts an incoming PeerStream

The method will return

  • Ok(Some(stream))) if a PeerStream was accepted
  • Ok(None) if the connection was closed without an error
  • Err(stream_error) if no stream could be accepted due to an error
Examples
while let Some(stream) = acceptor.accept().await? {
    println!("Stream opened from {:?}", stream.connection().remote_addr());
}

Poll for accepting an incoming PeerStream

The method will return

  • Poll::Ready(Ok(Some(stream))) if a PeerStream was accepted
  • Poll::Ready(Ok(None)) if the connection was closed without an error
  • Poll::Ready(Err(stream_error)) if no stream could be accepted due to an error
  • Poll::Pending if no new PeerStream was accepted by the connection yet. In this case the caller must retry calling Self::poll_accept. For this purpose the method will save the core::task::Waker which is provided as part of the core::task::Context parameter, and notify it as soon as retrying the method will yield a different result.

Accepts an incoming BidirectionalStream

The method will return

  • Ok(Some(stream))) if a BidirectionalStream was accepted
  • Ok(None) if the connection was closed without an error
  • Err(stream_error) if no stream could be accepted due to an error
Examples
while let Ok(Some(mut stream)) = acceptor.accept_bidirectional_stream().await {
    println!("Stream opened from {:?}", stream.connection().remote_addr());
}

Poll for accepting an incoming BidirectionalStream

The method will return

  • Poll::Ready(Ok(Some(stream))) if a BidirectionalStream was accepted
  • Poll::Ready(Ok(None)) if the connection was closed without an error
  • Poll::Ready(Err(stream_error)) if no stream could be accepted due to an error
  • Poll::Pending if no new BidirectionalStream was accepted by the connection yet. In this case the caller must retry calling Self::poll_accept_bidirectional_stream. For this purpose the method will save the core::task::Waker which is provided as part of the core::task::Context parameter, and notify it as soon as retrying the method will yield a different result.

Accepts an incoming ReceiveStream

The method will return

  • Ok(Some(stream))) if a ReceiveStream was accepted
  • Ok(None) if the connection was closed without an error
  • Err(stream_error) if no stream could be accepted due to an error
Examples
while let Ok(Some(mut stream)) = acceptor.accept_receive_stream().await {
    println!("Stream opened from {:?}", stream.connection().remote_addr());
}

Poll for accepting an incoming ReceiveStream

The method will return

  • Poll::Ready(Ok(Some(stream))) if a ReceiveStream was accepted
  • Poll::Ready(Ok(None)) if the connection was closed without an error
  • Poll::Ready(Err(stream_error)) if no stream could be accepted due to an error
  • Poll::Pending if no new ReceiveStream was accepted by the connection yet. In this case the caller must retry calling Self::poll_accept_receive_stream. For this purpose the method will save the core::task::Waker which is provided as part of the core::task::Context parameter, and notify it as soon as retrying the method will yield a different result.

Opens a new LocalStream with a specific type

The method will return

  • Ok(stream) if a stream of the requested type was opened
  • Err(stream_error) if the stream could not be opened due to an error
Examples
while let Ok(stream) = handle.open_stream(stream::Type::Bidirectional).await {
    println!("Stream opened from {:?}", stream.connection().remote_addr());
}

Polls opening a LocalStream with a specific type

The method will return

  • Poll::Ready(Ok(stream)) if a stream of the requested type was opened
  • Poll::Ready(Err(stream_error)) if the stream could not be opened due to an error
  • Poll::Pending if the stream has not been opened yet

Opens a new BidirectionalStream

The method will return

  • Ok(stream) if a bidirectional stream was opened
  • Err(stream_error) if the stream could not be opened due to an error
Examples
while let Ok(mut stream) = handle.open_bidirectional_stream().await {
    println!("Stream opened from {:?}", stream.connection().remote_addr());
}

Polls opening a BidirectionalStream

The method will return

  • Poll::Ready(Ok(stream)) if a bidirectional stream was opened
  • Poll::Ready(Err(stream_error)) if the stream could not be opened due to an error
  • Poll::Pending if the stream has not been opened yet

Opens a SendStream

Examples
let stream = connection.open_send_stream().await?;
println!("Send stream opened with id: {}", stream.id());

Polls opening a SendStream

Returns the local address that this connection is bound to.

Returns the remote address that this connection is connected to.

Returns the negotiated server name the connection is using.

Returns the negotiated application protocol the connection is using

Returns the internal identifier for the Connection

Note: This internal identifier is not the same as the connection ID included in packet headers as described in QUIC Transport RFC

Sends a Ping frame to the peer

Enables or disables the connection to actively keep the connection alive with the peer

This can be useful for maintaining connections beyond the configured idle timeout. The connection will continue to be held open until the keep alive is disabled or the connection is no longer able to be maintained due to connectivity.

Closes the Connection with the provided error code

This will immediately terminate all outstanding streams.

Examples
const MY_ERROR_CODE:u32 = 99;
connection.close(MY_ERROR_CODE.into());

API for querying the connection’s Subscriber::ConnectionContext.

The ConnectionContext provides a mechanism for users to provide a custom type and update it on each event. The query APIs (check Self::query_event_context_mut for mutable version) provide a way to inspect the ConnectionContext outside of events.

This function takes a FnOnce(&EventContext) -> Outcome, where EventContext represents the type of ConnectionContext. If the EventContext type matches any of the types of the configured Subscriber’s context, the query is executed and Ok(Outcome) is returned, else Err(query::Error).

Given that it is possible to compose Subscriber, which can have different ConnectionContext types, this function traverses all Subscribers, executes and short-circuiting on the first match.

Examples
use s2n_quic::{provider::event::{events, query, Subscriber}, Connection, Server};

struct MySubscriber{}

impl Subscriber for MySubscriber {
    type ConnectionContext = MyEventContext;
    fn create_connection_context(
       &mut self, _meta: &events::ConnectionMeta,
       _info: &events::ConnectionInfo,
    ) -> Self::ConnectionContext {
        MyEventContext { request: 0 }
    }
 }

#[derive(Clone, Copy)]
pub struct MyEventContext {
    request: u64,
}

let mut server = Server::builder()
  .with_event(MySubscriber {}).unwrap()
  .start().unwrap();

let outcome: Result<MyEventContext, query::Error> = connection
    .query_event_context(|event_context: &MyEventContext| *event_context);

match outcome {
    Ok(event_context) => {
        // `MyEventContext` matched a Subscriber::ConnectionContext and the
        // query executed.
        //
        // use the value event_context for logging, etc..
    }
    Err(query::Error::ConnectionLockPoisoned) => {
        // The query did not execute because of a connection error.
        //
        // log an error, panic, etc..
    }
    Err(query::Error::ContextTypeMismatch) => {
        // `MyEventContext` failed to match any Subscriber::ConnectionContext
        // and the query did not execute.
        //
        // log an error, panic, etc..
    }
    Err(_) => {
        // We encountered an unknown error so handle it generically, e.g. log,
        // panic, etc.
    }
}
Traverse order

Let’s demonstrate the traversal order for matching on ConnectionContext in the example below. We provide a composed Subscriber type (Foo, Bar), where both Foo and Bar have a ConnectionContext type of u64. The query traverse order is as follows:

  • (Foo::ConnectionContext, Bar::ConnectionContext)
  • Foo::ConnectionContext
  • Bar::ConnectionContext

Note: In this example the type u64 will always match Foo::u64 and Bar::u64 will never be matched. If this is undesirable, applications should make unique associated ConnectionContexts by creating new types.

use s2n_quic::{provider::event::{events, Subscriber}, Connection, Server};

struct Foo {}

impl Subscriber for Foo {
   type ConnectionContext = u64;
   fn create_connection_context(
       &mut self, _meta: &events::ConnectionMeta,
       _info: &events::ConnectionInfo,
   ) -> Self::ConnectionContext { 0 }
}

struct Bar {}

impl Subscriber for Bar {
   type ConnectionContext = u64;
   fn create_connection_context(
       &mut self, _meta: &events::ConnectionMeta,
       _info: &events::ConnectionInfo,
   ) -> Self::ConnectionContext { 0 }
}

let mut server = Server::builder()
    .with_event((Foo {}, Bar {})).unwrap()
    .start().unwrap();

// Matches Foo.
//
// Note: Because the `ConnectionContext` type is the same for
// both `Foo` and `Bar`, only `Foo`'s context will be matched.
let _ = connection.query_event_context(|ctx: &u64| *ctx );

// Matches (Foo, Bar).
let _ = connection.query_event_context(|ctx: &(u64, u64)| ctx.0 );

API for querying the connection’s Subscriber::ConnectionContext.

Similar to Self::query_event_context but provides mutable access to ConnectionContext.

let outcome = connection
    .query_event_context(
        |event_context: &MyEventContext| event_context.request += 1
    );

API for querying the connection’s datagram endpoint.

Provides mutable access to Sender or Receiver.

let outcome = connection
    .datagram_mut(
        |sender: &MySender| sender.send_datagram(Bytes::from_static(&[1, 2, 3]));
    );

Returns a cloneable handle to the connection

Examples
let handle = connection.handle();
let another_handle = handle.clone();

Splits the connection into a connection::Handle and connection::StreamAcceptor halves

Examples
let (mut handle, mut acceptor) = connection.split();
let mut send = handle.open_send_stream().await?;
tokio::spawn(async move {
    let _ = send.send(bytes::Bytes::from_static(&[1, 2, 3])).await;
});

while let Some(stream) = acceptor.accept().await? {
    println!("accepted stream {}", stream.id());
}

Trait Implementations

Formats the value using the given formatter. Read more

Auto Trait Implementations

Blanket Implementations

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.