Skip to main content

std/sys/net/connection/socket/
mod.rs

1#[cfg(test)]
2#[cfg(not(target_os = "l4re"))]
3mod tests;
4
5use crate::ffi::{c_int, c_void};
6use crate::io::{self, BorrowedCursor, ErrorKind, IoSlice, IoSliceMut};
7use crate::mem::MaybeUninit;
8use crate::net::{
9    Ipv4Addr, Ipv6Addr, Shutdown, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs,
10};
11use crate::sys::helpers::run_with_cstr;
12use crate::sys::net::connection::each_addr;
13use crate::sys::{AsInner, FromInner};
14use crate::time::Duration;
15use crate::{cmp, fmt, mem, ptr};
16
17cfg_select! {
18    target_os = "hermit" => {
19        mod hermit;
20        pub use hermit::*;
21    }
22    target_os = "solid_asp3" => {
23        mod solid;
24        pub use solid::*;
25    }
26    any(target_family = "unix", target_os = "wasi") => {
27        mod unix;
28        pub use unix::*;
29    }
30    target_os = "windows" => {
31        mod windows;
32        pub use windows::*;
33    }
34    _ => {}
35}
36
37use netc as c;
38
39// Similarly to reads (see READ_LIMIT), the `send` syscall on most platforms
40// takes a `size_t` length, but returns an `ssize_t` of bytes written. So the
41// actual maximum number of bytes we can send in one call is SSIZE_MAX.
42//
43// On Apple targets however, apparently the 64-bit libc is either buggy or
44// intentionally showing odd behavior by rejecting send calls with a size
45// larger than INT_MAX. So cap the send size to INT_MAX.
46//
47// Meanwhile on QNX, reads/writes/sends larger than INT_MAX return the wrong
48// number of bytes written (eg, writing 2^31 bytes returns (2^64 - 2^31) instead
49// of the correct byte count).
50//
51// On Windows, the relevant syscall takes an `i32` (unlike for read/write!),
52// so we need to clamp to i32::MAX.
53const MAX_SEND_LEN: usize =
54    cfg_select! {
55        any(target_vendor = "apple", target_os = "nto", target_os = "qnx") => c_int::MAX as usize,
56        target_os = "windows" => i32::MAX as usize,
57        _ => libc::ssize_t::MAX as usize,
58    };
59
60cfg_select! {
61    any(
62        target_os = "dragonfly",
63        target_os = "freebsd",
64        target_os = "openbsd",
65        target_os = "netbsd",
66        target_os = "illumos",
67        target_os = "solaris",
68        target_os = "haiku",
69        target_os = "l4re",
70        target_os = "nto",
71        target_os = "qnx",
72        target_os = "nuttx",
73        target_vendor = "apple",
74    ) => {
75        use c::{IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP, IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP};
76    }
77    _ => {
78        use c::{IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP};
79    }
80}
81
82cfg_select! {
83    any(
84        target_os = "linux",
85        target_os = "android",
86        target_os = "hurd",
87        target_os = "dragonfly",
88        target_os = "freebsd",
89        target_os = "openbsd",
90        target_os = "netbsd",
91        target_os = "solaris",
92        target_os = "illumos",
93        target_os = "haiku",
94        target_os = "nto",
95        target_os = "qnx",
96        target_os = "cygwin",
97    ) => {
98        use libc::MSG_NOSIGNAL;
99    }
100    _ => {
101        const MSG_NOSIGNAL: c_int = 0x0;
102    }
103}
104
105cfg_select! {
106    any(
107        target_os = "dragonfly",
108        target_os = "freebsd",
109        target_os = "openbsd",
110        target_os = "netbsd",
111        target_os = "solaris",
112        target_os = "illumos",
113        target_os = "nto",
114        target_os = "qnx",
115    ) => {
116        use crate::ffi::c_uchar;
117        type IpV4MultiCastType = c_uchar;
118    }
119    _ => {
120        type IpV4MultiCastType = c_int;
121    }
122}
123
124////////////////////////////////////////////////////////////////////////////////
125// address conversions
126////////////////////////////////////////////////////////////////////////////////
127
128fn ip_v4_addr_to_c(addr: &Ipv4Addr) -> c::in_addr {
129    // `s_addr` is stored as BE on all machines and the array is in BE order.
130    // So the native endian conversion method is used so that it's never swapped.
131    c::in_addr { s_addr: u32::from_ne_bytes(addr.octets()) }
132}
133
134fn ip_v6_addr_to_c(addr: &Ipv6Addr) -> c::in6_addr {
135    c::in6_addr { s6_addr: addr.octets() }
136}
137
138fn ip_v4_addr_from_c(addr: c::in_addr) -> Ipv4Addr {
139    Ipv4Addr::from(addr.s_addr.to_ne_bytes())
140}
141
142fn ip_v6_addr_from_c(addr: c::in6_addr) -> Ipv6Addr {
143    Ipv6Addr::from(addr.s6_addr)
144}
145
146fn socket_addr_v4_to_c(addr: &SocketAddrV4) -> c::sockaddr_in {
147    c::sockaddr_in {
148        sin_family: c::AF_INET as c::sa_family_t,
149        sin_port: addr.port().to_be(),
150        sin_addr: ip_v4_addr_to_c(addr.ip()),
151        ..unsafe { mem::zeroed() }
152    }
153}
154
155fn socket_addr_v6_to_c(addr: &SocketAddrV6) -> c::sockaddr_in6 {
156    c::sockaddr_in6 {
157        sin6_family: c::AF_INET6 as c::sa_family_t,
158        sin6_port: addr.port().to_be(),
159        sin6_addr: ip_v6_addr_to_c(addr.ip()),
160        sin6_flowinfo: addr.flowinfo(),
161        sin6_scope_id: addr.scope_id(),
162        ..unsafe { mem::zeroed() }
163    }
164}
165
166fn socket_addr_v4_from_c(addr: c::sockaddr_in) -> SocketAddrV4 {
167    SocketAddrV4::new(ip_v4_addr_from_c(addr.sin_addr), u16::from_be(addr.sin_port))
168}
169
170fn socket_addr_v6_from_c(addr: c::sockaddr_in6) -> SocketAddrV6 {
171    SocketAddrV6::new(
172        ip_v6_addr_from_c(addr.sin6_addr),
173        u16::from_be(addr.sin6_port),
174        addr.sin6_flowinfo,
175        addr.sin6_scope_id,
176    )
177}
178
179/// A type with the same memory layout as `c::sockaddr`. Used in converting Rust level
180/// SocketAddr* types into their system representation. The benefit of this specific
181/// type over using `c::sockaddr_storage` is that this type is exactly as large as it
182/// needs to be and not a lot larger. And it can be initialized more cleanly from Rust.
183#[repr(C)]
184union SocketAddrCRepr {
185    v4: c::sockaddr_in,
186    v6: c::sockaddr_in6,
187}
188
189impl SocketAddrCRepr {
190    fn as_ptr(&self) -> *const c::sockaddr {
191        self as *const _ as *const c::sockaddr
192    }
193}
194
195fn socket_addr_to_c(addr: &SocketAddr) -> (SocketAddrCRepr, c::socklen_t) {
196    match addr {
197        SocketAddr::V4(a) => {
198            let sockaddr = SocketAddrCRepr { v4: socket_addr_v4_to_c(a) };
199            (sockaddr, size_of::<c::sockaddr_in>() as c::socklen_t)
200        }
201        SocketAddr::V6(a) => {
202            let sockaddr = SocketAddrCRepr { v6: socket_addr_v6_to_c(a) };
203            (sockaddr, size_of::<c::sockaddr_in6>() as c::socklen_t)
204        }
205    }
206}
207
208fn addr_family(addr: &SocketAddr) -> c_int {
209    match addr {
210        SocketAddr::V4(..) => c::AF_INET,
211        SocketAddr::V6(..) => c::AF_INET6,
212    }
213}
214
215/// Converts the C socket address stored in `storage` to a Rust `SocketAddr`.
216///
217/// # Safety
218/// * `storage` must contain a valid C socket address whose length is no larger
219///   than `len`.
220unsafe fn socket_addr_from_c(
221    storage: *const c::sockaddr_storage,
222    len: usize,
223) -> io::Result<SocketAddr> {
224    match (*storage).ss_family as c_int {
225        c::AF_INET => {
226            if !(len >= size_of::<c::sockaddr_in>()) {
    ::core::panicking::panic("assertion failed: len >= size_of::<c::sockaddr_in>()")
};assert!(len >= size_of::<c::sockaddr_in>());
227            Ok(SocketAddr::V4(socket_addr_v4_from_c(unsafe {
228                *(storage as *const _ as *const c::sockaddr_in)
229            })))
230        }
231        c::AF_INET6 => {
232            if !(len >= size_of::<c::sockaddr_in6>()) {
    ::core::panicking::panic("assertion failed: len >= size_of::<c::sockaddr_in6>()")
};assert!(len >= size_of::<c::sockaddr_in6>());
233            Ok(SocketAddr::V6(socket_addr_v6_from_c(unsafe {
234                *(storage as *const _ as *const c::sockaddr_in6)
235            })))
236        }
237        _ => Err(::core::hint::must_use(::core::io::Error::from_static_message(const {
                &::core::io::SimpleMessage {
                        kind: ErrorKind::InvalidInput,
                        message: "invalid argument",
                    }
            }))io::const_error!(ErrorKind::InvalidInput, "invalid argument")),
238    }
239}
240
241////////////////////////////////////////////////////////////////////////////////
242// sockaddr and misc bindings
243////////////////////////////////////////////////////////////////////////////////
244
245/// Sets the value of a socket option.
246///
247/// # Safety
248/// `T` must be the type associated with the given socket option.
249pub unsafe fn setsockopt<T>(
250    sock: &Socket,
251    level: c_int,
252    option_name: c_int,
253    option_value: T,
254) -> io::Result<()> {
255    let option_len = size_of::<T>() as c::socklen_t;
256    // SAFETY:
257    // * `sock` is opened for the duration of this call, as `sock` owns the socket.
258    // * the pointer to `option_value` is readable at a size of `size_of::<T>`
259    //   bytes
260    // * the value of `option_value` has a valid type for the given socket option
261    //   (guaranteed by caller).
262    cvt(unsafe {
263        c::setsockopt(
264            sock.as_raw(),
265            level,
266            option_name,
267            (&raw const option_value) as *const _,
268            option_len,
269        )
270    })?;
271    Ok(())
272}
273
274/// Gets the value of a socket option.
275///
276/// # Safety
277/// `T` must be the type associated with the given socket option.
278pub unsafe fn getsockopt<T: Copy>(
279    sock: &Socket,
280    level: c_int,
281    option_name: c_int,
282) -> io::Result<T> {
283    let mut option_value = MaybeUninit::<T>::zeroed();
284    let mut option_len = size_of::<T>() as c::socklen_t;
285
286    // SAFETY:
287    // * `sock` is opened for the duration of this call, as `sock` owns the socket.
288    // * the pointer to `option_value` is writable and the stack allocation has
289    //   space for `size_of::<T>` bytes.
290    cvt(unsafe {
291        c::getsockopt(
292            sock.as_raw(),
293            level,
294            option_name,
295            option_value.as_mut_ptr().cast(),
296            &mut option_len,
297        )
298    })?;
299
300    // SAFETY: the `getsockopt` call succeeded and the caller guarantees that
301    //         `T` is the type of this option, thus `option_value` must have
302    //         been initialized by the system.
303    Ok(unsafe { option_value.assume_init() })
304}
305
306/// Wraps a call to a platform function that returns a socket address.
307///
308/// # Safety
309/// * if `f` returns a success (i.e. `cvt` returns `Ok` when called on the
310///   return value), the buffer provided to `f` must have been initialized
311///   with a valid C socket address, the length of which must be written
312///   to the second argument.
313unsafe fn sockname<F>(f: F) -> io::Result<SocketAddr>
314where
315    F: FnOnce(*mut c::sockaddr, *mut c::socklen_t) -> c_int,
316{
317    let mut storage = MaybeUninit::<c::sockaddr_storage>::zeroed();
318    let mut len = size_of::<c::sockaddr_storage>() as c::socklen_t;
319    cvt(f(storage.as_mut_ptr().cast(), &mut len))?;
320    // SAFETY:
321    // The caller guarantees that the storage has been successfully initialized
322    // and its size written to `len` if `f` returns a success.
323    unsafe { socket_addr_from_c(storage.as_ptr(), len as usize) }
324}
325
326#[cfg(target_os = "android")]
327fn to_ipv6mr_interface(value: u32) -> c_int {
328    value as c_int
329}
330
331#[cfg(not(target_os = "android"))]
332fn to_ipv6mr_interface(value: u32) -> crate::ffi::c_uint {
333    value as crate::ffi::c_uint
334}
335
336////////////////////////////////////////////////////////////////////////////////
337// lookup_host
338////////////////////////////////////////////////////////////////////////////////
339
340pub struct LookupHost {
341    original: *mut c::addrinfo,
342    cur: *mut c::addrinfo,
343    port: u16,
344}
345
346impl Iterator for LookupHost {
347    type Item = SocketAddr;
348    fn next(&mut self) -> Option<SocketAddr> {
349        loop {
350            unsafe {
351                let cur = self.cur.as_ref()?;
352                self.cur = cur.ai_next;
353                match socket_addr_from_c(cur.ai_addr.cast(), cur.ai_addrlen as usize) {
354                    Ok(mut addr) => {
355                        addr.set_port(self.port);
356                        return Some(addr);
357                    }
358                    Err(_) => continue,
359                }
360            }
361        }
362    }
363}
364
365unsafe impl Sync for LookupHost {}
366unsafe impl Send for LookupHost {}
367
368impl Drop for LookupHost {
369    fn drop(&mut self) {
370        unsafe { c::freeaddrinfo(self.original) }
371    }
372}
373
374pub fn lookup_host(host: &str, port: u16) -> io::Result<LookupHost> {
375    init();
376    run_with_cstr(host.as_bytes(), &|c_host| {
377        let mut hints: c::addrinfo = unsafe { mem::zeroed() };
378        hints.ai_socktype = c::SOCK_STREAM;
379        let mut res = ptr::null_mut();
380        unsafe {
381            cvt_gai(c::getaddrinfo(c_host.as_ptr(), ptr::null(), &hints, &mut res))
382                .map(|_| LookupHost { original: res, cur: res, port })
383        }
384    })
385}
386
387////////////////////////////////////////////////////////////////////////////////
388// TCP streams
389////////////////////////////////////////////////////////////////////////////////
390
391pub struct TcpStream {
392    inner: Socket,
393}
394
395impl TcpStream {
396    pub fn connect<A: ToSocketAddrs>(addr: A) -> io::Result<TcpStream> {
397        init();
398        return each_addr(addr, inner);
399
400        fn inner(addr: &SocketAddr) -> io::Result<TcpStream> {
401            let sock = Socket::new(addr_family(addr), c::SOCK_STREAM)?;
402            sock.connect(addr)?;
403            Ok(TcpStream { inner: sock })
404        }
405    }
406
407    pub fn connect_timeout(addr: &SocketAddr, timeout: Duration) -> io::Result<TcpStream> {
408        init();
409
410        let sock = Socket::new(addr_family(addr), c::SOCK_STREAM)?;
411        sock.connect_timeout(addr, timeout)?;
412        Ok(TcpStream { inner: sock })
413    }
414
415    #[inline]
416    pub fn socket(&self) -> &Socket {
417        &self.inner
418    }
419
420    pub fn into_socket(self) -> Socket {
421        self.inner
422    }
423
424    pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
425        self.inner.set_timeout(dur, c::SO_RCVTIMEO)
426    }
427
428    pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
429        self.inner.set_timeout(dur, c::SO_SNDTIMEO)
430    }
431
432    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
433        self.inner.timeout(c::SO_RCVTIMEO)
434    }
435
436    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
437        self.inner.timeout(c::SO_SNDTIMEO)
438    }
439
440    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
441        self.inner.peek(buf)
442    }
443
444    pub fn read(&self, buf: &mut [u8]) -> io::Result<usize> {
445        self.inner.read(buf)
446    }
447
448    pub fn read_buf(&self, buf: BorrowedCursor<'_, u8>) -> io::Result<()> {
449        self.inner.read_buf(buf)
450    }
451
452    pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
453        self.inner.read_vectored(bufs)
454    }
455
456    #[inline]
457    pub fn is_read_vectored(&self) -> bool {
458        self.inner.is_read_vectored()
459    }
460
461    pub fn write(&self, buf: &[u8]) -> io::Result<usize> {
462        let len = cmp::min(buf.len(), MAX_SEND_LEN) as wrlen_t;
463        let ret = cvt(unsafe {
464            c::send(self.inner.as_raw(), buf.as_ptr() as *const c_void, len, MSG_NOSIGNAL)
465        })?;
466        Ok(ret as usize)
467    }
468
469    pub fn write_vectored(&self, bufs: &[IoSlice<'_>]) -> io::Result<usize> {
470        self.inner.write_vectored(bufs)
471    }
472
473    #[inline]
474    pub fn is_write_vectored(&self) -> bool {
475        self.inner.is_write_vectored()
476    }
477
478    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
479        unsafe { sockname(|buf, len| c::getpeername(self.inner.as_raw(), buf, len)) }
480    }
481
482    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
483        unsafe { sockname(|buf, len| c::getsockname(self.inner.as_raw(), buf, len)) }
484    }
485
486    pub fn shutdown(&self, how: Shutdown) -> io::Result<()> {
487        self.inner.shutdown(how)
488    }
489
490    pub fn duplicate(&self) -> io::Result<TcpStream> {
491        self.inner.duplicate().map(|s| TcpStream { inner: s })
492    }
493
494    pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
495        self.inner.set_linger(linger)
496    }
497
498    pub fn linger(&self) -> io::Result<Option<Duration>> {
499        self.inner.linger()
500    }
501
502    pub fn set_keepalive(&self, keepalive: bool) -> io::Result<()> {
503        self.inner.set_keepalive(keepalive)
504    }
505
506    pub fn keepalive(&self) -> io::Result<bool> {
507        self.inner.keepalive()
508    }
509
510    pub fn set_nodelay(&self, nodelay: bool) -> io::Result<()> {
511        self.inner.set_nodelay(nodelay)
512    }
513
514    pub fn nodelay(&self) -> io::Result<bool> {
515        self.inner.nodelay()
516    }
517
518    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
519        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int) }
520    }
521
522    pub fn ttl(&self) -> io::Result<u32> {
523        let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)? };
524        Ok(raw as u32)
525    }
526
527    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
528        self.inner.take_error()
529    }
530
531    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
532        self.inner.set_nonblocking(nonblocking)
533    }
534}
535
536impl AsInner<Socket> for TcpStream {
537    #[inline]
538    fn as_inner(&self) -> &Socket {
539        &self.inner
540    }
541}
542
543impl FromInner<Socket> for TcpStream {
544    fn from_inner(socket: Socket) -> TcpStream {
545        TcpStream { inner: socket }
546    }
547}
548
549impl fmt::Debug for TcpStream {
550    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
551        let mut res = f.debug_struct("TcpStream");
552
553        if let Ok(addr) = self.socket_addr() {
554            res.field("addr", &addr);
555        }
556
557        if let Ok(peer) = self.peer_addr() {
558            res.field("peer", &peer);
559        }
560
561        let name = if falsecfg!(windows) { "socket" } else { "fd" };
562        res.field(name, &self.inner.as_raw()).finish()
563    }
564}
565
566////////////////////////////////////////////////////////////////////////////////
567// TCP listeners
568////////////////////////////////////////////////////////////////////////////////
569
570pub struct TcpListener {
571    inner: Socket,
572}
573
574impl TcpListener {
575    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<TcpListener> {
576        init();
577        return each_addr(addr, inner);
578
579        fn inner(addr: &SocketAddr) -> io::Result<TcpListener> {
580            let sock = Socket::new(addr_family(addr), c::SOCK_STREAM)?;
581
582            // On platforms with Berkeley-derived sockets, this allows to quickly
583            // rebind a socket, without needing to wait for the OS to clean up the
584            // previous one.
585            //
586            // On Windows, this allows rebinding sockets which are actively in use,
587            // which allows “socket hijacking”, so we explicitly don't set it here.
588            // https://docs.microsoft.com/en-us/windows/win32/winsock/using-so-reuseaddr-and-so-exclusiveaddruse
589            #[cfg(not(windows))]
590            unsafe {
591                setsockopt(&sock, c::SOL_SOCKET, c::SO_REUSEADDR, 1 as c_int)?
592            };
593
594            // Bind our new socket
595            let (addr, len) = socket_addr_to_c(addr);
596            cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
597
598            let backlog = if falsecfg!(target_os = "horizon") {
599                // The 3DS doesn't support a big connection backlog. Sometimes
600                // it allows up to about 37, but other times it doesn't even
601                // accept 32. There may be a global limitation causing this.
602                20
603            } else if falsecfg!(target_os = "haiku") {
604                // Haiku does not support a queue length > 32
605                // https://github.com/haiku/haiku/blob/979a0bc487864675517fb2fab28f87dc8bf43041/headers/posix/sys/socket.h#L81
606                32
607            } else {
608                // The default for all other platforms
609                128
610            };
611
612            // Start listening
613            cvt(unsafe { c::listen(sock.as_raw(), backlog) })?;
614            Ok(TcpListener { inner: sock })
615        }
616    }
617
618    #[inline]
619    pub fn socket(&self) -> &Socket {
620        &self.inner
621    }
622
623    pub fn into_socket(self) -> Socket {
624        self.inner
625    }
626
627    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
628        unsafe { sockname(|buf, len| c::getsockname(self.inner.as_raw(), buf, len)) }
629    }
630
631    pub fn accept(&self) -> io::Result<(TcpStream, SocketAddr)> {
632        // The `accept` function will fill in the storage with the address,
633        // so we don't need to zero it here.
634        // reference: https://linux.die.net/man/2/accept4
635        let mut storage = MaybeUninit::<c::sockaddr_storage>::uninit();
636        let mut len = size_of::<c::sockaddr_storage>() as c::socklen_t;
637        let sock = self.inner.accept(storage.as_mut_ptr() as *mut _, &mut len)?;
638        let addr = unsafe { socket_addr_from_c(storage.as_ptr(), len as usize)? };
639        Ok((TcpStream { inner: sock }, addr))
640    }
641
642    pub fn duplicate(&self) -> io::Result<TcpListener> {
643        self.inner.duplicate().map(|s| TcpListener { inner: s })
644    }
645
646    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
647        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int) }
648    }
649
650    pub fn ttl(&self) -> io::Result<u32> {
651        let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)? };
652        Ok(raw as u32)
653    }
654
655    pub fn set_only_v6(&self, only_v6: bool) -> io::Result<()> {
656        unsafe { setsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY, only_v6 as c_int) }
657    }
658
659    pub fn only_v6(&self) -> io::Result<bool> {
660        let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_V6ONLY)? };
661        Ok(raw != 0)
662    }
663
664    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
665        self.inner.take_error()
666    }
667
668    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
669        self.inner.set_nonblocking(nonblocking)
670    }
671}
672
673impl FromInner<Socket> for TcpListener {
674    fn from_inner(socket: Socket) -> TcpListener {
675        TcpListener { inner: socket }
676    }
677}
678
679impl fmt::Debug for TcpListener {
680    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
681        let mut res = f.debug_struct("TcpListener");
682
683        if let Ok(addr) = self.socket_addr() {
684            res.field("addr", &addr);
685        }
686
687        let name = if falsecfg!(windows) { "socket" } else { "fd" };
688        res.field(name, &self.inner.as_raw()).finish()
689    }
690}
691
692////////////////////////////////////////////////////////////////////////////////
693// UDP
694////////////////////////////////////////////////////////////////////////////////
695
696pub struct UdpSocket {
697    inner: Socket,
698}
699
700impl UdpSocket {
701    pub fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<UdpSocket> {
702        init();
703        return each_addr(addr, inner);
704
705        fn inner(addr: &SocketAddr) -> io::Result<UdpSocket> {
706            let sock = Socket::new(addr_family(addr), c::SOCK_DGRAM)?;
707            let (addr, len) = socket_addr_to_c(addr);
708            cvt(unsafe { c::bind(sock.as_raw(), addr.as_ptr(), len as _) })?;
709            Ok(UdpSocket { inner: sock })
710        }
711    }
712
713    #[inline]
714    pub fn socket(&self) -> &Socket {
715        &self.inner
716    }
717
718    pub fn into_socket(self) -> Socket {
719        self.inner
720    }
721
722    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
723        unsafe { sockname(|buf, len| c::getpeername(self.inner.as_raw(), buf, len)) }
724    }
725
726    pub fn socket_addr(&self) -> io::Result<SocketAddr> {
727        unsafe { sockname(|buf, len| c::getsockname(self.inner.as_raw(), buf, len)) }
728    }
729
730    pub fn recv_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
731        self.inner.recv_from(buf)
732    }
733
734    pub fn peek_from(&self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr)> {
735        self.inner.peek_from(buf)
736    }
737
738    pub fn send_to(&self, buf: &[u8], dst: &SocketAddr) -> io::Result<usize> {
739        if buf.len() > MAX_SEND_LEN {
740            return Err(io::Error::from_raw_os_error(c::EMSGSIZE));
741        }
742        let (dst, dstlen) = socket_addr_to_c(dst);
743        let ret = cvt(unsafe {
744            c::sendto(
745                self.inner.as_raw(),
746                buf.as_ptr() as *const c_void,
747                buf.len() as wrlen_t,
748                MSG_NOSIGNAL,
749                dst.as_ptr(),
750                dstlen,
751            )
752        })?;
753        Ok(ret as usize)
754    }
755
756    pub fn duplicate(&self) -> io::Result<UdpSocket> {
757        self.inner.duplicate().map(|s| UdpSocket { inner: s })
758    }
759
760    pub fn set_read_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
761        self.inner.set_timeout(dur, c::SO_RCVTIMEO)
762    }
763
764    pub fn set_write_timeout(&self, dur: Option<Duration>) -> io::Result<()> {
765        self.inner.set_timeout(dur, c::SO_SNDTIMEO)
766    }
767
768    pub fn read_timeout(&self) -> io::Result<Option<Duration>> {
769        self.inner.timeout(c::SO_RCVTIMEO)
770    }
771
772    pub fn write_timeout(&self) -> io::Result<Option<Duration>> {
773        self.inner.timeout(c::SO_SNDTIMEO)
774    }
775
776    pub fn set_broadcast(&self, broadcast: bool) -> io::Result<()> {
777        unsafe { setsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST, broadcast as c_int) }
778    }
779
780    pub fn broadcast(&self) -> io::Result<bool> {
781        let raw: c_int = unsafe { getsockopt(&self.inner, c::SOL_SOCKET, c::SO_BROADCAST)? };
782        Ok(raw != 0)
783    }
784
785    pub fn set_multicast_loop_v4(&self, multicast_loop_v4: bool) -> io::Result<()> {
786        unsafe {
787            setsockopt(
788                &self.inner,
789                c::IPPROTO_IP,
790                c::IP_MULTICAST_LOOP,
791                multicast_loop_v4 as IpV4MultiCastType,
792            )
793        }
794    }
795
796    pub fn multicast_loop_v4(&self) -> io::Result<bool> {
797        let raw: IpV4MultiCastType =
798            unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_LOOP)? };
799        Ok(raw != 0)
800    }
801
802    pub fn set_multicast_ttl_v4(&self, multicast_ttl_v4: u32) -> io::Result<()> {
803        let ttl: u8 = multicast_ttl_v4
804            .try_into()
805            .map_err(|_| io::Error::from(io::ErrorKind::InvalidInput))?;
806        unsafe {
807            setsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL, ttl as IpV4MultiCastType)
808        }
809    }
810
811    pub fn multicast_ttl_v4(&self) -> io::Result<u32> {
812        let raw: IpV4MultiCastType =
813            unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_MULTICAST_TTL)? };
814        Ok(raw as u32)
815    }
816
817    pub fn set_multicast_loop_v6(&self, multicast_loop_v6: bool) -> io::Result<()> {
818        unsafe {
819            setsockopt(
820                &self.inner,
821                c::IPPROTO_IPV6,
822                c::IPV6_MULTICAST_LOOP,
823                multicast_loop_v6 as c_int,
824            )
825        }
826    }
827
828    pub fn multicast_loop_v6(&self) -> io::Result<bool> {
829        let raw: c_int =
830            unsafe { getsockopt(&self.inner, c::IPPROTO_IPV6, c::IPV6_MULTICAST_LOOP)? };
831        Ok(raw != 0)
832    }
833
834    pub fn join_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
835        let mreq = c::ip_mreq {
836            imr_multiaddr: ip_v4_addr_to_c(multiaddr),
837            imr_interface: ip_v4_addr_to_c(interface),
838        };
839        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_ADD_MEMBERSHIP, mreq) }
840    }
841
842    pub fn join_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
843        let mreq = c::ipv6_mreq {
844            ipv6mr_multiaddr: ip_v6_addr_to_c(multiaddr),
845            ipv6mr_interface: to_ipv6mr_interface(interface),
846        };
847        unsafe { setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_ADD_MEMBERSHIP, mreq) }
848    }
849
850    pub fn leave_multicast_v4(&self, multiaddr: &Ipv4Addr, interface: &Ipv4Addr) -> io::Result<()> {
851        let mreq = c::ip_mreq {
852            imr_multiaddr: ip_v4_addr_to_c(multiaddr),
853            imr_interface: ip_v4_addr_to_c(interface),
854        };
855        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_DROP_MEMBERSHIP, mreq) }
856    }
857
858    pub fn leave_multicast_v6(&self, multiaddr: &Ipv6Addr, interface: u32) -> io::Result<()> {
859        let mreq = c::ipv6_mreq {
860            ipv6mr_multiaddr: ip_v6_addr_to_c(multiaddr),
861            ipv6mr_interface: to_ipv6mr_interface(interface),
862        };
863        unsafe { setsockopt(&self.inner, c::IPPROTO_IPV6, IPV6_DROP_MEMBERSHIP, mreq) }
864    }
865
866    pub fn set_ttl(&self, ttl: u32) -> io::Result<()> {
867        unsafe { setsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL, ttl as c_int) }
868    }
869
870    pub fn ttl(&self) -> io::Result<u32> {
871        let raw: c_int = unsafe { getsockopt(&self.inner, c::IPPROTO_IP, c::IP_TTL)? };
872        Ok(raw as u32)
873    }
874
875    pub fn take_error(&self) -> io::Result<Option<io::Error>> {
876        self.inner.take_error()
877    }
878
879    pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> {
880        self.inner.set_nonblocking(nonblocking)
881    }
882
883    pub fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
884        self.inner.read(buf)
885    }
886
887    pub fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
888        self.inner.peek(buf)
889    }
890
891    pub fn send(&self, buf: &[u8]) -> io::Result<usize> {
892        if buf.len() > MAX_SEND_LEN {
893            return Err(io::Error::from_raw_os_error(c::EMSGSIZE));
894        }
895        let ret = cvt(unsafe {
896            c::send(
897                self.inner.as_raw(),
898                buf.as_ptr() as *const c_void,
899                buf.len() as wrlen_t,
900                MSG_NOSIGNAL,
901            )
902        })?;
903        Ok(ret as usize)
904    }
905
906    pub fn connect<A: ToSocketAddrs>(&self, addr: A) -> io::Result<()> {
907        return each_addr(addr, |addr| inner(self, addr));
908
909        fn inner(this: &UdpSocket, addr: &SocketAddr) -> io::Result<()> {
910            let (addr, len) = socket_addr_to_c(addr);
911            cvt_r(|| unsafe { c::connect(this.inner.as_raw(), addr.as_ptr(), len) }).map(drop)
912        }
913    }
914}
915
916impl FromInner<Socket> for UdpSocket {
917    fn from_inner(socket: Socket) -> UdpSocket {
918        UdpSocket { inner: socket }
919    }
920}
921
922impl fmt::Debug for UdpSocket {
923    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
924        let mut res = f.debug_struct("UdpSocket");
925
926        if let Ok(addr) = self.socket_addr() {
927            res.field("addr", &addr);
928        }
929
930        let name = if falsecfg!(windows) { "socket" } else { "fd" };
931        res.field(name, &self.inner.as_raw()).finish()
932    }
933}