compio_net/udp.rs
1use std::{
2 future::Future,
3 io,
4 net::{Ipv4Addr, Ipv6Addr, SocketAddr},
5};
6
7use compio_buf::{BufResult, IoBuf, IoBufMut, IoVectoredBuf, IoVectoredBufMut};
8use compio_driver::{
9 BufferRef, impl_raw_fd,
10 op::{RecvFlags, RecvFromMultiResult, RecvMsgMultiResult},
11};
12use compio_io::ancillary::ReturnFlags;
13use futures_util::Stream;
14use socket2::{Protocol, SockAddr, Socket as Socket2, Type};
15
16use crate::{MSG_NOSIGNAL, Socket, ToSocketAddrsAsync};
17
18/// A UDP socket.
19///
20/// UDP is "connectionless", unlike TCP. Meaning, regardless of what address
21/// you've bound to, a `UdpSocket` is free to communicate with many different
22/// remotes. There are basically two main ways to use `UdpSocket`:
23///
24/// * one to many: [`bind`](`UdpSocket::bind`) and use
25/// [`send_to`](`UdpSocket::send_to`) and
26/// [`recv_from`](`UdpSocket::recv_from`) to communicate with many different
27/// addresses
28/// * one to one: [`connect`](`UdpSocket::connect`) and associate with a single
29/// address, using [`send`](`UdpSocket::send`) and [`recv`](`UdpSocket::recv`)
30/// to communicate only with that remote address
31///
32/// # Examples
33/// Bind and connect a pair of sockets and send a packet:
34///
35/// ```
36/// use std::net::SocketAddr;
37///
38/// use compio_net::UdpSocket;
39///
40/// # compio_runtime::Runtime::new().unwrap().block_on(async {
41/// let first_addr: SocketAddr = "127.0.0.1:0".parse().unwrap();
42/// let second_addr: SocketAddr = "127.0.0.1:0".parse().unwrap();
43///
44/// // bind sockets
45/// let mut socket = UdpSocket::bind(first_addr).await.unwrap();
46/// let first_addr = socket.local_addr().unwrap();
47/// let mut other_socket = UdpSocket::bind(second_addr).await.unwrap();
48/// let second_addr = other_socket.local_addr().unwrap();
49///
50/// // connect sockets
51/// socket.connect(second_addr).await.unwrap();
52/// other_socket.connect(first_addr).await.unwrap();
53///
54/// let buf = Vec::with_capacity(12);
55///
56/// // write data
57/// socket.send("Hello world!").await.unwrap();
58///
59/// // read data
60/// let (n_bytes, buf) = other_socket.recv(buf).await.unwrap();
61///
62/// assert_eq!(n_bytes, buf.len());
63/// assert_eq!(buf, b"Hello world!");
64/// # });
65/// ```
66/// Send and receive packets without connecting:
67///
68/// ```
69/// use std::net::SocketAddr;
70///
71/// use compio_net::UdpSocket;
72/// use socket2::SockAddr;
73///
74/// # compio_runtime::Runtime::new().unwrap().block_on(async {
75/// let first_addr: SocketAddr = "127.0.0.1:0".parse().unwrap();
76/// let second_addr: SocketAddr = "127.0.0.1:0".parse().unwrap();
77///
78/// // bind sockets
79/// let mut socket = UdpSocket::bind(first_addr).await.unwrap();
80/// let first_addr = socket.local_addr().unwrap();
81/// let mut other_socket = UdpSocket::bind(second_addr).await.unwrap();
82/// let second_addr = other_socket.local_addr().unwrap();
83///
84/// let buf = Vec::with_capacity(32);
85///
86/// // write data
87/// socket.send_to("hello world", second_addr).await.unwrap();
88///
89/// // read data
90/// let ((n_bytes, addr), buf) = other_socket.recv_from(buf).await.unwrap();
91///
92/// assert_eq!(addr, first_addr);
93/// assert_eq!(n_bytes, buf.len());
94/// assert_eq!(buf, b"hello world");
95/// # });
96/// ```
97#[derive(Debug, Clone)]
98pub struct UdpSocket {
99 inner: Socket,
100}
101
102impl UdpSocket {
103 /// Creates a new UDP socket and attempt to bind it to the addr provided.
104 pub async fn bind(addr: impl ToSocketAddrsAsync) -> io::Result<Self> {
105 super::each_addr(addr, |addr| async move {
106 let addr = SockAddr::from(addr);
107 let socket = Socket::new(addr.domain(), Type::DGRAM, Some(Protocol::UDP)).await?;
108 socket.bind(&addr).await?;
109 Ok(Self { inner: socket })
110 })
111 .await
112 }
113
114 /// Connects this UDP socket to a remote address, allowing the `send` and
115 /// `recv` to be used to send data and also applies filters to only
116 /// receive data from the specified address.
117 ///
118 /// Note that usually, a successful `connect` call does not specify
119 /// that there is a remote server listening on the port, rather, such an
120 /// error would only be detected after the first send.
121 pub async fn connect(&self, addr: impl ToSocketAddrsAsync) -> io::Result<()> {
122 super::each_addr(addr, |addr| async move {
123 self.inner.connect(&SockAddr::from(addr))
124 })
125 .await
126 }
127
128 /// Creates new UdpSocket from a std::net::UdpSocket.
129 pub fn from_std(socket: std::net::UdpSocket) -> io::Result<Self> {
130 Ok(Self {
131 inner: Socket::from_socket2(Socket2::from(socket))?,
132 })
133 }
134
135 /// Close the socket. If the returned future is dropped before polling, the
136 /// socket won't be closed.
137 ///
138 /// See [`TcpStream::close`] for more details.
139 ///
140 /// [`TcpStream::close`]: crate::tcp::TcpStream::close
141 pub fn close(self) -> impl Future<Output = io::Result<()>> {
142 self.inner.close()
143 }
144
145 /// Returns the socket address of the remote peer this socket was connected
146 /// to.
147 ///
148 /// # Examples
149 ///
150 /// ```no_run
151 /// use std::net::{Ipv4Addr, SocketAddr, SocketAddrV4};
152 ///
153 /// use compio_net::UdpSocket;
154 /// use socket2::SockAddr;
155 ///
156 /// # compio_runtime::Runtime::new().unwrap().block_on(async {
157 /// let socket = UdpSocket::bind("127.0.0.1:34254")
158 /// .await
159 /// .expect("couldn't bind to address");
160 /// socket
161 /// .connect("192.168.0.1:41203")
162 /// .await
163 /// .expect("couldn't connect to address");
164 /// assert_eq!(
165 /// socket.peer_addr().unwrap(),
166 /// SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(192, 168, 0, 1), 41203))
167 /// );
168 /// # });
169 /// ```
170 pub fn peer_addr(&self) -> io::Result<SocketAddr> {
171 self.inner
172 .peer_addr()
173 .map(|addr| addr.as_socket().expect("should be SocketAddr"))
174 }
175
176 /// Returns the local address that this socket is bound to.
177 ///
178 /// # Example
179 ///
180 /// ```
181 /// use std::net::SocketAddr;
182 ///
183 /// use compio_net::UdpSocket;
184 /// use socket2::SockAddr;
185 ///
186 /// # compio_runtime::Runtime::new().unwrap().block_on(async {
187 /// let addr: SocketAddr = "127.0.0.1:8080".parse().unwrap();
188 /// let sock = UdpSocket::bind(&addr).await.unwrap();
189 /// // the address the socket is bound to
190 /// let local_addr = sock.local_addr().unwrap();
191 /// assert_eq!(local_addr, addr);
192 /// # });
193 /// ```
194 pub fn local_addr(&self) -> io::Result<SocketAddr> {
195 self.inner
196 .local_addr()
197 .map(|addr| addr.as_socket().expect("should be SocketAddr"))
198 }
199
200 /// Receives a packet of data from the socket into the buffer, returning the
201 /// original buffer and quantity of data received.
202 pub async fn recv<T: IoBufMut>(&self, buffer: T) -> BufResult<usize, T> {
203 self.inner.recv(buffer, RecvFlags::empty()).await
204 }
205
206 /// Receives a packet of data from the socket into the buffer, returning the
207 /// original buffer and quantity of data received.
208 pub async fn recv_vectored<T: IoVectoredBufMut>(&self, buffer: T) -> BufResult<usize, T> {
209 self.inner.recv_vectored(buffer, RecvFlags::empty()).await
210 }
211
212 /// Read some bytes from this source and return a [`BufferRef`].
213 ///
214 /// If `len` == 0, will use buffer pool's inner buffer size as the max len;
215 /// if `len` > 0, `min(len, inner buffer size)` will be the read max len.
216 pub async fn recv_managed(&self, len: usize) -> io::Result<Option<BufferRef>> {
217 self.inner.recv_managed(len, RecvFlags::empty()).await
218 }
219
220 /// Read some bytes from this source and return a stream of [`BufferRef`]s.
221 ///
222 /// If `len` == 0, will use buffer pool's inner buffer size as the max len
223 /// of each buffer; if `len` > 0, `min(len, inner buffer size)` will be
224 /// the read max len of each buffer.
225 pub fn recv_multi(&self, len: usize) -> impl Stream<Item = io::Result<BufferRef>> {
226 self.inner.recv_multi(len, RecvFlags::empty())
227 }
228
229 /// Sends some data to the socket from the buffer, returning the original
230 /// buffer and quantity of data sent.
231 pub async fn send<T: IoBuf>(&self, buffer: T) -> BufResult<usize, T> {
232 self.inner.send(buffer, MSG_NOSIGNAL).await
233 }
234
235 /// Sends some data to the socket from the buffer, returning the original
236 /// buffer and quantity of data sent.
237 pub async fn send_vectored<T: IoVectoredBuf>(&self, buffer: T) -> BufResult<usize, T> {
238 self.inner.send_vectored(buffer, MSG_NOSIGNAL).await
239 }
240
241 /// Receives a single datagram message on the socket. On success, returns
242 /// the number of bytes received and the origin.
243 pub async fn recv_from<T: IoBufMut>(&self, buffer: T) -> BufResult<(usize, SocketAddr), T> {
244 self.inner
245 .recv_from(buffer, RecvFlags::empty())
246 .await
247 .map_res(|(n, addr)| {
248 let addr = addr
249 .expect("should have addr")
250 .as_socket()
251 .expect("should be SocketAddr");
252 (n, addr)
253 })
254 }
255
256 /// Receives a single datagram message on the socket. On success, returns
257 /// the number of bytes received and the origin.
258 pub async fn recv_from_vectored<T: IoVectoredBufMut>(
259 &self,
260 buffer: T,
261 ) -> BufResult<(usize, SocketAddr), T> {
262 self.inner
263 .recv_from_vectored(buffer, RecvFlags::empty())
264 .await
265 .map_res(|(n, addr)| {
266 let addr = addr
267 .expect("should have addr")
268 .as_socket()
269 .expect("should be SocketAddr");
270 (n, addr)
271 })
272 }
273
274 /// Read some bytes from this source and the runtime's buffer pool and
275 /// return a [`BufferRef`] with the sender address.
276 ///
277 /// If `len` == 0, will use buffer pool's inner buffer size as the max len;
278 /// if `len` > 0, `min(len, inner buffer size)` will be the read max len
279 pub async fn recv_from_managed(
280 &self,
281 len: usize,
282 ) -> io::Result<Option<(BufferRef, SocketAddr)>> {
283 let res = self
284 .inner
285 .recv_from_managed(len, RecvFlags::empty())
286 .await?;
287 let ret = match res {
288 Some((buffer, addr)) => {
289 let addr = addr
290 .expect("should have addr")
291 .as_socket()
292 .expect("should be SocketAddr");
293 Some((buffer, addr))
294 }
295 None => None,
296 };
297 Ok(ret)
298 }
299
300 /// Read some bytes from this source and the runtime's buffer pool and
301 /// return a stream of [`RecvFromMultiResult`].
302 pub fn recv_from_multi(&self) -> impl Stream<Item = io::Result<RecvFromMultiResult>> {
303 self.inner.recv_from_multi(RecvFlags::empty())
304 }
305
306 /// Receives a single datagram message and ancillary data on the socket. On
307 /// success, returns the number of bytes received, control length, the
308 /// origin and `recvmsg` flags.
309 pub async fn recv_msg<T: IoBufMut, C: IoBufMut>(
310 &self,
311 buffer: T,
312 control: C,
313 ) -> BufResult<(usize, usize, SocketAddr, ReturnFlags), (T, C)> {
314 self.inner
315 .recv_msg(buffer, control, RecvFlags::empty())
316 .await
317 .map_res(|(n, m, addr, flags)| {
318 let addr = addr
319 .expect("should have addr")
320 .as_socket()
321 .expect("should be SocketAddr");
322 (n, m, addr, flags)
323 })
324 }
325
326 /// Receives a single datagram message and ancillary data on the socket. On
327 /// success, returns the number of bytes received, control length, the
328 /// origin and `recvmsg` flags.
329 pub async fn recv_msg_vectored<T: IoVectoredBufMut, C: IoBufMut>(
330 &self,
331 buffer: T,
332 control: C,
333 ) -> BufResult<(usize, usize, SocketAddr, ReturnFlags), (T, C)> {
334 self.inner
335 .recv_msg_vectored(buffer, control, RecvFlags::empty())
336 .await
337 .map_res(|(n, m, addr, flags)| {
338 let addr = addr
339 .expect("should have addr")
340 .as_socket()
341 .expect("should be SocketAddr");
342 (n, m, addr, flags)
343 })
344 }
345
346 /// Receives a single datagram message on the socket from the runtime's
347 /// buffer pool, together with ancillary data. The ancillary data buffer is
348 /// provided by the caller.
349 ///
350 /// If `len` == 0, will use buffer pool's inner buffer size as the max len;
351 /// if `len` > 0, `min(len, inner buffer size)` will be the read max len
352 pub async fn recv_msg_managed<C: IoBufMut>(
353 &self,
354 len: usize,
355 control: C,
356 ) -> io::Result<Option<(BufferRef, C, SocketAddr, ReturnFlags)>> {
357 let res = self
358 .inner
359 .recv_msg_managed(len, control, RecvFlags::empty())
360 .await?;
361 let ret = match res {
362 Some((buffer, control, addr, flags)) => {
363 let addr = addr
364 .expect("should have addr")
365 .as_socket()
366 .expect("should be SocketAddr");
367 Some((buffer, control, addr, flags))
368 }
369 None => None,
370 };
371 Ok(ret)
372 }
373
374 /// Receives multiple single datagram messages and ancillary data on the
375 /// socket from the runtime's buffer pool.
376 pub fn recv_msg_multi(
377 &self,
378 control_len: usize,
379 ) -> impl Stream<Item = io::Result<RecvMsgMultiResult>> {
380 self.inner.recv_msg_multi(control_len, RecvFlags::empty())
381 }
382
383 /// Sends data on the socket to the given address. On success, returns the
384 /// number of bytes sent.
385 pub async fn send_to<T: IoBuf>(
386 &self,
387 buffer: T,
388 addr: impl ToSocketAddrsAsync,
389 ) -> BufResult<usize, T> {
390 super::first_addr_buf(addr, buffer, |addr, buffer| async move {
391 self.inner
392 .send_to(buffer, &SockAddr::from(addr), MSG_NOSIGNAL)
393 .await
394 })
395 .await
396 }
397
398 /// Sends data on the socket to the given address. On success, returns the
399 /// number of bytes sent.
400 pub async fn send_to_vectored<T: IoVectoredBuf>(
401 &self,
402 buffer: T,
403 addr: impl ToSocketAddrsAsync,
404 ) -> BufResult<usize, T> {
405 super::first_addr_buf(addr, buffer, |addr, buffer| async move {
406 self.inner
407 .send_to_vectored(buffer, &SockAddr::from(addr), MSG_NOSIGNAL)
408 .await
409 })
410 .await
411 }
412
413 /// Sends data on the socket to the given address accompanied by ancillary
414 /// data. On success, returns the number of bytes sent.
415 pub async fn send_msg<T: IoBuf, C: IoBuf>(
416 &self,
417 buffer: T,
418 control: C,
419 addr: impl ToSocketAddrsAsync,
420 ) -> BufResult<usize, (T, C)> {
421 super::first_addr_buf(
422 addr,
423 (buffer, control),
424 |addr, (buffer, control)| async move {
425 self.inner
426 .send_msg(buffer, control, Some(&SockAddr::from(addr)), MSG_NOSIGNAL)
427 .await
428 },
429 )
430 .await
431 }
432
433 /// Sends data on the socket to the given address accompanied by ancillary
434 /// data. On success, returns the number of bytes sent.
435 pub async fn send_msg_vectored<T: IoVectoredBuf, C: IoBuf>(
436 &self,
437 buffer: T,
438 control: C,
439 addr: impl ToSocketAddrsAsync,
440 ) -> BufResult<usize, (T, C)> {
441 super::first_addr_buf(
442 addr,
443 (buffer, control),
444 |addr, (buffer, control)| async move {
445 self.inner
446 .send_msg_vectored(buffer, control, Some(&SockAddr::from(addr)), MSG_NOSIGNAL)
447 .await
448 },
449 )
450 .await
451 }
452
453 /// Sends data on the socket with zero copy.
454 ///
455 /// Returns the result of send and a future that resolves to the
456 /// original buffer when the send is complete.
457 pub async fn send_zerocopy<T: IoBuf>(
458 &self,
459 buf: T,
460 ) -> BufResult<usize, impl Future<Output = T> + use<T>> {
461 self.inner.send_zerocopy(buf, MSG_NOSIGNAL).await
462 }
463
464 /// Sends vectored data on the socket with zero copy.
465 ///
466 /// Returns the result of send and a future that resolves to the
467 /// original buffer when the send is complete.
468 pub async fn send_zerocopy_vectored<T: IoVectoredBuf>(
469 &self,
470 buf: T,
471 ) -> BufResult<usize, impl Future<Output = T> + use<T>> {
472 self.inner.send_zerocopy_vectored(buf, MSG_NOSIGNAL).await
473 }
474
475 /// Sends data on the socket to the given address with zero copy.
476 ///
477 /// Returns the result of send and a future that resolves to the
478 /// original buffer when the send is complete.
479 pub async fn send_to_zerocopy<A: ToSocketAddrsAsync, T: IoBuf>(
480 &self,
481 buffer: T,
482 addr: A,
483 ) -> BufResult<usize, impl Future<Output = T> + use<A, T>> {
484 super::first_addr_buf_zerocopy(addr, buffer, |addr, buffer| async move {
485 self.inner
486 .send_to_zerocopy(buffer, &addr.into(), MSG_NOSIGNAL)
487 .await
488 })
489 .await
490 }
491
492 /// Sends vectored data on the socket to the given address with zero copy.
493 ///
494 /// Returns the result of send and a future that resolves to the
495 /// original buffer when the send is complete.
496 pub async fn send_to_zerocopy_vectored<A: ToSocketAddrsAsync, T: IoVectoredBuf>(
497 &self,
498 buffer: T,
499 addr: A,
500 ) -> BufResult<usize, impl Future<Output = T> + use<A, T>> {
501 super::first_addr_buf_zerocopy(addr, buffer, |addr, buffer| async move {
502 self.inner
503 .send_to_zerocopy_vectored(buffer, &addr.into(), MSG_NOSIGNAL)
504 .await
505 })
506 .await
507 }
508
509 /// Sends data with control message on the socket to the given address with
510 /// zero copy.
511 ///
512 /// Returns the result of send and a future that resolves to the
513 /// original buffer when the send is complete.
514 pub async fn send_msg_zerocopy<A: ToSocketAddrsAsync, T: IoBuf, C: IoBuf>(
515 &self,
516 buffer: T,
517 control: C,
518 addr: A,
519 ) -> BufResult<usize, impl Future<Output = (T, C)> + use<A, T, C>> {
520 super::first_addr_buf_zerocopy(addr, (buffer, control), |addr, (b, c)| async move {
521 self.inner
522 .send_msg_zerocopy(b, c, Some(&addr.into()), MSG_NOSIGNAL)
523 .await
524 })
525 .await
526 }
527
528 /// Sends vectored data with control message on the socket to the given
529 /// address with zero copy.
530 ///
531 /// Returns the result of send and a future that resolves to the
532 /// original buffer when the send is complete.
533 pub async fn send_msg_zerocopy_vectored<A: ToSocketAddrsAsync, T: IoVectoredBuf, C: IoBuf>(
534 &self,
535 buffer: T,
536 control: C,
537 addr: A,
538 ) -> BufResult<usize, impl Future<Output = (T, C)> + use<A, T, C>> {
539 super::first_addr_buf_zerocopy(addr, (buffer, control), |addr, (b, c)| async move {
540 self.inner
541 .send_msg_zerocopy_vectored(b, c, Some(&addr.into()), MSG_NOSIGNAL)
542 .await
543 })
544 .await
545 }
546
547 /// Gets the value of the `SO_BROADCAST` option for this socket.
548 ///
549 /// For more information about this option, see [`set_broadcast`].
550 ///
551 /// [`set_broadcast`]: method@Self::set_broadcast
552 pub fn broadcast(&self) -> io::Result<bool> {
553 self.inner.socket.broadcast()
554 }
555
556 /// Sets the value of the `SO_BROADCAST` option for this socket.
557 ///
558 /// When enabled, this socket is allowed to send packets to a broadcast
559 /// address.
560 pub fn set_broadcast(&self, on: bool) -> io::Result<()> {
561 self.inner.socket.set_broadcast(on)
562 }
563
564 /// Gets the value of the `IP_MULTICAST_LOOP` option for this socket.
565 ///
566 /// For more information about this option, see [`set_multicast_loop_v4`].
567 ///
568 /// [`set_multicast_loop_v4`]: method@Self::set_multicast_loop_v4
569 pub fn multicast_loop_v4(&self) -> io::Result<bool> {
570 self.inner.socket.multicast_loop_v4()
571 }
572
573 /// Sets the value of the `IP_MULTICAST_LOOP` option for this socket.
574 ///
575 /// If enabled, multicast packets will be looped back to the local socket.
576 ///
577 /// # Note
578 ///
579 /// This may not have any effect on IPv6 sockets.
580 pub fn set_multicast_loop_v4(&self, on: bool) -> io::Result<()> {
581 self.inner.socket.set_multicast_loop_v4(on)
582 }
583
584 /// Gets the value of the `IP_MULTICAST_TTL` option for this socket.
585 ///
586 /// For more information about this option, see [`set_multicast_ttl_v4`].
587 ///
588 /// [`set_multicast_ttl_v4`]: method@Self::set_multicast_ttl_v4
589 pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
590 self.inner.socket.multicast_ttl_v4()
591 }
592
593 /// Sets the value of the `IP_MULTICAST_TTL` option for this socket.
594 ///
595 /// Indicates the time-to-live value of outgoing multicast packets for
596 /// this socket. The default value is 1 which means that multicast packets
597 /// don't leave the local network unless explicitly requested.
598 ///
599 /// # Note
600 ///
601 /// This may not have any effect on IPv6 sockets.
602 pub fn set_multicast_ttl_v4(&self, ttl: u32) -> io::Result<()> {
603 self.inner.socket.set_multicast_ttl_v4(ttl)
604 }
605
606 /// Gets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
607 ///
608 /// For more information about this option, see [`set_multicast_loop_v6`].
609 ///
610 /// [`set_multicast_loop_v6`]: method@Self::set_multicast_loop_v6
611 pub fn multicast_loop_v6(&self) -> io::Result<bool> {
612 self.inner.socket.multicast_loop_v6()
613 }
614
615 /// Sets the value of the `IPV6_MULTICAST_LOOP` option for this socket.
616 ///
617 /// Controls whether this socket sees the multicast packets it sends itself.
618 ///
619 /// # Note
620 ///
621 /// This may not have any effect on IPv4 sockets.
622 pub fn set_multicast_loop_v6(&self, on: bool) -> io::Result<()> {
623 self.inner.socket.set_multicast_loop_v6(on)
624 }
625
626 /// Gets the value of the `IPV6_TCLASS` option for this socket.
627 ///
628 /// For more information about this option, see [`set_tclass_v6`].
629 ///
630 /// [`set_tclass_v6`]: Self::set_tclass_v6
631 #[cfg(any(
632 target_os = "android",
633 target_os = "dragonfly",
634 target_os = "freebsd",
635 target_os = "fuchsia",
636 target_os = "linux",
637 target_os = "macos",
638 target_os = "netbsd",
639 target_os = "openbsd",
640 target_os = "cygwin",
641 ))]
642 pub fn tclass_v6(&self) -> io::Result<u32> {
643 self.inner.socket.tclass_v6()
644 }
645
646 /// Sets the value for the `IPV6_TCLASS` option on this socket.
647 ///
648 /// Specifies the traffic class field that is used in every packet
649 /// sent from this socket.
650 ///
651 /// # Note
652 ///
653 /// This may not have any effect on IPv4 sockets.
654 #[cfg(any(
655 target_os = "android",
656 target_os = "dragonfly",
657 target_os = "freebsd",
658 target_os = "fuchsia",
659 target_os = "linux",
660 target_os = "macos",
661 target_os = "netbsd",
662 target_os = "openbsd",
663 target_os = "cygwin",
664 ))]
665 pub fn set_tclass_v6(&self, tclass: u32) -> io::Result<()> {
666 self.inner.socket.set_tclass_v6(tclass)
667 }
668
669 /// Gets the value of the `IP_TTL` option for this socket.
670 ///
671 /// For more information about this option, see [`set_ttl_v4`].
672 ///
673 /// [`set_ttl_v4`]: method@Self::set_ttl_v4
674 pub fn ttl_v4(&self) -> io::Result<u32> {
675 self.inner.socket.ttl_v4()
676 }
677
678 /// Sets the value for the `IP_TTL` option on this socket.
679 ///
680 /// This value sets the time-to-live field that is used in every packet sent
681 /// from this socket.
682 pub fn set_ttl_v4(&self, ttl: u32) -> io::Result<()> {
683 self.inner.socket.set_ttl_v4(ttl)
684 }
685
686 /// Gets the value of the `IP_TOS` option for this socket.
687 ///
688 /// For more information about this option, see [`set_tos_v4`].
689 ///
690 /// [`set_tos_v4`]: Self::set_tos_v4
691 // https://docs.rs/socket2/0.6.1/src/socket2/socket.rs.html#1585
692 #[cfg(not(any(
693 target_os = "fuchsia",
694 target_os = "redox",
695 target_os = "solaris",
696 target_os = "illumos",
697 target_os = "haiku"
698 )))]
699 pub fn tos_v4(&self) -> io::Result<u32> {
700 self.inner.socket.tos_v4()
701 }
702
703 /// Sets the value for the `IP_TOS` option on this socket.
704 ///
705 /// This value sets the type-of-service field that is used in every packet
706 /// sent from this socket.
707 ///
708 /// # Note
709 ///
710 /// - This may not have any effect on IPv6 sockets.
711 #[cfg(not(any(
712 target_os = "fuchsia",
713 target_os = "redox",
714 target_os = "solaris",
715 target_os = "illumos",
716 target_os = "haiku"
717 )))]
718 pub fn set_tos_v4(&self, tos: u32) -> io::Result<()> {
719 self.inner.socket.set_tos_v4(tos)
720 }
721
722 /// Gets the value for the `SO_BINDTODEVICE` option on this socket
723 ///
724 /// This value gets the socket-bound device's interface name.
725 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux",))]
726 pub fn device(&self) -> io::Result<Option<Vec<u8>>> {
727 self.inner.socket.device()
728 }
729
730 /// Sets the value for the `SO_BINDTODEVICE` option on this socket
731 ///
732 /// If a socket is bound to an interface, only packets received from that
733 /// particular interface are processed by the socket. Note that this only
734 /// works for some socket types, particularly `AF_INET` sockets.
735 ///
736 /// If `interface` is `None` or an empty string it removes the binding.
737 #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
738 pub fn bind_device(&self, interface: Option<&[u8]>) -> io::Result<()> {
739 self.inner.socket.bind_device(interface)
740 }
741
742 /// Executes an operation of the `IP_ADD_MEMBERSHIP` type.
743 ///
744 /// This function specifies a new multicast group for this socket to join.
745 /// The address must be a valid multicast address, and `interface` is the
746 /// address of the local interface with which the system should join the
747 /// multicast group. If it's equal to `INADDR_ANY` then an appropriate
748 /// interface is chosen by the system.
749 pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
750 self.inner.socket.join_multicast_v4(multiaddr, interface)
751 }
752
753 /// Executes an operation of the `IPV6_ADD_MEMBERSHIP` type.
754 ///
755 /// This function specifies a new multicast group for this socket to join.
756 /// The address must be a valid multicast address, and `interface` is the
757 /// index of the interface to join/leave (or 0 to indicate any interface).
758 pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
759 self.inner.socket.join_multicast_v6(multiaddr, interface)
760 }
761
762 /// Executes an operation of the `IP_DROP_MEMBERSHIP` type.
763 ///
764 /// For more information about this option, see [`join_multicast_v4`].
765 ///
766 /// [`join_multicast_v4`]: method@Self::join_multicast_v4
767 pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
768 self.inner.socket.leave_multicast_v4(multiaddr, interface)
769 }
770
771 /// Executes an operation of the `IPV6_DROP_MEMBERSHIP` type.
772 ///
773 /// For more information about this option, see [`join_multicast_v6`].
774 ///
775 /// [`join_multicast_v6`]: method@Self::join_multicast_v6
776 pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
777 self.inner.socket.leave_multicast_v6(multiaddr, interface)
778 }
779
780 /// Returns the value of the `SO_ERROR` option.
781 pub fn take_error(&self) -> io::Result<Option<io::Error>> {
782 self.inner.socket.take_error()
783 }
784
785 /// Gets a socket option.
786 ///
787 /// # Safety
788 ///
789 /// The caller must ensure `T` is the correct type for `level` and `name`.
790 pub unsafe fn get_socket_option<T: Copy>(&self, level: i32, name: i32) -> io::Result<T> {
791 unsafe { self.inner.get_socket_option(level, name) }
792 }
793
794 /// Sets a socket option.
795 ///
796 /// # Safety
797 ///
798 /// The caller must ensure `T` is the correct type for `level` and `name`.
799 pub unsafe fn set_socket_option<T: Copy>(
800 &self,
801 level: i32,
802 name: i32,
803 value: &T,
804 ) -> io::Result<()> {
805 unsafe { self.inner.set_socket_option(level, name, value) }
806 }
807}
808
809impl_raw_fd!(UdpSocket, socket2::Socket, inner, socket);