@@ -954,6 +954,15 @@ impl UdpSocket {
954954 /// When there is no pending data, `Err(io::ErrorKind::WouldBlock)` is
955955 /// returned. This function is usually paired with `readable()`.
956956 ///
957+ /// # Notes
958+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
959+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
960+ /// Because UDP is stateless and does not validate the origin of a packet,
961+ /// the attacker does not need to be able to intercept traffic in order to interfere.
962+ /// It is important to be aware of this when designing your application-level protocol.
963+ ///
964+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
965+ ///
957966 /// # Examples
958967 ///
959968 /// ```no_run
@@ -1177,6 +1186,15 @@ impl UdpSocket {
11771186 /// Ok(())
11781187 /// }
11791188 /// ```
1189+ ///
1190+ /// # Notes
1191+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1192+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1193+ /// Because UDP is stateless and does not validate the origin of a packet,
1194+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1195+ /// It is important to be aware of this when designing your application-level protocol.
1196+ ///
1197+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
11801198 pub async fn recv_from ( & self , buf : & mut [ u8 ] ) -> io:: Result < ( usize , SocketAddr ) > {
11811199 self . io
11821200 . registration ( )
@@ -1201,6 +1219,15 @@ impl UdpSocket {
12011219 /// # Errors
12021220 ///
12031221 /// This function may encounter any standard I/O error except `WouldBlock`.
1222+ ///
1223+ /// # Notes
1224+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1225+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1226+ /// Because UDP is stateless and does not validate the origin of a packet,
1227+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1228+ /// It is important to be aware of this when designing your application-level protocol.
1229+ ///
1230+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
12041231 pub fn poll_recv_from (
12051232 & self ,
12061233 cx : & mut Context < ' _ > ,
@@ -1233,6 +1260,16 @@ impl UdpSocket {
12331260 /// When there is no pending data, `Err(io::ErrorKind::WouldBlock)` is
12341261 /// returned. This function is usually paired with `readable()`.
12351262 ///
1263+ /// # Notes
1264+ ///
1265+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1266+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1267+ /// Because UDP is stateless and does not validate the origin of a packet,
1268+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1269+ /// It is important to be aware of this when designing your application-level protocol.
1270+ ///
1271+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
1272+ ///
12361273 /// # Examples
12371274 ///
12381275 /// ```no_run
@@ -1367,6 +1404,17 @@ impl UdpSocket {
13671404 /// Make sure to always use a sufficiently large buffer to hold the
13681405 /// maximum UDP packet size, which can be up to 65536 bytes in size.
13691406 ///
1407+ /// MacOS will return an error if you pass a zero-sized buffer.
1408+ ///
1409+ /// If you're merely interested in learning the sender of the data at the head of the queue,
1410+ /// try [`peek_sender`].
1411+ ///
1412+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1413+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1414+ /// Because UDP is stateless and does not validate the origin of a packet,
1415+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1416+ /// It is important to be aware of this when designing your application-level protocol.
1417+ ///
13701418 /// # Examples
13711419 ///
13721420 /// ```no_run
@@ -1385,6 +1433,9 @@ impl UdpSocket {
13851433 /// Ok(())
13861434 /// }
13871435 /// ```
1436+ ///
1437+ /// [`peek_sender`]: method@Self::peek_sender
1438+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
13881439 pub async fn peek_from ( & self , buf : & mut [ u8 ] ) -> io:: Result < ( usize , SocketAddr ) > {
13891440 self . io
13901441 . registration ( )
@@ -1393,7 +1444,7 @@ impl UdpSocket {
13931444 }
13941445
13951446 /// Receives data from the socket, without removing it from the input queue.
1396- /// On success, returns the number of bytes read .
1447+ /// On success, returns the sending address of the datagram .
13971448 ///
13981449 /// # Notes
13991450 ///
@@ -1407,6 +1458,17 @@ impl UdpSocket {
14071458 /// Make sure to always use a sufficiently large buffer to hold the
14081459 /// maximum UDP packet size, which can be up to 65536 bytes in size.
14091460 ///
1461+ /// MacOS will return an error if you pass a zero-sized buffer.
1462+ ///
1463+ /// If you're merely interested in learning the sender of the data at the head of the queue,
1464+ /// try [`poll_peek_sender`].
1465+ ///
1466+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1467+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1468+ /// Because UDP is stateless and does not validate the origin of a packet,
1469+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1470+ /// It is important to be aware of this when designing your application-level protocol.
1471+ ///
14101472 /// # Return value
14111473 ///
14121474 /// The function returns:
@@ -1418,6 +1480,9 @@ impl UdpSocket {
14181480 /// # Errors
14191481 ///
14201482 /// This function may encounter any standard I/O error except `WouldBlock`.
1483+ ///
1484+ /// [`poll_peek_sender`]: method@Self::poll_peek_sender
1485+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
14211486 pub fn poll_peek_from (
14221487 & self ,
14231488 cx : & mut Context < ' _ > ,
@@ -1440,6 +1505,117 @@ impl UdpSocket {
14401505 Poll :: Ready ( Ok ( addr) )
14411506 }
14421507
1508+ /// Tries to receive data on the socket without removing it from the input queue.
1509+ /// On success, returns the number of bytes read and the sending address of the
1510+ /// datagram.
1511+ ///
1512+ /// When there is no pending data, `Err(io::ErrorKind::WouldBlock)` is
1513+ /// returned. This function is usually paired with `readable()`.
1514+ ///
1515+ /// # Notes
1516+ ///
1517+ /// On Windows, if the data is larger than the buffer specified, the buffer
1518+ /// is filled with the first part of the data, and peek returns the error
1519+ /// WSAEMSGSIZE(10040). The excess data is lost.
1520+ /// Make sure to always use a sufficiently large buffer to hold the
1521+ /// maximum UDP packet size, which can be up to 65536 bytes in size.
1522+ ///
1523+ /// MacOS will return an error if you pass a zero-sized buffer.
1524+ ///
1525+ /// If you're merely interested in learning the sender of the data at the head of the queue,
1526+ /// try [`try_peek_sender`].
1527+ ///
1528+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1529+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1530+ /// Because UDP is stateless and does not validate the origin of a packet,
1531+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1532+ /// It is important to be aware of this when designing your application-level protocol.
1533+ ///
1534+ /// [`try_peek_sender`]: method@Self::try_peek_sender
1535+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
1536+ pub fn try_peek_from ( & self , buf : & mut [ u8 ] ) -> io:: Result < ( usize , SocketAddr ) > {
1537+ self . io
1538+ . registration ( )
1539+ . try_io ( Interest :: READABLE , || self . io . peek_from ( buf) )
1540+ }
1541+
1542+ /// Retrieve the sender of the data at the head of the input queue, waiting if empty.
1543+ ///
1544+ /// This is equivalent to calling [`peek_from`] with a zero-sized buffer,
1545+ /// but suppresses the `WSAEMSGSIZE` error on Windows and the "invalid argument" error on macOS.
1546+ ///
1547+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1548+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1549+ /// Because UDP is stateless and does not validate the origin of a packet,
1550+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1551+ /// It is important to be aware of this when designing your application-level protocol.
1552+ ///
1553+ /// [`peek_from`]: method@Self::peek_from
1554+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
1555+ pub async fn peek_sender ( & self ) -> io:: Result < SocketAddr > {
1556+ self . io
1557+ . registration ( )
1558+ . async_io ( Interest :: READABLE , || self . peek_sender_inner ( ) )
1559+ . await
1560+ }
1561+
1562+ /// Retrieve the sender of the data at the head of the input queue,
1563+ /// scheduling a wakeup if empty.
1564+ ///
1565+ /// This is equivalent to calling [`poll_peek_from`] with a zero-sized buffer,
1566+ /// but suppresses the `WSAEMSGSIZE` error on Windows and the "invalid argument" error on macOS.
1567+ ///
1568+ /// # Notes
1569+ ///
1570+ /// Note that on multiple calls to a `poll_*` method in the recv direction, only the
1571+ /// `Waker` from the `Context` passed to the most recent call will be scheduled to
1572+ /// receive a wakeup.
1573+ ///
1574+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1575+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1576+ /// Because UDP is stateless and does not validate the origin of a packet,
1577+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1578+ /// It is important to be aware of this when designing your application-level protocol.
1579+ ///
1580+ /// [`poll_peek_from`]: method@Self::poll_peek_from
1581+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
1582+ pub fn poll_peek_sender ( & self , cx : & mut Context < ' _ > ) -> Poll < io:: Result < SocketAddr > > {
1583+ self . io
1584+ . registration ( )
1585+ . poll_read_io ( cx, || self . peek_sender_inner ( ) )
1586+ }
1587+
1588+ /// Try to retrieve the sender of the data at the head of the input queue.
1589+ ///
1590+ /// When there is no pending data, `Err(io::ErrorKind::WouldBlock)` is
1591+ /// returned. This function is usually paired with `readable()`.
1592+ ///
1593+ /// Note that the socket address **cannot** be implicitly trusted, because it is relatively
1594+ /// trivial to send a UDP datagram with a spoofed origin in a [packet injection attack].
1595+ /// Because UDP is stateless and does not validate the origin of a packet,
1596+ /// the attacker does not need to be able to intercept traffic in order to interfere.
1597+ /// It is important to be aware of this when designing your application-level protocol.
1598+ ///
1599+ /// [packet injection attack]: https://en.wikipedia.org/wiki/Packet_injection
1600+ pub fn try_peek_sender ( & self ) -> io:: Result < SocketAddr > {
1601+ self . io
1602+ . registration ( )
1603+ . try_io ( Interest :: READABLE , || self . peek_sender_inner ( ) )
1604+ }
1605+
1606+ #[ inline]
1607+ fn peek_sender_inner ( & self ) -> io:: Result < SocketAddr > {
1608+ self . io . try_io ( || {
1609+ self . as_socket ( )
1610+ . peek_sender ( ) ?
1611+ // May be `None` if the platform doesn't populate the sender for some reason.
1612+ // In testing, that only occurred on macOS if you pass a zero-sized buffer,
1613+ // but the implementation of `Socket::peek_sender()` covers that.
1614+ . as_socket ( )
1615+ . ok_or_else ( || io:: Error :: new ( io:: ErrorKind :: Other , "sender not available" ) )
1616+ } )
1617+ }
1618+
14431619 /// Gets the value of the `SO_BROADCAST` option for this socket.
14441620 ///
14451621 /// For more information about this option, see [`set_broadcast`].
0 commit comments