@@ -1503,6 +1503,148 @@ impl UdpSocket {
1503
1503
. await
1504
1504
}
1505
1505
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
+
1506
1648
/// Receives data from the socket, without removing it from the input queue.
1507
1649
/// On success, returns the number of bytes read and the address from whence
1508
1650
/// the data came.
0 commit comments