1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
use crate::{
io::{rx, tx},
path::{self, mtu},
time::{Clock, Timestamp},
};
use core::{
fmt,
future::Future,
task::{Context, Poll},
};
pub mod limits;
pub use limits::Limiter;
/// Enumerates endpoint types
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Type {
/// The endpoint is a client
Client,
/// The endpoint is a server
Server,
}
impl Type {
/// Returns true if the given endpoint is a QUIC client
pub fn is_client(self) -> bool {
self == Self::Client
}
/// Returns true if the given endpoint is a QUIC server
pub fn is_server(self) -> bool {
self == Self::Server
}
/// Returns the [`Type`] of the peer.
/// - If called on `Client` this will return `Server`
/// - If called on `Server` this will return `Client`
#[must_use]
pub fn peer_type(self) -> Self {
match self {
Self::Client => Self::Server,
Self::Server => Self::Client,
}
}
}
/// Enumerates endpoint locations
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub enum Location {
/// The local endpoint
Local,
/// The remote endpoint
Remote,
}
impl fmt::Display for Location {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self {
Self::Local => write!(f, "the local endpoint"),
Self::Remote => write!(f, "the remote endpoint"),
}
}
}
impl Location {
/// Returns true if the given endpoint is local
pub fn is_local(self) -> bool {
self == Self::Local
}
/// Returns true if the given endpoint is remote
pub fn is_remote(self) -> bool {
self == Self::Remote
}
/// Returns the [`Location`] of the peer.
/// - If called on `Local` this will return `Remote`
/// - If called on `Remote` this will return `Local`
#[must_use]
pub fn peer_type(self) -> Self {
match self {
Self::Local => Self::Remote,
Self::Remote => Self::Local,
}
}
}
/// The main interface for a QUIC endpoint
pub trait Endpoint: 'static + Send + Sized {
type PathHandle: path::Handle;
type Subscriber: crate::event::Subscriber;
const ENDPOINT_TYPE: Type;
/// Receives and processes datagrams for the Rx queue
fn receive<Rx, C>(&mut self, rx: &mut Rx, clock: &C)
where
Rx: rx::Queue<Handle = Self::PathHandle>,
C: Clock;
/// Transmits outgoing datagrams into the Tx queue
fn transmit<Tx, C>(&mut self, tx: &mut Tx, clock: &C)
where
Tx: tx::Queue<Handle = Self::PathHandle>,
C: Clock;
/// Returns a future which polls for application-space wakeups
///
/// When successful, the number of wakeups is returned.
fn wakeups<'a, C: Clock>(&'a mut self, clock: &'a C) -> Wakeups<'a, Self, C> {
Wakeups {
endpoint: self,
clock,
}
}
/// Polls for any application-space wakeups
///
/// When successful, the number of wakeups is returned.
fn poll_wakeups<C: Clock>(
&mut self,
cx: &mut Context<'_>,
clock: &C,
) -> Poll<Result<usize, CloseError>>;
/// Returns the latest Timestamp at which `transmit` should be called
fn timeout(&self) -> Option<Timestamp>;
/// Sets configuration for the maximum transmission unit (MTU) that can be sent on a path
fn set_mtu_config(&mut self, mtu_config: mtu::Config);
/// Returns the endpoint's event subscriber
fn subscriber(&mut self) -> &mut Self::Subscriber;
}
/// A future which polls an endpoint for application-space wakeups
pub struct Wakeups<'a, E: Endpoint, C: Clock> {
endpoint: &'a mut E,
clock: &'a C,
}
impl<'a, E: Endpoint, C: Clock> Future for Wakeups<'a, E, C> {
type Output = Result<usize, CloseError>;
fn poll(mut self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let clock = self.clock;
self.endpoint.poll_wakeups(cx, clock)
}
}
/// Indicates the endpoint is no longer processing connections.
#[derive(Clone, Copy, Debug)]
pub struct CloseError;