axstd/net/udp.rs
1use super::{SocketAddr, ToSocketAddrs};
2use crate::io;
3
4use arceos_api::net::{self as api, AxUdpSocketHandle};
5
6/// A UDP socket.
7pub struct UdpSocket(AxUdpSocketHandle);
8
9impl UdpSocket {
10 /// Creates a UDP socket from the given address.
11 ///
12 /// The address type can be any implementor of [`ToSocketAddrs`] trait. See
13 /// its documentation for concrete examples.
14 ///
15 /// If `addr` yields multiple addresses, `bind` will be attempted with
16 /// each of the addresses until one succeeds and returns the socket. If none
17 /// of the addresses succeed in creating a socket, the error returned from
18 /// the last attempt (the last address) is returned.
19 pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
20 super::each_addr(addr, |addr: io::Result<&SocketAddr>| {
21 let addr = addr?;
22 let socket = api::ax_udp_socket();
23 api::ax_udp_bind(&socket, *addr)?;
24 Ok(UdpSocket(socket))
25 })
26 }
27
28 /// Returns the socket address that this socket was created from.
29 pub fn local_addr(&self) -> io::Result<SocketAddr> {
30 api::ax_udp_socket_addr(&self.0)
31 }
32
33 /// Returns the socket address of the remote peer this socket was connected to.
34 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
35 api::ax_udp_peer_addr(&self.0)
36 }
37
38 /// Receives a single datagram message on the socket. On success, returns
39 /// the number of bytes read and the origin.
40 pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
41 api::ax_udp_recv_from(&self.0, buf)
42 }
43
44 /// Receives a single datagram message on the socket, without removing it from
45 /// the queue. On success, returns the number of bytes read and the origin.
46 pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
47 api::ax_udp_peek_from(&self.0, buf)
48 }
49
50 /// Sends data on the socket to the given address. On success, returns the
51 /// number of bytes written.
52 ///
53 /// Address type can be any implementor of [`ToSocketAddrs`] trait. See its
54 /// documentation for concrete examples.
55 ///
56 /// It is possible for `addr` to yield multiple addresses, but `send_to`
57 /// will only send data to the first address yielded by `addr`.
58 pub fn send_to<A: ToSocketAddrs>(&self, buf: &[u8], addr: A) -> io::Result<usize> {
59 match addr.to_socket_addrs()?.next() {
60 Some(addr) => api::ax_udp_send_to(&self.0, buf, addr),
61 None => axerrno::ax_err!(InvalidInput, "no addresses to send data to"),
62 }
63 }
64
65 /// Connects this UDP socket to a remote address, allowing the `send` and
66 /// `recv` syscalls to be used to send data and also applies filters to only
67 /// receive data from the specified address.
68 ///
69 /// If `addr` yields multiple addresses, `connect` will be attempted with
70 /// each of the addresses until the underlying OS function returns no
71 /// error. Note that usually, a successful `connect` call does not specify
72 /// that there is a remote server listening on the port, rather, such an
73 /// error would only be detected after the first send. If the OS returns an
74 /// error for each of the specified addresses, the error returned from the
75 /// last connection attempt (the last address) is returned.
76 pub fn connect(&self, addr: SocketAddr) -> io::Result<()> {
77 super::each_addr(addr, |addr: io::Result<&SocketAddr>| {
78 let addr = addr?;
79 api::ax_udp_connect(&self.0, *addr)
80 })
81 }
82
83 /// Sends data on the socket to the remote address to which it is connected.
84 ///
85 /// [`UdpSocket::connect`] will connect this socket to a remote address. This
86 /// method will fail if the socket is not connected.
87 pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
88 api::ax_udp_send(&self.0, buf)
89 }
90
91 /// Receives a single datagram message on the socket from the remote address to
92 /// which it is connected. On success, returns the number of bytes read.
93 pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
94 api::ax_udp_recv(&self.0, buf)
95 }
96}