/
quic.rs
207 lines (172 loc) · 6.71 KB
/
quic.rs
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);
}