@@ -1503,6 +1503,148 @@ impl UdpSocket {
15031503 . await
15041504 }
15051505
1506+ /// Receives a single datagram from the connected address without removing it from the queue.
1507+ /// On success, returns the number of bytes read from whence the data came.
1508+ ///
1509+ /// # Notes
1510+ ///
1511+ /// On Windows, if the data is larger than the buffer specified, the buffer
1512+ /// is filled with the first part of the data, and `peek_from` returns the error
1513+ /// `WSAEMSGSIZE(10040)`. The excess data is lost.
1514+ /// Make sure to always use a sufficiently large buffer to hold the
1515+ /// maximum UDP packet size, which can be up to 65536 bytes in size.
1516+ ///
1517+ /// MacOS will return an error if you pass a zero-sized buffer.
1518+ ///
1519+ /// If you're merely interested in learning the sender of the data at the head of the queue,
1520+ /// try [`peek_sender`].
1521+ ///
1522+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1523+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1524+ /// Because UDP is stateless and does not validate the origin of a packet,
1525+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1526+ /// It is important to be aware of this when designing your application-level protocol.
1527+ ///
1528+ /// # Examples
1529+ ///
1530+ /// ```no_run
1531+ /// use tokio::net::UdpSocket;
1532+ /// use std::io;
1533+ ///
1534+ /// #[tokio::main]
1535+ /// async fn main() -> io::Result<()> {
1536+ /// let socket = UdpSocket::bind("127.0.0.1:8080").await?;
1537+ ///
1538+ /// let mut buf = vec![0u8; 32];
1539+ /// let len = socket.peek(&mut buf).await?;
1540+ ///
1541+ /// println!("peeked {:?} bytes", len);
1542+ ///
1543+ /// Ok(())
1544+ /// }
1545+ /// ```
1546+ ///
1547+ /// [`peek_sender`]: method@Self::peek_sender
1548+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
1549+ pub async fn peek ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
1550+ self . io
1551+ . registration ( )
1552+ . async_io ( Interest :: READABLE , || self . io . peek ( buf) )
1553+ . await
1554+ }
1555+
1556+ /// Receives data from the connected address, without removing it from the input queue.
1557+ /// On success, returns the sending address of the datagram.
1558+ ///
1559+ /// # Notes
1560+ ///
1561+ /// Note that on multiple calls to a `poll_*` method in the `recv` direction, only the
1562+ /// `Waker` from the `Context` passed to the most recent call will be scheduled to
1563+ /// receive a wakeup
1564+ ///
1565+ /// On Windows, if the data is larger than the buffer specified, the buffer
1566+ /// is filled with the first part of the data, and peek returns the error
1567+ /// `WSAEMSGSIZE(10040)`. The excess data is lost.
1568+ /// Make sure to always use a sufficiently large buffer to hold the
1569+ /// maximum UDP packet size, which can be up to 65536 bytes in size.
1570+ ///
1571+ /// MacOS will return an error if you pass a zero-sized buffer.
1572+ ///
1573+ /// If you're merely interested in learning the sender of the data at the head of the queue,
1574+ /// try [`poll_peek_sender`].
1575+ ///
1576+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1577+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1578+ /// Because UDP is stateless and does not validate the origin of a packet,
1579+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1580+ /// It is important to be aware of this when designing your application-level protocol.
1581+ ///
1582+ /// # Return value
1583+ ///
1584+ /// The function returns:
1585+ ///
1586+ /// * `Poll::Pending` if the socket is not ready to read
1587+ /// * `Poll::Ready(Ok(()))` reads data into `ReadBuf` if the socket is ready
1588+ /// * `Poll::Ready(Err(e))` if an error is encountered.
1589+ ///
1590+ /// # Errors
1591+ ///
1592+ /// This function may encounter any standard I/O error except `WouldBlock`.
1593+ ///
1594+ /// [`poll_peek_sender`]: method@Self::poll_peek_sender
1595+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
1596+ pub fn poll_peek ( & self , cx : & mut Context < ' _ > , buf : & mut ReadBuf < ' _ > ) -> Poll < io:: Result < ( ) > > {
1597+ #[ allow( clippy:: blocks_in_conditions) ]
1598+ let n = ready ! ( self . io. registration( ) . poll_read_io( cx, || {
1599+ // Safety: will not read the maybe uninitialized bytes.
1600+ let b = unsafe {
1601+ & mut * ( buf. unfilled_mut( ) as * mut [ std:: mem:: MaybeUninit <u8 >] as * mut [ u8 ] )
1602+ } ;
1603+
1604+ self . io. peek( b)
1605+ } ) ) ?;
1606+
1607+ // Safety: We trust `recv` to have filled up `n` bytes in the buffer.
1608+ unsafe {
1609+ buf. assume_init ( n) ;
1610+ }
1611+ buf. advance ( n) ;
1612+ Poll :: Ready ( Ok ( ( ) ) )
1613+ }
1614+
1615+ /// Tries to receive data on the connected address without removing it from the input queue.
1616+ /// On success, returns the number of bytes read.
1617+ ///
1618+ /// When there is no pending data, `Err(io::ErrorKind::WouldBlock)` is
1619+ /// returned. This function is usually paired with `readable()`.
1620+ ///
1621+ /// # Notes
1622+ ///
1623+ /// On Windows, if the data is larger than the buffer specified, the buffer
1624+ /// is filled with the first part of the data, and peek returns the error
1625+ /// `WSAEMSGSIZE(10040)`. The excess data is lost.
1626+ /// Make sure to always use a sufficiently large buffer to hold the
1627+ /// maximum UDP packet size, which can be up to 65536 bytes in size.
1628+ ///
1629+ /// MacOS will return an error if you pass a zero-sized buffer.
1630+ ///
1631+ /// If you're merely interested in learning the sender of the data at the head of the queue,
1632+ /// try [`try_peek_sender`].
1633+ ///
1634+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1635+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1636+ /// Because UDP is stateless and does not validate the origin of a packet,
1637+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1638+ /// It is important to be aware of this when designing your application-level protocol.
1639+ ///
1640+ /// [`try_peek_sender`]: method@Self::try_peek_sender
1641+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
1642+ pub fn try_peek ( & self , buf : & mut [ u8 ] ) -> io:: Result < usize > {
1643+ self . io
1644+ . registration ( )
1645+ . try_io ( Interest :: READABLE , || self . io . peek ( buf) )
1646+ }
1647+
15061648 /// Receives data from the socket, without removing it from the input queue.
15071649 /// On success, returns the number of bytes read and the address from whence
15081650 /// the data came.
0 commit comments