Struct s2n_quic::connection::Connection
source · [−]pub struct Connection(_);
Implementations
sourceimpl Connection
impl Connection
sourcepub async fn accept(&mut self) -> Result<Option<PeerStream>>
pub async fn accept(&mut self) -> Result<Option<PeerStream>>
Accepts an incoming PeerStream
The method will return
Ok(Some(stream)))
if aPeerStream
was acceptedOk(None)
if the connection was closed without an errorErr(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());
}
sourcepub fn poll_accept(
&mut self,
cx: &mut Context<'_>
) -> Poll<Result<Option<PeerStream>>>
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 aPeerStream
was acceptedPoll::Ready(Ok(None))
if the connection was closed without an errorPoll::Ready(Err(stream_error))
if no stream could be accepted due to an errorPoll::Pending
if no newPeerStream
was accepted by the connection yet. In this case the caller must retry callingSelf::poll_accept
. For this purpose the method will save thecore::task::Waker
which is provided as part of thecore::task::Context
parameter, and notify it as soon as retrying the method will yield a different result.
sourcepub async fn accept_bidirectional_stream(
&mut self
) -> Result<Option<BidirectionalStream>>
pub async fn accept_bidirectional_stream(
&mut self
) -> Result<Option<BidirectionalStream>>
Accepts an incoming BidirectionalStream
The method will return
Ok(Some(stream)))
if aBidirectionalStream
was acceptedOk(None)
if the connection was closed without an errorErr(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());
}
sourcepub fn poll_accept_bidirectional_stream(
&mut self,
cx: &mut Context<'_>
) -> Poll<Result<Option<BidirectionalStream>>>
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 aBidirectionalStream
was acceptedPoll::Ready(Ok(None))
if the connection was closed without an errorPoll::Ready(Err(stream_error))
if no stream could be accepted due to an errorPoll::Pending
if no newBidirectionalStream
was accepted by the connection yet. In this case the caller must retry callingSelf::poll_accept_bidirectional_stream
. For this purpose the method will save thecore::task::Waker
which is provided as part of thecore::task::Context
parameter, and notify it as soon as retrying the method will yield a different result.
sourcepub async fn accept_receive_stream(&mut self) -> Result<Option<ReceiveStream>>
pub async fn accept_receive_stream(&mut self) -> Result<Option<ReceiveStream>>
Accepts an incoming ReceiveStream
The method will return
Ok(Some(stream)))
if aReceiveStream
was acceptedOk(None)
if the connection was closed without an errorErr(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());
}
sourcepub fn poll_accept_receive_stream(
&mut self,
cx: &mut Context<'_>
) -> Poll<Result<Option<ReceiveStream>>>
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 aReceiveStream
was acceptedPoll::Ready(Ok(None))
if the connection was closed without an errorPoll::Ready(Err(stream_error))
if no stream could be accepted due to an errorPoll::Pending
if no newReceiveStream
was accepted by the connection yet. In this case the caller must retry callingSelf::poll_accept_receive_stream
. For this purpose the method will save thecore::task::Waker
which is provided as part of thecore::task::Context
parameter, and notify it as soon as retrying the method will yield a different result.
sourcepub async fn open_stream(&mut self, stream_type: Type) -> Result<LocalStream>
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 openedErr(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());
}
sourcepub fn poll_open_stream(
&mut self,
stream_type: Type,
cx: &mut Context<'_>
) -> Poll<Result<LocalStream>>
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 openedPoll::Ready(Err(stream_error))
if the stream could not be opened due to an errorPoll::Pending
if the stream has not been opened yet
sourcepub async fn open_bidirectional_stream(&mut self) -> Result<BidirectionalStream>
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 openedErr(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());
}
sourcepub fn poll_open_bidirectional_stream(
&mut self,
cx: &mut Context<'_>
) -> Poll<Result<BidirectionalStream>>
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 openedPoll::Ready(Err(stream_error))
if the stream could not be opened due to an errorPoll::Pending
if the stream has not been opened yet
sourcepub async fn open_send_stream(&mut self) -> Result<SendStream>
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());
sourcepub fn poll_open_send_stream(
&mut self,
cx: &mut Context<'_>
) -> Poll<Result<SendStream>>
pub fn poll_open_send_stream(
&mut self,
cx: &mut Context<'_>
) -> Poll<Result<SendStream>>
Polls opening a SendStream
sourcepub fn local_addr(&self) -> Result<SocketAddr>
pub fn local_addr(&self) -> Result<SocketAddr>
Returns the local address that this connection is bound to.
sourcepub fn remote_addr(&self) -> Result<SocketAddr>
pub fn remote_addr(&self) -> Result<SocketAddr>
Returns the remote address that this connection is connected to.
sourcepub fn server_name(&self) -> Result<Option<Name>>
pub fn server_name(&self) -> Result<Option<Name>>
Returns the negotiated server name the connection is using.
sourcepub fn application_protocol(&self) -> Result<Bytes>
pub fn application_protocol(&self) -> Result<Bytes>
Returns the negotiated application protocol the connection is using
sourcepub fn id(&self) -> u64
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
sourcepub fn keep_alive(&mut self, enabled: bool) -> Result<()>
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.
sourcepub fn close(&self, error_code: Error)
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());
sourcepub fn query_event_context<Query, EventContext, Outcome>(
&self,
query: Query
) -> Result<Outcome, Error>where
Query: FnOnce(&EventContext) -> Outcome,
EventContext: 'static,
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 ConnectionContext
s 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 );
sourcepub fn query_event_context_mut<Query, EventContext, Outcome>(
&mut self,
query: Query
) -> Result<Outcome, Error>where
Query: FnOnce(&mut EventContext) -> Outcome,
EventContext: 'static,
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
);
sourcepub fn datagram_mut<Query, ProviderType, Outcome>(
&mut self,
query: Query
) -> Result<Outcome, Error>where
Query: FnOnce(&mut ProviderType) -> Outcome,
ProviderType: 'static,
pub fn datagram_mut<Query, ProviderType, Outcome>(
&mut 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]));
);
sourcepub fn handle(&self) -> Handle
pub fn handle(&self) -> Handle
Returns a cloneable handle to the connection
Examples
let handle = connection.handle();
let another_handle = handle.clone();
sourcepub fn split(self) -> (Handle, StreamAcceptor)
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());
}