|
1 | 1 | use crate::{
|
| 2 | + buf::fixed::FixedBuf, |
2 | 3 | buf::{BoundedBuf, BoundedBufMut},
|
3 | 4 | io::{SharedFd, Socket},
|
4 | 5 | };
|
@@ -96,6 +97,34 @@ impl UdpSocket {
|
96 | 97 | Ok(UdpSocket { inner: socket })
|
97 | 98 | }
|
98 | 99 |
|
| 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 | + |
99 | 128 | /// Creates new `UdpSocket` from a previously bound `std::net::UdpSocket`.
|
100 | 129 | ///
|
101 | 130 | /// This function is intended to be used to wrap a UDP socket from the
|
@@ -206,12 +235,48 @@ impl UdpSocket {
|
206 | 235 | self.inner.read(buf).await
|
207 | 236 | }
|
208 | 237 |
|
| 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 | + |
209 | 256 | /// Write some data to the socket from the buffer, returning the original buffer and
|
210 | 257 | /// quantity of data written.
|
211 | 258 | pub async fn write<T: BoundedBuf>(&self, buf: T) -> crate::BufResult<usize, T> {
|
212 | 259 | self.inner.write(buf).await
|
213 | 260 | }
|
214 | 261 |
|
| 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 | + |
215 | 280 | /// Shuts down the read, write, or both halves of this connection.
|
216 | 281 | ///
|
217 | 282 | /// This function will cause all pending and future I/O on the specified portions to return
|
|
0 commit comments