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(core_ctx: &CC, ip_options: &IpOptions<I, CC::WeakDeviceId, Self>)
283 -> bool;
284
285 fn to_other_socket_options<'a>(
286 core_ctx: &CC,
287 state: &'a IpOptions<I, CC::WeakDeviceId, Self>,
288 ) -> &'a DatagramIpSpecificSocketOptions<I::OtherVersion, CC::WeakDeviceId>;
289
290 fn ds_converter(core_ctx: &CC) -> impl DualStackConverter<I, CC::WeakDeviceId, Self>;
291
292 fn to_other_bound_socket_id(
293 core_ctx: &CC,
294 id: &Self::SocketId<I, CC::WeakDeviceId>,
295 ) -> <Self::SocketMapSpec<I::OtherVersion, CC::WeakDeviceId> as DatagramSocketMapSpec<
296 I::OtherVersion,
297 CC::WeakDeviceId,
298 Self::AddrSpec,
299 >>::BoundSocketId;
300
301 fn with_both_bound_sockets_mut<
302 O,
303 F: FnOnce(
304 &mut Self::IpSocketsCtx<'_>,
305 &mut BoundSocketsFromSpec<I, CC, Self>,
306 &mut BoundSocketsFromSpec<I::OtherVersion, CC, Self>,
307 ) -> O,
308 >(
309 core_ctx: &mut CC,
310 cb: F,
311 ) -> O;
312
313 fn with_other_bound_sockets_mut<
314 O,
315 F: FnOnce(
316 &mut Self::IpSocketsCtx<'_>,
317 &mut BoundSocketsFromSpec<I::OtherVersion, CC, Self>,
318 ) -> O,
319 >(
320 core_ctx: &mut CC,
321 cb: F,
322 ) -> O;
323
324 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
325 core_ctx: &mut CC,
326 cb: F,
327 ) -> O;
328}
329
330impl<I, CC, BC, S> DualStackDatagramBoundStateContext<I, BC, S> for CC
331where
332 I: IpExt,
333 CC: DeviceIdContext<AnyDevice>,
334 BC: DatagramBindingsTypes,
335 S: DualStackDatagramSpecBoundStateContext<I, CC, BC>,
336{
337 type IpSocketsCtx<'a> = S::IpSocketsCtx<'a>;
338
339 fn dual_stack_enabled(&self, ip_options: &IpOptions<I, Self::WeakDeviceId, S>) -> bool {
340 S::dual_stack_enabled(self, ip_options)
341 }
342
343 fn to_other_socket_options<'a>(
344 &self,
345 ip_options: &'a IpOptions<I, Self::WeakDeviceId, S>,
346 ) -> &'a DatagramIpSpecificSocketOptions<I::OtherVersion, Self::WeakDeviceId> {
347 S::to_other_socket_options(self, ip_options)
348 }
349
350 fn ds_converter(&self) -> impl DualStackConverter<I, Self::WeakDeviceId, S> {
351 S::ds_converter(self)
352 }
353
354 fn to_other_bound_socket_id(
355 &self,
356 id: &S::SocketId<I, Self::WeakDeviceId>,
357 ) -> <S::SocketMapSpec<I::OtherVersion, Self::WeakDeviceId> as DatagramSocketMapSpec<
358 I::OtherVersion,
359 Self::WeakDeviceId,
360 S::AddrSpec,
361 >>::BoundSocketId {
362 S::to_other_bound_socket_id(self, id)
363 }
364
365 fn with_both_bound_sockets_mut<
366 O,
367 F: FnOnce(
368 &mut Self::IpSocketsCtx<'_>,
369 &mut BoundSocketsFromSpec<I, Self, S>,
370 &mut BoundSocketsFromSpec<I::OtherVersion, Self, S>,
371 ) -> O,
372 >(
373 &mut self,
374 cb: F,
375 ) -> O {
376 S::with_both_bound_sockets_mut(self, cb)
377 }
378
379 fn with_other_bound_sockets_mut<
380 O,
381 F: FnOnce(
382 &mut Self::IpSocketsCtx<'_>,
383 &mut BoundSocketsFromSpec<I::OtherVersion, Self, S>,
384 ) -> O,
385 >(
386 &mut self,
387 cb: F,
388 ) -> O {
389 S::with_other_bound_sockets_mut(self, cb)
390 }
391
392 fn with_transport_context<O, F: FnOnce(&mut Self::IpSocketsCtx<'_>) -> O>(
393 &mut self,
394 cb: F,
395 ) -> O {
396 S::with_transport_context(self, cb)
397 }
398}
399
400#[allow(missing_docs)]
410pub trait NonDualStackDatagramSpecBoundStateContext<I: IpExt, CC: DeviceIdContext<AnyDevice>, BC>:
411 DatagramSocketSpec
412{
413 fn nds_converter(core_ctx: &CC) -> impl NonDualStackConverter<I, CC::WeakDeviceId, Self>;
414}
415
416impl<I, CC, BC, S> NonDualStackDatagramBoundStateContext<I, BC, S> for CC
417where
418 I: IpExt,
419 CC: DeviceIdContext<AnyDevice>,
420 S: NonDualStackDatagramSpecBoundStateContext<I, CC, BC>,
421{
422 fn nds_converter(&self) -> impl NonDualStackConverter<I, CC::WeakDeviceId, S> {
423 S::nds_converter(self)
424 }
425}