nuuksio 0.0.0

Nuuksio asynchronous runtime
Documentation
const SOCKADDR_IN_LEN: libc::socklen_t = mem::size_of::<libc::sockaddr_in>() as libc::socklen_t;
const SOCKADDR_IN6_LEN: libc::socklen_t = mem::size_of::<libc::sockaddr_in6>() as libc::socklen_t;

fn from_socket_addr(addr: SocketAddr) -> (libc::sockaddr_storage, libc::socklen_t) {
    let mut out = MaybeUninit::<libc::sockaddr_storage>::uninit();
    let len = match addr {
        SocketAddr::V4(addr) => {
            let out = out.as_mut_ptr().cast::<libc::sockaddr_in>();
            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::<libc::sockaddr_in6>();
            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<libc::sockaddr_storage>,
    len: libc::socklen_t,
) -> Option<SocketAddr> {
    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::<libc::sockaddr_in>() };
            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::<libc::sockaddr_in6>() };
            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,
    }
}