Skip to content

Commit 002c94f

Browse files
authored
net: UDP socket gets local_addr, read_fixed and write_fixed (#189)
The type UdpSocket gets methods local_addr, read_fixed and write_fixed. local_addr is useful when binding the socket to 127.0.0.1:0 to be able to report what port the OS assigned. The read_fixed and write_fixed are useful, like read and write, when the UDP socket has been connected to an address.
1 parent 4b92cdb commit 002c94f

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

src/net/udp.rs

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use crate::{
2+
buf::fixed::FixedBuf,
23
buf::{BoundedBuf, BoundedBufMut},
34
io::{SharedFd, Socket},
45
};
@@ -96,6 +97,34 @@ impl UdpSocket {
9697
Ok(UdpSocket { inner: socket })
9798
}
9899

100+
/// Returns the local address that this UDP socket is bound to.
101+
///
102+
/// This can be useful, for example, when binding to port 0 to
103+
/// figure out which port was actually bound.
104+
///
105+
/// # Examples
106+
///
107+
/// ```
108+
/// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
109+
/// use tokio_uring::net::UdpSocket;
110+
///
111+
/// tokio_uring::start(async {
112+
/// let socket = UdpSocket::bind("127.0.0.1:8080".parse().unwrap()).await.unwrap();
113+
/// let addr = socket.local_addr().expect("Couldn't get local address");
114+
/// assert_eq!(addr, SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), 8080)));
115+
/// });
116+
/// ```
117+
pub fn local_addr(&self) -> io::Result<SocketAddr> {
118+
let fd = self.inner.as_raw_fd();
119+
// SAFETY: Our fd is the handle the kernel has given us for a UdpSocket.
120+
// Create a std::net::UdpSocket long enough to call its local_addr method
121+
// and then forget it so the socket is not closed here.
122+
let s = unsafe { std::net::UdpSocket::from_raw_fd(fd) };
123+
let local_addr = s.local_addr();
124+
std::mem::forget(s);
125+
local_addr
126+
}
127+
99128
/// Creates new `UdpSocket` from a previously bound `std::net::UdpSocket`.
100129
///
101130
/// This function is intended to be used to wrap a UDP socket from the
@@ -206,12 +235,48 @@ impl UdpSocket {
206235
self.inner.read(buf).await
207236
}
208237

238+
/// Like [`read`], but using a pre-mapped buffer
239+
/// registered with [`FixedBufRegistry`].
240+
///
241+
/// [`read`]: Self::read
242+
/// [`FixedBufRegistry`]: crate::buf::fixed::FixedBufRegistry
243+
///
244+
/// # Errors
245+
///
246+
/// In addition to errors that can be reported by `read`,
247+
/// this operation fails if the buffer is not registered in the
248+
/// current `tokio-uring` runtime.
249+
pub async fn read_fixed<T>(&self, buf: T) -> crate::BufResult<usize, T>
250+
where
251+
T: BoundedBufMut<BufMut = FixedBuf>,
252+
{
253+
self.inner.read_fixed(buf).await
254+
}
255+
209256
/// Write some data to the socket from the buffer, returning the original buffer and
210257
/// quantity of data written.
211258
pub async fn write<T: BoundedBuf>(&self, buf: T) -> crate::BufResult<usize, T> {
212259
self.inner.write(buf).await
213260
}
214261

262+
/// Like [`write`], but using a pre-mapped buffer
263+
/// registered with [`FixedBufRegistry`].
264+
///
265+
/// [`write`]: Self::write
266+
/// [`FixedBufRegistry`]: crate::buf::fixed::FixedBufRegistry
267+
///
268+
/// # Errors
269+
///
270+
/// In addition to errors that can be reported by `write`,
271+
/// this operation fails if the buffer is not registered in the
272+
/// current `tokio-uring` runtime.
273+
pub async fn write_fixed<T>(&self, buf: T) -> crate::BufResult<usize, T>
274+
where
275+
T: BoundedBuf<Buf = FixedBuf>,
276+
{
277+
self.inner.write_fixed(buf).await
278+
}
279+
215280
/// Shuts down the read, write, or both halves of this connection.
216281
///
217282
/// This function will cause all pending and future I/O on the specified portions to return

0 commit comments

Comments
 (0)