rasi_syscall/
net.rs

1//! syscall for networking.
2
3use std::{
4    io,
5    net::{Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr},
6    sync::OnceLock,
7    task::Waker,
8};
9
10use crate::{cancellable::CancelablePoll, handle::Handle};
11
12/// Network-related system call interface
13pub trait Network: Sync + Send {
14    /// Executes an operation of the IP_ADD_MEMBERSHIP type.
15    ///
16    /// This function specifies a new multicast group for this socket to join.
17    /// The address must be a valid multicast address, and interface is the
18    /// address of the local interface with which the system should join the
19    /// multicast group. If it’s equal to INADDR_ANY then an appropriate
20    /// interface is chosen by the system.
21    fn udp_join_multicast_v4(
22        &self,
23        handle: &Handle,
24        multiaddr: &Ipv4Addr,
25        interface: &Ipv4Addr,
26    ) -> io::Result<()>;
27
28    /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
29    ///
30    /// This function specifies a new multicast group for this socket to join.
31    /// The address must be a valid multicast address, and `interface` is the
32    /// index of the interface to join/leave (or 0 to indicate any interface).
33    fn udp_join_multicast_v6(
34        &self,
35        handle: &Handle,
36        multiaddr: &Ipv6Addr,
37        interface: u32,
38    ) -> io::Result<()>;
39
40    /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
41    ///
42    /// For more information about this option, see
43    /// [`join_multicast_v4`][link].
44    ///
45    /// [link]: #method.join_multicast_v4
46    fn udp_leave_multicast_v4(
47        &self,
48        handle: &Handle,
49        multiaddr: &Ipv4Addr,
50        interface: &Ipv4Addr,
51    ) -> io::Result<()>;
52
53    /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
54    ///
55    /// For more information about this option, see
56    /// [`join_multicast_v6`][link].
57    ///
58    /// [link]: #method.join_multicast_v6
59    fn udp_leave_multicast_v6(
60        &self,
61        handle: &Handle,
62        multiaddr: &Ipv6Addr,
63        interface: u32,
64    ) -> io::Result<()>;
65
66    /// Sets the value of the SO_BROADCAST option for this socket.
67    /// When enabled, this socket is allowed to send packets to a broadcast address.
68    fn udp_set_broadcast(&self, handle: &Handle, on: bool) -> io::Result<()>;
69
70    /// Gets the value of the SO_BROADCAST option for this socket.
71    /// For more information about this option, see [`udp_set_broadcast`](Self::udp_set_broadcast).
72    fn udp_broadcast(&self, handle: &Handle) -> io::Result<bool>;
73
74    /// Gets the value of the IP_TTL option for this socket.
75    /// For more information about this option, see [`tcp_listener_set_ttl`](Self::tcp_listener_set_ttl).
76    fn udp_ttl(&self, handle: &Handle) -> io::Result<u32>;
77
78    /// Sets the value for the IP_TTL option on this socket.
79    /// This value sets the time-to-live field that is used in every packet sent from this socket.
80    fn udp_set_ttl(&self, handle: &Handle, ttl: u32) -> io::Result<()>;
81
82    /// Returns the local [`socket address`](SocketAddr) bound to this udp socket.
83    fn udp_local_addr(&self, handle: &Handle) -> io::Result<SocketAddr>;
84
85    /// Create udp socket and bind it to `laddrs`.
86    ///
87    /// Binding with a port number of 0 will request that the OS assigns a port to this socket. The
88    /// port allocated can be queried via the [`udp_local_addr`](Self::udp_local_addr) method.
89    ///
90    /// Returns [`CancelablePoll::Pending(CancelHandle)`](CancelablePoll::Pending),
91    /// indicating that the current operation could not be completed
92    /// immediately and needs to be retried later.
93    fn udp_bind(&self, waker: Waker, laddrs: &[SocketAddr]) -> CancelablePoll<io::Result<Handle>>;
94
95    /// Sends data on the socket to the given `target` address.
96    ///
97    /// On success, returns the number of bytes written.
98    ///
99    /// Returns [`CancelablePoll::Pending(CancelHandle)`](CancelablePoll::Pending),
100    /// indicating that the current operation could not be completed
101    /// immediately and needs to be retried later.
102    fn udp_send_to(
103        &self,
104        waker: Waker,
105        socket: &Handle,
106        buf: &[u8],
107        target: SocketAddr,
108    ) -> CancelablePoll<io::Result<usize>>;
109
110    /// Receives data from the socket.
111    ///
112    /// On success, returns the number of bytes read and the origin.
113    ///
114    /// Returns [`CancelablePoll::Pending(CancelHandle)`](CancelablePoll::Pending),
115    /// indicating that the current operation could not be completed
116    /// immediately and needs to be retried later.
117    fn udp_recv_from(
118        &self,
119        waker: Waker,
120        socket: &Handle,
121        buf: &mut [u8],
122    ) -> CancelablePoll<io::Result<(usize, SocketAddr)>>;
123
124    /// Create new `TcpListener` which will be bound to the specified `laddrs`
125    ///
126    /// The returned listener is ready for accepting connections.
127    ///
128    /// Binding with a port number of 0 will request that the OS assigns a port to this listener.
129    /// The port allocated can be queried via the [`tcp_listener_local_addr`](Self::tcp_listener_local_addr) method.
130    ///
131    /// Returns [`CancelablePoll::Pending(CancelHandle)`](CancelablePoll::Pending),
132    /// indicating that the current operation could not be completed
133    /// immediately and needs to be retried later.
134    fn tcp_listener_bind(
135        &self,
136        waker: Waker,
137        laddrs: &[SocketAddr],
138    ) -> CancelablePoll<io::Result<Handle>>;
139
140    /// Returns the local [`socket address`](SocketAddr) bound to this tcp listener.
141    fn tcp_listener_local_addr(&self, handle: &Handle) -> io::Result<SocketAddr>;
142
143    /// Gets the value of the IP_TTL option for this socket.
144    /// For more information about this option, see [`tcp_listener_set_ttl`](Self::tcp_listener_set_ttl).
145    fn tcp_listener_ttl(&self, handle: &Handle) -> io::Result<u32>;
146
147    /// Sets the value for the IP_TTL option on this socket.
148    /// This value sets the time-to-live field that is used in every packet sent from this socket.
149    fn tcp_listener_set_ttl(&self, handle: &Handle, ttl: u32) -> io::Result<()>;
150
151    /// Accepts a new incoming connection to this tcp listener.
152    ///
153    /// When a connection is established, the corresponding stream and address will be returned.
154    ///
155    /// Returns [`CancelablePoll::Pending(CancelHandle)`](CancelablePoll::Pending),
156    /// indicating that the current operation could not be completed
157    /// immediately and needs to be retried later.
158    fn tcp_listener_accept(
159        &self,
160        waker: Waker,
161        handle: &Handle,
162    ) -> CancelablePoll<io::Result<(Handle, SocketAddr)>>;
163
164    /// Create a new `TcpStream` and connect to `raddrs`.
165    ///
166    /// The port allocated can be queried via the [`tcp_stream_local_addr`](Self::tcp_stream_local_addr) method.
167    ///
168    /// Returns [`CancelablePoll::Pending(CancelHandle)`](CancelablePoll::Pending),
169    /// indicating that the current operation could not be completed
170    /// immediately and needs to be retried later.
171    fn tcp_stream_connect(
172        &self,
173        waker: Waker,
174        raddrs: &[SocketAddr],
175    ) -> CancelablePoll<io::Result<Handle>>;
176
177    /// Sends data on the socket to the remote address
178    ///
179    /// On success, returns the number of bytes written.
180    fn tcp_stream_write(
181        &self,
182        waker: Waker,
183        socket: &Handle,
184        buf: &[u8],
185    ) -> CancelablePoll<io::Result<usize>>;
186
187    /// Receives data from the socket.
188    ///
189    /// On success, returns the number of bytes read.
190    fn tcp_stream_read(
191        &self,
192        waker: Waker,
193        socket: &Handle,
194        buf: &mut [u8],
195    ) -> CancelablePoll<io::Result<usize>>;
196
197    /// Returns the local [`socket address`](SocketAddr) bound to this tcp stream.
198    fn tcp_stream_local_addr(&self, handle: &Handle) -> io::Result<SocketAddr>;
199
200    /// Returns the remote [`socket address`](SocketAddr) this tcp stream connected.
201    fn tcp_stream_remote_addr(&self, handle: &Handle) -> io::Result<SocketAddr>;
202
203    /// Gets the value of the TCP_NODELAY option on this socket.
204    /// For more information about this option, see [`tcp_stream_set_nodelay`](Self::tcp_stream_set_nodelay).
205    fn tcp_stream_nodelay(&self, handle: &Handle) -> io::Result<bool>;
206
207    /// Sets the value of the TCP_NODELAY option on this socket.
208    ///
209    /// If set, this option disables the Nagle algorithm.
210    /// This means that segments are always sent as soon as possible,
211    /// even if there is only a small amount of data. When not set,
212    /// data is buffered until there is a sufficient amount to send out,
213    /// thereby avoiding the frequent sending of small packets.
214    fn tcp_stream_set_nodelay(&self, handle: &Handle, nodelay: bool) -> io::Result<()>;
215
216    /// Gets the value of the IP_TTL option for this socket.
217    /// For more information about this option, see [`tcp_listener_set_ttl`](Self::tcp_listener_set_ttl).
218    fn tcp_stream_ttl(&self, handle: &Handle) -> io::Result<u32>;
219
220    /// Sets the value for the IP_TTL option on this socket.
221    /// This value sets the time-to-live field that is used in every packet sent from this socket.
222    fn tcp_stream_set_ttl(&self, handle: &Handle, ttl: u32) -> io::Result<()>;
223
224    /// Shuts down the read, write, or both halves of this connection.
225    /// This function will cause all pending and future I/O on the specified
226    /// portions to return immediately with an appropriate value (see the documentation of Shutdown).
227    fn tcp_stream_shutdown(&self, handle: &Handle, how: Shutdown) -> io::Result<()>;
228
229    /// Creates a new UnixListener bound to the specified socket path.
230    #[cfg(unix)]
231    fn unix_listener_bind(
232        &self,
233        waker: Waker,
234        path: &std::path::Path,
235    ) -> CancelablePoll<io::Result<Handle>>;
236
237    /// Accepts a new incoming connection to this listener.
238    /// The call is responsible for ensuring that the listening socket is in non-blocking mode.
239    #[cfg(unix)]
240    fn unix_listener_accept(
241        &self,
242        waker: Waker,
243        handle: &Handle,
244    ) -> CancelablePoll<io::Result<(Handle, std::os::unix::net::SocketAddr)>>;
245
246    /// Returns the local socket address of this listener.
247    #[cfg(unix)]
248    fn unix_listener_local_addr(
249        &self,
250        handle: &Handle,
251    ) -> io::Result<std::os::unix::net::SocketAddr>;
252
253    /// Connects to the unix socket named by address.
254    #[cfg(unix)]
255    fn unix_stream_connect(
256        &self,
257        waker: Waker,
258        path: &std::path::Path,
259    ) -> CancelablePoll<io::Result<Handle>>;
260
261    /// Returns the socket address of the local half of this connection.
262    #[cfg(all(unix, feature = "unix_socket"))]
263    fn unix_stream_local_addr(&self, handle: &Handle)
264        -> io::Result<std::os::unix::net::SocketAddr>;
265
266    /// Returns the socket address of the remote half of this connection.
267    #[cfg(all(unix, feature = "unix_socket"))]
268    fn unix_stream_peer_addr(&self, handle: &Handle) -> io::Result<std::os::unix::net::SocketAddr>;
269
270    /// huts down the read, write, or both halves of this connection.
271    /// This function will cause all pending and future I/O calls on the specified portions
272    /// to immediately return with an appropriate value (see the documentation of [`Shutdown`]).
273    #[cfg(all(unix, feature = "unix_socket"))]
274    fn unix_stream_shutdown(&self, handle: &Handle, how: Shutdown) -> io::Result<()>;
275
276    /// Sends data on the socket to the remote address
277    ///
278    /// On success, returns the number of bytes written.
279    #[cfg(all(unix, feature = "unix_socket"))]
280    fn unix_stream_write(
281        &self,
282        waker: Waker,
283        socket: &Handle,
284        buf: &[u8],
285    ) -> CancelablePoll<io::Result<usize>>;
286
287    /// Receives data from the socket.
288    ///
289    /// On success, returns the number of bytes read.
290    #[cfg(all(unix, feature = "unix_socket"))]
291    fn unix_stream_read(
292        &self,
293        waker: Waker,
294        socket: &Handle,
295        buf: &mut [u8],
296    ) -> CancelablePoll<io::Result<usize>>;
297}
298
299static GLOBAL_NETWORK: OnceLock<Box<dyn Network>> = OnceLock::new();
300
301/// Register provided [`Network`] as global network implementation.
302///
303/// # Panic
304///
305/// Multiple calls to this function are not permitted!!!
306pub fn register_global_network<E: Network + 'static>(executor: E) {
307    if GLOBAL_NETWORK.set(Box::new(executor)).is_err() {
308        panic!("Multiple calls to register_global_network are not permitted!!!");
309    }
310}
311
312/// Get the globally registered instance of [`Network`].
313///
314/// # Panic
315///
316/// You should call [`register_global_network`] first to register implementation,
317/// otherwise this function will cause a panic with `Call register_global_network first`
318pub fn global_network() -> &'static dyn Network {
319    GLOBAL_NETWORK
320        .get()
321        .expect("Call register_global_network first")
322        .as_ref()
323}