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}