1use netstack3_base::socket::MaybeDualStack;
15use netstack3_base::{AnyDevice, CoreTxMetadataContext, DeviceIdContext};
16use netstack3_ip::{MulticastMembershipHandler, TransportIpContext};
17
18use crate::internal::datagram::{
19 BoundSocketsFromSpec, DatagramBindingsTypes, DatagramBoundStateContext,
20 DatagramIpSpecificSocketOptions, DatagramSocketMapSpec, DatagramSocketSet, DatagramSocketSpec,
21 DatagramStateContext, DualStackConverter, DualStackDatagramBoundStateContext, DualStackIpExt,
22 IpExt, IpOptions, NonDualStackConverter, NonDualStackDatagramBoundStateContext, SocketState,
23};
24use crate::internal::sndbuf::TxMetadata;
25
26#[allow(missing_docs)]
35pub trait DatagramSpecStateContext<
36 I: IpExt,
37 CC: DeviceIdContext<AnyDevice>,
38 BC: DatagramBindingsTypes,
39>: DatagramSocketSpec
40{
41 type SocketsStateCtx<'a>: DatagramBoundStateContext<I, BC, Self>
42 + DeviceIdContext<AnyDevice, DeviceId = CC::DeviceId, WeakDeviceId = CC::WeakDeviceId>;
43
44 fn with_all_sockets_mut<O, F: FnOnce(&mut DatagramSocketSet<I, CC::WeakDeviceId, Self>) -> O>(
45 core_ctx: &mut CC,
46 cb: F,
47 ) -> O;
48
49 fn with_all_sockets<O, F: FnOnce(&DatagramSocketSet<I, CC::WeakDeviceId, Self>) -> O>(
50 core_ctx: &mut CC,
51 cb: F,
52 ) -> O;
53
54 fn with_socket_state<
55 O,
56 F: FnOnce(&mut Self::SocketsStateCtx<'_>, &SocketState<I, CC::WeakDeviceId, Self>) -> O,
57 >(
58 core_ctx: &mut CC,
59 id: &Self::SocketId<I, CC::WeakDeviceId>,
60 cb: F,
61 ) -> O;
62
63 fn with_socket_state_mut<
64 O,
65 F: FnOnce(&mut Self::SocketsStateCtx<'_>, &mut SocketState<I, CC::WeakDeviceId, Self>) -> O,
66 >(
67 core_ctx: &mut CC,
68 id: &Self::SocketId<I, CC::WeakDeviceId>,
69 cb: F,
70 ) -> O;
71
72 fn for_each_socket<
73 F: FnMut(
74 &mut Self::SocketsStateCtx<'_>,
75 &Self::SocketId<I, CC::WeakDeviceId>,
76 &SocketState<I, CC::WeakDeviceId, Self>,
77 ),
78 >(
79 core_ctx: &mut CC,
80 cb: F,
81 );
82}
83
84impl<I, CC, BC, S> DatagramStateContext<I, BC, S> for CC
85where
86 I: IpExt,
87 BC: DatagramBindingsTypes,
88 CC: DeviceIdContext<AnyDevice>,
89 S: DatagramSpecStateContext<I, CC, BC>,
90{
91 type SocketsStateCtx<'a> = S::SocketsStateCtx<'a>;
92
93 fn with_all_sockets_mut<O, F: FnOnce(&mut DatagramSocketSet<I, Self::WeakDeviceId, S>) -> O>(
94 &mut self,
95 cb: F,
96 ) -> O {
97 S::with_all_sockets_mut(self, cb)
98 }
99
100 fn with_all_sockets<O, F: FnOnce(&DatagramSocketSet<I, Self::WeakDeviceId, S>) -> O>(
101 &mut self,
102 cb: F,
103 ) -> O {
104 S::with_all_sockets(self, cb)
105 }
106
107 fn with_socket_state<
108 O,
109 F: FnOnce(&mut Self::SocketsStateCtx<'_>, &SocketState<I, Self::WeakDeviceId, S>) -> O,
110 >(
111 &mut self,
112 id: &S::SocketId<I, Self::WeakDeviceId>,
113 cb: F,
114 ) -> O {
115 S::with_socket_state(self, id, cb)
116 }
117
118 fn with_socket_state_mut<
119 O,
120 F: FnOnce(&mut Self::SocketsStateCtx<'_>, &mut SocketState<I, Self::WeakDeviceId, S>) -> O,
121 >(
122 &mut self,
123 id: &S::SocketId<I, Self::WeakDeviceId>,
124 cb: F,
125 ) -> O {
126 S::with_socket_state_mut(self, id, cb)
127 }
128
129 fn for_each_socket<
130 F: FnMut(
131 &mut Self::SocketsStateCtx<'_>,
132 &S::SocketId<I, Self::WeakDeviceId>,
133 &SocketState<I, Self::WeakDeviceId, S>,
134 ),
135 >(
136 &mut self,
137 cb: F,
138 ) {
139 S::for_each_socket(self, cb)
140 }
141}
142
143#[allow(missing_docs)]
152pub trait DatagramSpecBoundStateContext<
153 I: IpExt + DualStackIpExt,
154 CC: DeviceIdContext<AnyDevice>,
155 BC: DatagramBindingsTypes,
156>: DatagramSocketSpec
157{
158 type IpSocketsCtx<'a>: TransportIpContext<I, BC>
159 + CoreTxMetadataContext<TxMetadata<I, CC::WeakDeviceId, Self>, BC>
160 + MulticastMembershipHandler<I, BC>
161 + DeviceIdContext<AnyDevice, DeviceId = CC::DeviceId, WeakDeviceId = CC::WeakDeviceId>;
162
163 type DualStackContext: DualStackDatagramBoundStateContext<
164 I,
165 BC,
166 Self,
167 DeviceId = CC::DeviceId,
168 WeakDeviceId = CC::WeakDeviceId,
169 >;
170
171 type NonDualStackContext: NonDualStackDatagramBoundStateContext<
172 I,
173 BC,
174 Self,
175 DeviceId = CC::DeviceId,
176 WeakDeviceId = CC::WeakDeviceId,
177 >;
178
179 fn with_bound_sockets<
180 O,
181 F: FnOnce(&mut Self::IpSocketsCtx<'_>, &BoundSocketsFromSpec<I, CC, Self>) -> O,
182 >(
183 core_ctx: &mut CC,
184 cb: F,
185 ) -> O;
186
187 fn with_bound_sockets_mut<
188 O,
189 F: FnOnce(&mut Self::IpSocketsCtx<'_>, &mut BoundSocketsFromSpec<I, CC, Self>) -> O,
190 >(
191 core_ctx: &mut CC,
192 cb: F,
193 ) -> O;
194
195 fn dual_stack_context(
196 core_ctx: &mut CC,
197 ) -> MaybeDualStack<&mut Self::DualStackContext, &mut Self::NonDualStackContext>;
198
199 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
200 core_ctx: &mut CC,
201 cb: F,
202 ) -> O;
203}
204
205impl<I, CC, BC, S> DatagramBoundStateContext<I, BC, S> for CC
206where
207 I: IpExt + DualStackIpExt,
208 CC: DeviceIdContext<AnyDevice>,
209 BC: DatagramBindingsTypes,
210 S: DatagramSpecBoundStateContext<I, CC, BC>,
211{
212 type IpSocketsCtx<'a> = S::IpSocketsCtx<'a>;
213 type DualStackContext = S::DualStackContext;
214 type NonDualStackContext = S::NonDualStackContext;
215
216 fn with_bound_sockets<
217 O,
218 F: FnOnce(&mut Self::IpSocketsCtx<'_>, &BoundSocketsFromSpec<I, CC, S>) -> O,
219 >(
220 &mut self,
221 cb: F,
222 ) -> O {
223 S::with_bound_sockets(self, cb)
224 }
225
226 fn with_bound_sockets_mut<
227 O,
228 F: FnOnce(&mut Self::IpSocketsCtx<'_>, &mut BoundSocketsFromSpec<I, CC, S>) -> O,
229 >(
230 &mut self,
231 cb: F,
232 ) -> O {
233 S::with_bound_sockets_mut(self, cb)
234 }
235
236 fn dual_stack_context(
237 &mut self,
238 ) -> MaybeDualStack<&mut Self::DualStackContext, &mut Self::NonDualStackContext> {
239 S::dual_stack_context(self)
240 }
241
242 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
243 &mut self,
244 cb: F,
245 ) -> O {
246 S::with_transport_context(self, cb)
247 }
248}
249
250#[allow(missing_docs)]
260pub trait DualStackDatagramSpecBoundStateContext<
261 I: IpExt,
262 CC: DeviceIdContext<AnyDevice>,
263 BC: DatagramBindingsTypes,
264>: DatagramSocketSpec
265{
266 type IpSocketsCtx<'a>: TransportIpContext<I, BC>
267 + CoreTxMetadataContext<TxMetadata<I, CC::WeakDeviceId, Self>, BC>
268 + DeviceIdContext<AnyDevice, DeviceId = CC::DeviceId, WeakDeviceId = CC::WeakDeviceId>
269 + TransportIpContext<I::OtherVersion, BC>
270 + CoreTxMetadataContext<TxMetadata<I::OtherVersion, CC::WeakDeviceId, Self>, BC>;
271
272 fn dual_stack_enabled(
273 core_ctx: &CC,
274 state: &impl AsRef<IpOptions<I, CC::WeakDeviceId, Self>>,
275 ) -> bool;
276
277 fn to_other_socket_options<'a>(
278 core_ctx: &CC,
279 state: &'a IpOptions<I, CC::WeakDeviceId, Self>,
280 ) -> &'a DatagramIpSpecificSocketOptions<I::OtherVersion, CC::WeakDeviceId>;
281
282 fn ds_converter(core_ctx: &CC) -> impl DualStackConverter<I, CC::WeakDeviceId, Self>;
283
284 fn to_other_bound_socket_id(
285 core_ctx: &CC,
286 id: &Self::SocketId<I, CC::WeakDeviceId>,
287 ) -> <Self::SocketMapSpec<I::OtherVersion, CC::WeakDeviceId> as DatagramSocketMapSpec<
288 I::OtherVersion,
289 CC::WeakDeviceId,
290 Self::AddrSpec,
291 >>::BoundSocketId;
292
293 fn with_both_bound_sockets_mut<
294 O,
295 F: FnOnce(
296 &mut Self::IpSocketsCtx<'_>,
297 &mut BoundSocketsFromSpec<I, CC, Self>,
298 &mut BoundSocketsFromSpec<I::OtherVersion, CC, Self>,
299 ) -> O,
300 >(
301 core_ctx: &mut CC,
302 cb: F,
303 ) -> O;
304
305 fn with_other_bound_sockets_mut<
306 O,
307 F: FnOnce(
308 &mut Self::IpSocketsCtx<'_>,
309 &mut BoundSocketsFromSpec<I::OtherVersion, CC, Self>,
310 ) -> O,
311 >(
312 core_ctx: &mut CC,
313 cb: F,
314 ) -> O;
315
316 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
317 core_ctx: &mut CC,
318 cb: F,
319 ) -> O;
320}
321
322impl<I, CC, BC, S> DualStackDatagramBoundStateContext<I, BC, S> for CC
323where
324 I: IpExt,
325 CC: DeviceIdContext<AnyDevice>,
326 BC: DatagramBindingsTypes,
327 S: DualStackDatagramSpecBoundStateContext<I, CC, BC>,
328{
329 type IpSocketsCtx<'a> = S::IpSocketsCtx<'a>;
330
331 fn dual_stack_enabled(&self, state: &impl AsRef<IpOptions<I, Self::WeakDeviceId, S>>) -> bool {
332 S::dual_stack_enabled(self, state)
333 }
334
335 fn to_other_socket_options<'a>(
336 &self,
337 state: &'a IpOptions<I, Self::WeakDeviceId, S>,
338 ) -> &'a DatagramIpSpecificSocketOptions<I::OtherVersion, Self::WeakDeviceId> {
339 S::to_other_socket_options(self, state)
340 }
341
342 fn ds_converter(&self) -> impl DualStackConverter<I, Self::WeakDeviceId, S> {
343 S::ds_converter(self)
344 }
345
346 fn to_other_bound_socket_id(
347 &self,
348 id: &S::SocketId<I, Self::WeakDeviceId>,
349 ) -> <S::SocketMapSpec<I::OtherVersion, Self::WeakDeviceId> as DatagramSocketMapSpec<
350 I::OtherVersion,
351 Self::WeakDeviceId,
352 S::AddrSpec,
353 >>::BoundSocketId {
354 S::to_other_bound_socket_id(self, id)
355 }
356
357 fn with_both_bound_sockets_mut<
358 O,
359 F: FnOnce(
360 &mut Self::IpSocketsCtx<'_>,
361 &mut BoundSocketsFromSpec<I, Self, S>,
362 &mut BoundSocketsFromSpec<I::OtherVersion, Self, S>,
363 ) -> O,
364 >(
365 &mut self,
366 cb: F,
367 ) -> O {
368 S::with_both_bound_sockets_mut(self, cb)
369 }
370
371 fn with_other_bound_sockets_mut<
372 O,
373 F: FnOnce(
374 &mut Self::IpSocketsCtx<'_>,
375 &mut BoundSocketsFromSpec<I::OtherVersion, Self, S>,
376 ) -> O,
377 >(
378 &mut self,
379 cb: F,
380 ) -> O {
381 S::with_other_bound_sockets_mut(self, cb)
382 }
383
384 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
385 &mut self,
386 cb: F,
387 ) -> O {
388 S::with_transport_context(self, cb)
389 }
390}
391
392#[allow(missing_docs)]
402pub trait NonDualStackDatagramSpecBoundStateContext<I: IpExt, CC: DeviceIdContext<AnyDevice>, BC>:
403 DatagramSocketSpec
404{
405 fn nds_converter(core_ctx: &CC) -> impl NonDualStackConverter<I, CC::WeakDeviceId, Self>;
406}
407
408impl<I, CC, BC, S> NonDualStackDatagramBoundStateContext<I, BC, S> for CC
409where
410 I: IpExt,
411 CC: DeviceIdContext<AnyDevice>,
412 S: NonDualStackDatagramSpecBoundStateContext<I, CC, BC>,
413{
414 fn nds_converter(&self) -> impl NonDualStackConverter<I, CC::WeakDeviceId, S> {
415 S::nds_converter(self)
416 }
417}