s2n_quic_dc/stream/
environment.rs1use crate::{
5 clock,
6 either::Either,
7 event,
8 stream::{recv, runtime, socket, TransportFeatures},
9};
10use core::future::Future;
11use s2n_quic_core::{inet::SocketAddress, time::Timestamp, varint::VarInt};
12use s2n_quic_platform::features;
13use std::{io, sync::Arc};
14
15use super::recv::buffer::Buffer;
16
17type Result<T = (), E = io::Error> = core::result::Result<T, E>;
18
19#[cfg(any(feature = "testing", test))]
20#[allow(
21 clippy::unwrap_used,
22 clippy::unwrap_in_result,
23 clippy::panic,
24 clippy::panic_in_result_fn,
25 reason = "bach simulation environment is test-support code and may panic to surface setup failures"
26)]
27pub mod bach;
28#[cfg(feature = "tokio")]
29pub mod tokio;
30pub mod udp;
31
32pub trait Environment {
33 type Clock: Clone + clock::Clock;
34 type Subscriber: event::Subscriber + Clone;
35
36 fn subscriber(&self) -> &Self::Subscriber;
37 fn clock(&self) -> Self::Clock;
38 fn gso(&self) -> features::Gso;
39 fn reader_rt(&self) -> runtime::ArcHandle<Self::Subscriber>;
40 fn spawn_reader<F: 'static + Send + Future<Output = ()>>(&self, f: F);
41 fn writer_rt(&self) -> runtime::ArcHandle<Self::Subscriber>;
42 fn spawn_writer<F: 'static + Send + Future<Output = ()>>(&self, f: F);
43
44 #[inline]
46 fn endpoint_publisher(&self) -> event::EndpointPublisherSubscriber<'_, Self::Subscriber> {
47 use s2n_quic_core::time::Clock as _;
48
49 self.endpoint_publisher_with_time(self.clock().get_time())
50 }
51
52 #[inline]
53 fn endpoint_publisher_with_time(
54 &self,
55 timestamp: Timestamp,
56 ) -> event::EndpointPublisherSubscriber<'_, Self::Subscriber> {
57 use s2n_quic_core::event::IntoEvent;
58
59 let timestamp = timestamp.into_event();
60
61 event::EndpointPublisherSubscriber::new(
62 event::builder::EndpointMeta { timestamp },
63 None,
64 self.subscriber(),
65 )
66 }
67}
68
69impl<A, B> Environment for Either<A, B>
70where
71 A: Environment,
72 B: Environment<Subscriber = A::Subscriber>,
73{
74 type Clock = Either<A::Clock, B::Clock>;
75 type Subscriber = A::Subscriber;
76
77 fn subscriber(&self) -> &Self::Subscriber {
78 match self {
79 Either::A(a) => a.subscriber(),
80 Either::B(b) => b.subscriber(),
81 }
82 }
83
84 fn clock(&self) -> Self::Clock {
85 match self {
86 Either::A(a) => Either::A(a.clock()),
87 Either::B(b) => Either::B(b.clock()),
88 }
89 }
90
91 fn gso(&self) -> features::Gso {
92 match self {
93 Either::A(a) => a.gso(),
94 Either::B(b) => b.gso(),
95 }
96 }
97
98 fn reader_rt(&self) -> runtime::ArcHandle<Self::Subscriber> {
99 match self {
100 Either::A(a) => a.reader_rt(),
101 Either::B(b) => b.reader_rt(),
102 }
103 }
104
105 fn spawn_reader<F: 'static + Send + Future<Output = ()>>(&self, f: F) {
106 match self {
107 Either::A(a) => a.spawn_reader(f),
108 Either::B(b) => b.spawn_reader(f),
109 }
110 }
111
112 fn writer_rt(&self) -> runtime::ArcHandle<Self::Subscriber> {
113 match self {
114 Either::A(a) => a.writer_rt(),
115 Either::B(b) => b.writer_rt(),
116 }
117 }
118
119 fn spawn_writer<F: 'static + Send + Future<Output = ()>>(&self, f: F) {
120 match self {
121 Either::A(a) => a.spawn_writer(f),
122 Either::B(b) => b.spawn_writer(f),
123 }
124 }
125}
126
127pub struct SocketSet<R, W = R> {
128 pub application: Box<dyn socket::application::Builder>,
129 pub read_worker: Option<R>,
130 pub write_worker: Option<W>,
131 pub remote_addr: SocketAddress,
132 pub source_queue_id: Option<VarInt>,
133}
134
135type SetupResult<ReadWorker, WriteWorker> =
136 Result<(SocketSet<ReadWorker, WriteWorker>, recv::shared::RecvBuffer)>;
137
138pub trait Peer<E: Environment> {
139 type ReadWorkerSocket: ReadWorkerSocket;
140 type WriteWorkerSocket: WriteWorkerSocket;
141
142 fn features(&self) -> TransportFeatures;
143 fn setup(self, env: &E) -> SetupResult<Self::ReadWorkerSocket, Self::WriteWorkerSocket>;
144}
145
146pub trait ReadWorkerSocket {
147 type Socket: super::socket::Socket;
148
149 fn setup(self) -> Self::Socket;
150}
151
152impl ReadWorkerSocket for () {
153 type Socket = super::socket::SendOnly<Arc<std::net::UdpSocket>>;
154
155 #[inline]
156 fn setup(self) -> Self::Socket {
157 unreachable!()
158 }
159}
160
161impl<T: super::socket::Socket> ReadWorkerSocket for T {
162 type Socket = T;
163
164 #[inline]
165 fn setup(self) -> Self::Socket {
166 self
167 }
168}
169
170pub trait WriteWorkerSocket {
171 type Socket: super::socket::Socket;
172 type Buffer: 'static + Buffer + Send;
173
174 fn setup(self) -> (Self::Socket, Self::Buffer);
175}
176
177impl WriteWorkerSocket for () {
178 type Socket = super::socket::SendOnly<Arc<std::net::UdpSocket>>;
179 type Buffer = recv::buffer::Local;
180
181 #[inline]
182 fn setup(self) -> (Self::Socket, Self::Buffer) {
183 unreachable!()
184 }
185}
186
187impl<T: super::socket::Socket, B: 'static + Buffer + Send> WriteWorkerSocket for (T, B) {
188 type Socket = T;
189 type Buffer = B;
190
191 #[inline]
192 fn setup(self) -> (Self::Socket, Self::Buffer) {
193 self
194 }
195}
196
197pub struct AcceptError<Peer> {
198 pub secret_control: Vec<u8>,
199 pub peer: Option<Peer>,
200 pub error: io::Error,
201}
202
203pub struct Builder<E: Environment> {
204 env: E,
205}
206
207impl<E: Environment> Builder<E> {
208 #[inline]
209 pub fn new(env: E) -> Self {
210 Self { env }
211 }
212
213 #[inline]
214 pub fn clock(&self) -> E::Clock {
215 self.env.clock()
216 }
217}