netstack3_datagram/
spec_context.rs

1// Copyright 2024 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! Datagram spec context definitions.
6//!
7//! This module contains the mirror traits for the datagram core context traits.
8//! They exist in a separate module so that:
9//!
10//! * They're not in scope in the main datagram module, avoiding conflicting
11//!   names.
12//! * The boilerplate around the mirror traits is mostly out of the way.
13
14use 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/// A mirror trait of [`DatagramStateContext`] allowing foreign crates to
27/// provide blanket impls for it.
28///
29/// This trait repeats all the definitions in [`DatagramStateContext`] to
30/// provide blanket impls from an implementation on the type implementing
31/// [`DatagramSocketSpec`], which is local for foreign implementers.
32///
33/// See [`DatagramStateContext`] for details.
34#[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/// A mirror trait of [`DatagramBoundStateContext`] allowing foreign crates to
144/// provide blanket impls for it.
145///
146/// This trait repeats all the definitions in [`DatagramBoundStateContext`] to
147/// provide blanket impls from an implementation on the type implementing
148/// [`DatagramSocketSpec`], which is local for foreign implementers.
149///
150/// See [`DatagramBoundStateContext`] for details.
151#[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/// A mirror trait of [`DualStackDatagramBoundStateContext`] allowing foreign
261/// crates to provide blanket impls for it.
262///
263/// This trait repeats all the definitions in
264/// [`DualStackDatagramBoundStateContext`] to provide blanket impls from an
265/// implementation on the type implementing [`DatagramSocketSpec`], which is
266/// local for foreign implementers.
267///
268/// See [`DualStackDatagramBoundStateContext`] for details.
269#[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/// A mirror trait of [`NonDualStackDatagramBoundStateContext`] allowing foreign
403/// crates to provide blanket impls for it.
404///
405/// This trait repeats all the definitions in
406/// [`NonDualStackDatagramBoundStateContext`] to provide blanket impls from an
407/// implementation on the type implementing [`DatagramSocketSpec`], which is
408/// local for foreign implementers.
409///
410/// See [`NonDualStackDatagramBoundStateContext`] for details.
411#[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}