const SOCKADDR_IN_LEN: libc::socklen_t = mem::size_of::() as libc::socklen_t; const SOCKADDR_IN6_LEN: libc::socklen_t = mem::size_of::() as libc::socklen_t; fn from_socket_addr(addr: SocketAddr) -> (libc::sockaddr_storage, libc::socklen_t) { let mut out = MaybeUninit::::uninit(); let len = match addr { SocketAddr::V4(addr) => { let out = out.as_mut_ptr().cast::(); unsafe { out.write(libc::sockaddr_in { sin_family: libc::AF_INET as u16, sin_port: addr.port().to_be(), sin_addr: libc::in_addr { s_addr: u32::from_ne_bytes(addr.ip().octets()), }, sin_zero: [0; 8], }); } SOCKADDR_IN_LEN } SocketAddr::V6(addr) => { let out = out.as_mut_ptr().cast::(); unsafe { out.write(libc::sockaddr_in6 { sin6_family: libc::AF_INET6 as u16, sin6_port: addr.port().to_be(), sin6_flowinfo: addr.flowinfo(), sin6_addr: libc::in6_addr { s6_addr: addr.ip().octets(), }, sin6_scope_id: addr.scope_id(), }); } SOCKADDR_IN6_LEN } }; let addr = unsafe { out.assume_init() }; (addr, len) } fn to_socket_addr( mut addr: MaybeUninit, len: libc::socklen_t, ) -> Option { match len { SOCKADDR_IN_LEN => { // Safety: `SOCKADDR_IN_LEN` bytes are initialized // and `libc::sockaddr_in` is `SOCKADDR_IN_LEN` bytes long let addr = unsafe { *addr.as_mut_ptr().cast::() }; if addr.sin_family as i32 == libc::AF_INET { let ip = Ipv4Addr::from(u32::from_be(addr.sin_addr.s_addr)); let port = u16::from_be(addr.sin_port); let addr = SocketAddrV4::new(ip, port); Some(SocketAddr::V4(addr)) } else { None } } SOCKADDR_IN6_LEN => { // Safety: `SOCKADDR_IN6_LEN` bytes are initialized // and `libc::sockaddr_in6` is `SOCKADDR_IN6_LEN` bytes long let addr = unsafe { *addr.as_mut_ptr().cast::() }; if addr.sin6_family as i32 == libc::AF_INET6 { let ip = Ipv6Addr::from(addr.sin6_addr.s6_addr); let port = u16::from_be(addr.sin6_port); let flowinfo = addr.sin6_flowinfo; let scope_id = addr.sin6_scope_id; let addr = SocketAddrV6::new(ip, port, flowinfo, scope_id); Some(SocketAddr::V6(addr)) } else { None } } _ => None, } }