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 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
//! QUIC Transport traits
//!
//! This module includes traits and types meant to allow being generic over any
//! QUIC implementation.
use std::task::{self, Poll};
use bytes::Buf;
use crate::ext::Datagram;
pub use crate::proto::stream::{InvalidStreamId, StreamId};
pub use crate::stream::WriteBuf;
// Unresolved questions:
//
// - Should the `poll_` methods be `Pin<&mut Self>`?
/// Trait that represent an error from the transport layer
pub trait Error: std::error::Error + Send + Sync {
/// Check if the current error is a transport timeout
fn is_timeout(&self) -> bool;
/// Get the QUIC error code from connection close or stream stop
fn err_code(&self) -> Option<u64>;
}
impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
fn from(err: E) -> Box<dyn Error + 'a> {
Box::new(err)
}
}
/// Trait representing a QUIC connection.
pub trait Connection<B: Buf> {
/// The type produced by `poll_accept_bidi()`
type BidiStream: SendStream<B> + RecvStream;
/// The type of the sending part of `BidiStream`
type SendStream: SendStream<B>;
/// The type produced by `poll_accept_recv()`
type RecvStream: RecvStream;
/// A producer of outgoing Unidirectional and Bidirectional streams.
type OpenStreams: OpenStreams<
B,
SendStream = Self::SendStream,
RecvStream = Self::RecvStream,
BidiStream = Self::BidiStream,
>;
/// Error type yielded by this trait methods
type Error: Into<Box<dyn Error>>;
/// Accept an incoming unidirectional stream
///
/// Returning `None` implies the connection is closing or closed.
fn poll_accept_recv(
&mut self,
cx: &mut task::Context<'_>,
) -> Poll<Result<Option<Self::RecvStream>, Self::Error>>;
/// Accept an incoming bidirectional stream
///
/// Returning `None` implies the connection is closing or closed.
fn poll_accept_bidi(
&mut self,
cx: &mut task::Context<'_>,
) -> Poll<Result<Option<Self::BidiStream>, Self::Error>>;
/// Poll the connection to create a new bidirectional stream.
fn poll_open_bidi(
&mut self,
cx: &mut task::Context<'_>,
) -> Poll<Result<Self::BidiStream, Self::Error>>;
/// Poll the connection to create a new unidirectional stream.
fn poll_open_send(
&mut self,
cx: &mut task::Context<'_>,
) -> Poll<Result<Self::SendStream, Self::Error>>;
/// Get an object to open outgoing streams.
fn opener(&self) -> Self::OpenStreams;
/// Close the connection immediately
fn close(&mut self, code: crate::error::Code, reason: &[u8]);
}
/// Extends the `Connection` trait for sending datagrams
///
/// See: <https://www.rfc-editor.org/rfc/rfc9297>
pub trait SendDatagramExt<B: Buf> {
/// The error type that can occur when sending a datagram
type Error: Into<Box<dyn Error>>;
/// Send a datagram
fn send_datagram(&mut self, data: Datagram<B>) -> Result<(), Self::Error>;
}
/// Extends the `Connection` trait for receiving datagrams
///
/// See: <https://www.rfc-editor.org/rfc/rfc9297>
pub trait RecvDatagramExt {
/// The type of `Buf` for *raw* datagrams (without the stream_id decoded)
type Buf: Buf;
/// The error type that can occur when receiving a datagram
type Error: Into<Box<dyn Error>>;
/// Poll the connection for incoming datagrams.
fn poll_accept_datagram(
&mut self,
cx: &mut task::Context<'_>,
) -> Poll<Result<Option<Self::Buf>, Self::Error>>;
}
/// Trait for opening outgoing streams
pub trait OpenStreams<B: Buf> {
/// The type produced by `poll_open_bidi()`
type BidiStream: SendStream<B> + RecvStream;
/// The type produced by `poll_open_send()`
type SendStream: SendStream<B>;
/// The type of the receiving part of `BidiStream`
type RecvStream: RecvStream;
/// Error type yielded by these trait methods
type Error: Into<Box<dyn Error>>;
/// Poll the connection to create a new bidirectional stream.
fn poll_open_bidi(
&mut self,
cx: &mut task::Context<'_>,
) -> Poll<Result<Self::BidiStream, Self::Error>>;
/// Poll the connection to create a new unidirectional stream.
fn poll_open_send(
&mut self,
cx: &mut task::Context<'_>,
) -> Poll<Result<Self::SendStream, Self::Error>>;
/// Close the connection immediately
fn close(&mut self, code: crate::error::Code, reason: &[u8]);
}
/// A trait describing the "send" actions of a QUIC stream.
pub trait SendStream<B: Buf> {
/// The error type returned by fallible send methods.
type Error: Into<Box<dyn Error>>;
/// Polls if the stream can send more data.
fn poll_ready(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
/// Send more data on the stream.
fn send_data<T: Into<WriteBuf<B>>>(&mut self, data: T) -> Result<(), Self::Error>;
/// Poll to finish the sending side of the stream.
fn poll_finish(&mut self, cx: &mut task::Context<'_>) -> Poll<Result<(), Self::Error>>;
/// Send a QUIC reset code.
fn reset(&mut self, reset_code: u64);
/// Get QUIC send stream id
fn send_id(&self) -> StreamId;
}
/// Allows sending unframed pure bytes to a stream. Similar to [`AsyncWrite`](https://docs.rs/tokio/latest/tokio/io/trait.AsyncWrite.html)
pub trait SendStreamUnframed<B: Buf>: SendStream<B> {
/// Attempts write data into the stream.
///
/// Returns the number of bytes written.
///
/// `buf` is advanced by the number of bytes written.
fn poll_send<D: Buf>(
&mut self,
cx: &mut task::Context<'_>,
buf: &mut D,
) -> Poll<Result<usize, Self::Error>>;
}
/// A trait describing the "receive" actions of a QUIC stream.
pub trait RecvStream {
/// The type of `Buf` for data received on this stream.
type Buf: Buf;
/// The error type that can occur when receiving data.
type Error: Into<Box<dyn Error>>;
/// Poll the stream for more data.
///
/// When the receive side will no longer receive more data (such as because
/// the peer closed their sending side), this should return `None`.
fn poll_data(
&mut self,
cx: &mut task::Context<'_>,
) -> Poll<Result<Option<Self::Buf>, Self::Error>>;
/// Send a `STOP_SENDING` QUIC code.
fn stop_sending(&mut self, error_code: u64);
/// Get QUIC send stream id
fn recv_id(&self) -> StreamId;
}
/// Optional trait to allow "splitting" a bidirectional stream into two sides.
pub trait BidiStream<B: Buf>: SendStream<B> + RecvStream {
/// The type for the send half.
type SendStream: SendStream<B>;
/// The type for the receive half.
type RecvStream: RecvStream;
/// Split this stream into two halves.
fn split(self) -> (Self::SendStream, Self::RecvStream);
}