Struct s2n_quic::connection::Connection

source ·
pub struct Connection(/* private fields */);

Implementations§

source§

impl Connection

source

pub async fn accept(&mut self) -> Result<Option<PeerStream>>

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());
}
source

pub fn poll_accept( &mut self, cx: &mut Context<'_> ) -> Poll<Result<Option<PeerStream>>>

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

pub async fn accept_bidirectional_stream( &mut self ) -> Result<Option<BidirectionalStream>>

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());
}
source

pub fn poll_accept_bidirectional_stream( &mut self, cx: &mut Context<'_> ) -> Poll<Result<Option<BidirectionalStream>>>

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

pub async fn accept_receive_stream(&mut self) -> Result<Option<ReceiveStream>>

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());
}
source

pub fn poll_accept_receive_stream( &mut self, cx: &mut Context<'_> ) -> Poll<Result<Option<ReceiveStream>>>

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

pub async fn open_stream(&mut self, stream_type: Type) -> Result<LocalStream>

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());
}
source

pub fn poll_open_stream( &mut self, stream_type: Type, cx: &mut Context<'_> ) -> Poll<Result<LocalStream>>

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
source

pub async fn open_bidirectional_stream(&mut self) -> Result<BidirectionalStream>

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());
}
source

pub fn poll_open_bidirectional_stream( &mut self, cx: &mut Context<'_> ) -> Poll<Result<BidirectionalStream>>

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
source

pub async fn open_send_stream(&mut self) -> Result<SendStream>

Opens a SendStream

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

pub fn poll_open_send_stream( &mut self, cx: &mut Context<'_> ) -> Poll<Result<SendStream>>

Polls opening a SendStream

source

pub fn local_addr(&self) -> Result<SocketAddr>

Returns the local address that this connection is bound to.

source

pub fn remote_addr(&self) -> Result<SocketAddr>

Returns the remote address that this connection is connected to.

source

pub fn server_name(&self) -> Result<Option<Name>>

Returns the negotiated server name the connection is using.

source

pub fn application_protocol(&self) -> Result<Bytes>

Returns the negotiated application protocol the connection is using

source

pub fn id(&self) -> u64

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

source

pub fn ping(&mut self) -> Result<()>

Sends a Ping frame to the peer

source

pub fn keep_alive(&mut self, enabled: bool) -> Result<()>

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.

source

pub fn close(&self, error_code: Error)

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());
source

pub fn query_event_context<Query, EventContext, Outcome>( &self, query: Query ) -> Result<Outcome, Error>
where Query: FnOnce(&EventContext) -> Outcome, EventContext: 'static,

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 );
source

pub fn query_event_context_mut<Query, EventContext, Outcome>( &mut self, query: Query ) -> Result<Outcome, Error>
where Query: FnOnce(&mut EventContext) -> Outcome, EventContext: 'static,

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
    );
source

pub fn datagram_mut<Query, ProviderType, Outcome>( &self, query: Query ) -> Result<Outcome, Error>
where Query: FnOnce(&mut ProviderType) -> Outcome, ProviderType: 'static,

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]));
    );
source

pub fn handle(&self) -> Handle

Returns a cloneable handle to the connection

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

pub fn split(self) -> (Handle, StreamAcceptor)

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§

source§

impl Debug for Connection

source§

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

Formats the value using the given formatter. Read more

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

source§

fn from(t: T) -> T

Returns the argument unchanged.

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, U> TryFrom<U> for T
where U: Into<T>,

§

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

§

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<T, U> Upcast<T> for U
where T: UpcastFrom<U>,

source§

fn upcast(self) -> T

source§

impl<T, B> UpcastFrom<Counter<T, B>> for T

source§

fn upcast_from(value: Counter<T, B>) -> T

source§

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

source§

fn vzip(self) -> V