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