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: &CC,
197 ) -> MaybeDualStack<&Self::DualStackContext, &Self::NonDualStackContext>;
198
199 fn dual_stack_context_mut(
200 core_ctx: &mut CC,
201 ) -> MaybeDualStack<&mut Self::DualStackContext, &mut Self::NonDualStackContext>;
202
203 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
204 core_ctx: &mut CC,
205 cb: F,
206 ) -> O;
207}
208
209impl<I, CC, BC, S> DatagramBoundStateContext<I, BC, S> for CC
210where
211 I: IpExt + DualStackIpExt,
212 CC: DeviceIdContext<AnyDevice>,
213 BC: DatagramBindingsTypes,
214 S: DatagramSpecBoundStateContext<I, CC, BC>,
215{
216 type IpSocketsCtx<'a> = S::IpSocketsCtx<'a>;
217 type DualStackContext = S::DualStackContext;
218 type NonDualStackContext = S::NonDualStackContext;
219
220 fn with_bound_sockets<
221 O,
222 F: FnOnce(&mut Self::IpSocketsCtx<'_>, &BoundSocketsFromSpec<I, CC, S>) -> O,
223 >(
224 &mut self,
225 cb: F,
226 ) -> O {
227 S::with_bound_sockets(self, cb)
228 }
229
230 fn with_bound_sockets_mut<
231 O,
232 F: FnOnce(&mut Self::IpSocketsCtx<'_>, &mut BoundSocketsFromSpec<I, CC, S>) -> O,
233 >(
234 &mut self,
235 cb: F,
236 ) -> O {
237 S::with_bound_sockets_mut(self, cb)
238 }
239
240 fn dual_stack_context(
241 &self,
242 ) -> MaybeDualStack<&Self::DualStackContext, &Self::NonDualStackContext> {
243 S::dual_stack_context(self)
244 }
245
246 fn dual_stack_context_mut(
247 &mut self,
248 ) -> MaybeDualStack<&mut Self::DualStackContext, &mut Self::NonDualStackContext> {
249 S::dual_stack_context_mut(self)
250 }
251
252 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
253 &mut self,
254 cb: F,
255 ) -> O {
256 S::with_transport_context(self, cb)
257 }
258}
259
260#[allow(missing_docs)]
270pub trait DualStackDatagramSpecBoundStateContext<
271 I: IpExt,
272 CC: DeviceIdContext<AnyDevice>,
273 BC: DatagramBindingsTypes,
274>: DatagramSocketSpec
275{
276 type IpSocketsCtx<'a>: TransportIpContext<I, BC>
277 + CoreTxMetadataContext<TxMetadata<I, CC::WeakDeviceId, Self>, BC>
278 + DeviceIdContext<AnyDevice, DeviceId = CC::DeviceId, WeakDeviceId = CC::WeakDeviceId>
279 + TransportIpContext<I::OtherVersion, BC>
280 + CoreTxMetadataContext<TxMetadata<I::OtherVersion, CC::WeakDeviceId, Self>, BC>;
281
282 fn dual_stack_enabled(
283 core_ctx: &CC,
284 state: &impl AsRef<IpOptions<I, CC::WeakDeviceId, Self>>,
285 ) -> bool;
286
287 fn to_other_socket_options<'a>(
288 core_ctx: &CC,
289 state: &'a IpOptions<I, CC::WeakDeviceId, Self>,
290 ) -> &'a DatagramIpSpecificSocketOptions<I::OtherVersion, CC::WeakDeviceId>;
291
292 fn ds_converter(core_ctx: &CC) -> impl DualStackConverter<I, CC::WeakDeviceId, Self>;
293
294 fn to_other_bound_socket_id(
295 core_ctx: &CC,
296 id: &Self::SocketId<I, CC::WeakDeviceId>,
297 ) -> <Self::SocketMapSpec<I::OtherVersion, CC::WeakDeviceId> as DatagramSocketMapSpec<
298 I::OtherVersion,
299 CC::WeakDeviceId,
300 Self::AddrSpec,
301 >>::BoundSocketId;
302
303 fn with_both_bound_sockets_mut<
304 O,
305 F: FnOnce(
306 &mut Self::IpSocketsCtx<'_>,
307 &mut BoundSocketsFromSpec<I, CC, Self>,
308 &mut BoundSocketsFromSpec<I::OtherVersion, CC, Self>,
309 ) -> O,
310 >(
311 core_ctx: &mut CC,
312 cb: F,
313 ) -> O;
314
315 fn with_other_bound_sockets_mut<
316 O,
317 F: FnOnce(
318 &mut Self::IpSocketsCtx<'_>,
319 &mut BoundSocketsFromSpec<I::OtherVersion, CC, Self>,
320 ) -> O,
321 >(
322 core_ctx: &mut CC,
323 cb: F,
324 ) -> O;
325
326 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
327 core_ctx: &mut CC,
328 cb: F,
329 ) -> O;
330}
331
332impl<I, CC, BC, S> DualStackDatagramBoundStateContext<I, BC, S> for CC
333where
334 I: IpExt,
335 CC: DeviceIdContext<AnyDevice>,
336 BC: DatagramBindingsTypes,
337 S: DualStackDatagramSpecBoundStateContext<I, CC, BC>,
338{
339 type IpSocketsCtx<'a> = S::IpSocketsCtx<'a>;
340
341 fn dual_stack_enabled(&self, state: &impl AsRef<IpOptions<I, Self::WeakDeviceId, S>>) -> bool {
342 S::dual_stack_enabled(self, state)
343 }
344
345 fn to_other_socket_options<'a>(
346 &self,
347 state: &'a IpOptions<I, Self::WeakDeviceId, S>,
348 ) -> &'a DatagramIpSpecificSocketOptions<I::OtherVersion, Self::WeakDeviceId> {
349 S::to_other_socket_options(self, state)
350 }
351
352 fn ds_converter(&self) -> impl DualStackConverter<I, Self::WeakDeviceId, S> {
353 S::ds_converter(self)
354 }
355
356 fn to_other_bound_socket_id(
357 &self,
358 id: &S::SocketId<I, Self::WeakDeviceId>,
359 ) -> <S::SocketMapSpec<I::OtherVersion, Self::WeakDeviceId> as DatagramSocketMapSpec<
360 I::OtherVersion,
361 Self::WeakDeviceId,
362 S::AddrSpec,
363 >>::BoundSocketId {
364 S::to_other_bound_socket_id(self, id)
365 }
366
367 fn with_both_bound_sockets_mut<
368 O,
369 F: FnOnce(
370 &mut Self::IpSocketsCtx<'_>,
371 &mut BoundSocketsFromSpec<I, Self, S>,
372 &mut BoundSocketsFromSpec<I::OtherVersion, Self, S>,
373 ) -> O,
374 >(
375 &mut self,
376 cb: F,
377 ) -> O {
378 S::with_both_bound_sockets_mut(self, cb)
379 }
380
381 fn with_other_bound_sockets_mut<
382 O,
383 F: FnOnce(
384 &mut Self::IpSocketsCtx<'_>,
385 &mut BoundSocketsFromSpec<I::OtherVersion, Self, S>,
386 ) -> O,
387 >(
388 &mut self,
389 cb: F,
390 ) -> O {
391 S::with_other_bound_sockets_mut(self, cb)
392 }
393
394 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
395 &mut self,
396 cb: F,
397 ) -> O {
398 S::with_transport_context(self, cb)
399 }
400}
401
402#[allow(missing_docs)]
412pub trait NonDualStackDatagramSpecBoundStateContext<I: IpExt, CC: DeviceIdContext<AnyDevice>, BC>:
413 DatagramSocketSpec
414{
415 fn nds_converter(core_ctx: &CC) -> impl NonDualStackConverter<I, CC::WeakDeviceId, Self>;
416}
417
418impl<I, CC, BC, S> NonDualStackDatagramBoundStateContext<I, BC, S> for CC
419where
420 I: IpExt,
421 CC: DeviceIdContext<AnyDevice>,
422 S: NonDualStackDatagramSpecBoundStateContext<I, CC, BC>,
423{
424 fn nds_converter(&self) -> impl NonDualStackConverter<I, CC::WeakDeviceId, S> {
425 S::nds_converter(self)
426 }
427}