@@ -6,6 +6,7 @@ use std::fmt;
66use std:: io;
77use std:: net:: { self , Ipv4Addr , Ipv6Addr , SocketAddr } ;
88use std:: task:: { Context , Poll } ;
9+ use crate :: net:: unix:: SocketAddr ;
910
1011cfg_io_util ! {
1112 use bytes:: BufMut ;
@@ -1331,6 +1332,11 @@ impl UdpSocket {
13311332 /// Make sure to always use a sufficiently large buffer to hold the
13321333 /// maximum UDP packet size, which can be up to 65536 bytes in size.
13331334 ///
1335+ /// MacOS will return an error if you pass a zero-sized buffer.
1336+ ///
1337+ /// If you're merely interested in learning the sender of the data at the head of the queue,
1338+ /// try [`peek_sender`].
1339+ ///
13341340 /// # Examples
13351341 ///
13361342 /// ```no_run
@@ -1349,6 +1355,8 @@ impl UdpSocket {
13491355 /// Ok(())
13501356 /// }
13511357 /// ```
1358+ ///
1359+ /// [`peek_sender`]: method@Self::peek_sender
13521360 pub async fn peek_from ( & self , buf : & mut [ u8 ] ) -> io:: Result < ( usize , SocketAddr ) > {
13531361 self . io
13541362 . registration ( )
@@ -1371,6 +1379,11 @@ impl UdpSocket {
13711379 /// Make sure to always use a sufficiently large buffer to hold the
13721380 /// maximum UDP packet size, which can be up to 65536 bytes in size.
13731381 ///
1382+ /// MacOS will return an error if you pass a zero-sized buffer.
1383+ ///
1384+ /// If you're merely interested in learning the sender of the data at the head of the queue,
1385+ /// try [`poll_peek_sender`].
1386+ ///
13741387 /// # Return value
13751388 ///
13761389 /// The function returns:
@@ -1382,6 +1395,8 @@ impl UdpSocket {
13821395 /// # Errors
13831396 ///
13841397 /// This function may encounter any standard I/O error except `WouldBlock`.
1398+ ///
1399+ /// [`poll_peek_sender`]: method@Self::poll_peek_sender
13851400 pub fn poll_peek_from (
13861401 & self ,
13871402 cx : & mut Context < ' _ > ,
@@ -1404,6 +1419,50 @@ impl UdpSocket {
14041419 Poll :: Ready ( Ok ( addr) )
14051420 }
14061421
1422+ /// Retrieve the sender of the data at the head of the input queue, waiting if empty.
1423+ ///
1424+ /// This is equivalent to calling [`peek_from`] with a zero-sized buffer,
1425+ /// but suppresses the `WSAEMSGSIZE` error on Windows and the "invalid argument" error on macOS.
1426+ ///
1427+ /// [`peek_from`]: method@Self::peek_from
1428+ pub async fn peek_sender ( & self ) -> io:: Result < SocketAddr > {
1429+ self . io
1430+ . registration ( )
1431+ . async_io ( Interest :: READABLE , || self . try_peek_sender ( ) )
1432+ . await
1433+ }
1434+
1435+ /// Retrieve the sender of the data at the head of the input queue,
1436+ /// scheduling a wakeup if empty.
1437+ ///
1438+ /// This is equivalent to calling [`poll_peek_from`] with a zero-sized buffer,
1439+ /// but suppresses the `WSAEMSGSIZE` error on Windows and the "invalid argument" error on macOS.
1440+ ///
1441+ /// # Notes
1442+ ///
1443+ /// Note that on multiple calls to a `poll_*` method in the recv direction, only the
1444+ /// `Waker` from the `Context` passed to the most recent call will be scheduled to
1445+ /// receive a wakeup.
1446+ ///
1447+ /// [`poll_peek_from`]: method@Self::poll_peek_from
1448+ pub fn poll_peek_sender ( & self , cx : & mut Context < ' _ > ) -> Poll < io:: Result < SocketAddr > > {
1449+ self . io
1450+ . registration ( )
1451+ . poll_read_io ( cx, || self . try_peek_sender ( ) )
1452+ }
1453+
1454+ #[ inline]
1455+ fn try_peek_sender ( & self ) -> io:: Result < SocketAddr > {
1456+ self
1457+ . as_socket ( )
1458+ . peek_sender ( ) ?
1459+ // May be `None` if the platform doesn't populate the sender for some reason.
1460+ // In testing, that only occurred on macOS if you pass a zero-sized buffer,
1461+ // but the implementation of `Socket::peek_sender()` covers that.
1462+ . as_socket ( )
1463+ . ok_or_else ( || io:: Error :: new ( io:: ErrorKind :: Other , "sender not available" ) )
1464+ }
1465+
14071466 /// Gets the value of the `SO_BROADCAST` option for this socket.
14081467 ///
14091468 /// For more information about this option, see [`set_broadcast`].
0 commit comments