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}