about summary refs log tree commit diff
diff options
context:
space:
mode:
authorPatiga <dev@patiga.eu>2022-12-03 12:44:32 +0100
committerPatiga <dev@patiga.eu>2023-08-22 18:19:49 +0200
commitadb22b92dd3674cf9b661504575b53245eec7f65 (patch)
treebbeb93342df4e0ade5e4d87775cdcd83aa8f06b0
parent320b412f9c55bf480d26276ff0ab480e4ecb29c0 (diff)
downloadrust-adb22b92dd3674cf9b661504575b53245eec7f65.tar.gz
rust-adb22b92dd3674cf9b661504575b53245eec7f65.zip
Improve UdpSocket documentation
I tried working with `UdpSocket` and ran into `EINVAL` errors with no
clear indication of what causes the error. Also, it was uncharacteristically
hard to figure this module out, compared to other Rust `std` modules.

1. `send` and `send_to` return a `usize`
This one is just clarity. Usually, returned `usize`s indicate that the
buffer might have only been sent partially. This is not the case with
UDP. Since that `usize` must always be `buffer.len()`, I have documented
that.

2. `bind` limits `connect` and `send_to`
When you bind to a limited address space like localhost, you can only
`connect` to addresses in that same address space. Error kind:
`AddrNotAvailable`.

3. `connect`ing to localhost locks you to localhost
On Linux, if you first `connect` to localhost, subsequent `connect`s to
non-localhost addresses fail. Error kind: `InvalidInput`.

Co-authored-by: Jubilee <46493976+workingjubilee@users.noreply.github.com>
-rw-r--r--library/std/src/net/udp.rs21
1 files changed, 20 insertions, 1 deletions
diff --git a/library/std/src/net/udp.rs b/library/std/src/net/udp.rs
index 5ca4ed832f3..a9049aabd8c 100644
--- a/library/std/src/net/udp.rs
+++ b/library/std/src/net/udp.rs
@@ -99,6 +99,16 @@ impl UdpSocket {
     ///
     /// let socket = UdpSocket::bind("127.0.0.1:0").unwrap();
     /// ```
+    ///
+    /// Note that `bind` declares the scope of your network connection.
+    /// You can only receive datagrams from and send datagrams to
+    /// participants in that view of the network.
+    /// For instance, binding to a loopback address as in the example
+    /// above will prevent you from sending datagrams to another device
+    /// in your local network.
+    ///
+    /// In order to limit your view of the network the least, `bind` to
+    /// [`Ipv4Addr::UNSPECIFIED`] or [`Ipv6Addr::UNSPECIFIED`].
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
         super::each_addr(addr, net_imp::UdpSocket::bind).map(UdpSocket)
@@ -157,7 +167,9 @@ impl UdpSocket {
     }
 
     /// Sends data on the socket to the given address. On success, returns the
-    /// number of bytes written.
+    /// number of bytes written. Note that the operating system may refuse
+    /// buffers larger than 65507. However, partial writes are not possible
+    /// until buffer sizes above `i32::MAX`.
     ///
     /// Address type can be any implementor of [`ToSocketAddrs`] trait. See its
     /// documentation for concrete examples.
@@ -652,12 +664,19 @@ impl UdpSocket {
     /// function of a UDP socket is not a useful thing to do: The OS will be
     /// unable to determine whether something is listening on the remote
     /// address without the application sending data.
+    ///
+    /// If your first `connect` is to a loopback address, subsequent
+    /// `connect`s to non-loopback addresses might fail, depending
+    /// on the platform.
     #[stable(feature = "net2_mutators", since = "1.9.0")]
     pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
         super::each_addr(addr, |addr| self.0.connect(addr))
     }
 
     /// Sends data on the socket to the remote address to which it is connected.
+    /// On success, returns the number of bytes written. Note that the operating
+    /// system may refuse buffers larger than 65507. However, partial writes are
+    /// not possible until buffer sizes above `i32::MAX`.
     ///
     /// [`UdpSocket::connect`] will connect this socket to a remote address. This
     /// method will fail if the socket is not connected.