socket9 0.1.0-alpha.1

Extended untilities for the networking/unix sockets and raw network sockets
Documentation

use std::{mem::MaybeUninit, net::{Ipv4Addr, Ipv6Addr}};

use crate::
{
    LocalFrom, OptRMarker, OptWMarker, SockOptMarker
};


use super::*;

    pub(crate) 
    fn getsockopt<VAL, FD>(fd: &FD) -> io::Result<VAL> 
    where 
        VAL: SockOptMarker + OptRMarker, FD: AsFd
    {
        let mut optval: MaybeUninit<VAL::InputType> = MaybeUninit::zeroed();
        let mut len = size_of::<VAL::InputType>() as libc::socklen_t;

        let res = 
            unsafe
            {
                libc::getsockopt(fd.as_fd().as_raw_fd(),VAL::SO_LEVEL,VAL::SO_OPTNAME,
                    optval.as_mut_ptr().cast(),&mut len,
                )
            };

        // more likely it will not fail
        if res == 0
        {
            return Ok(VAL::from( unsafe { optval.assume_init() }));
        }
        else
        {
            return Err(std::io::Error::last_os_error());
        }
    }

    pub(crate) 
    fn setsockopt<VAL, FD>(fd: &FD, val: VAL) -> io::Result<()>
    where 
        VAL: SockOptMarker + OptWMarker, FD: AsFd
    {
        let optval = ptr::addr_of!(val).cast();
        let option_len: u32 = size_of::<VAL::DataType>() as libc::socklen_t;

        let res = 
            unsafe
            {
                libc::setsockopt(fd.as_fd().as_raw_fd(), VAL::SO_LEVEL,VAL::SO_OPTNAME, 
                    optval, option_len)
            };

        // more likely it will not fail
        if res == 0
        {
            return Ok(());
        }
        else
        {
            return Err(std::io::Error::last_os_error());
        }
    }

    impl LocalFrom<&Ipv4Addr> for libc::in_addr
    {
        fn from(addr: &Ipv4Addr) -> Self 
        {
            return 
                libc::in_addr{ s_addr: u32::from_ne_bytes(addr.octets()) };
        }
    }


    impl LocalFrom<&Ipv6Addr> for libc::in6_addr
    {
        fn from(addr: &Ipv6Addr) -> Self 
        {
            return 
                libc::in6_addr{ s6_addr: addr.octets() };
        }
    }

    impl LocalFrom<libc::in_addr> for Ipv4Addr
    {
        fn from(addr: libc::in_addr) -> Self 
        {
            return 
                <Ipv4Addr as From<[u8; 4]>>::from(addr.s_addr.to_ne_bytes())
        }
    }

    impl LocalFrom<libc::in6_addr> for Ipv6Addr
    {
        fn from(addr: libc::in6_addr) -> Self 
        {
            return 
                <Ipv6Addr as From<[u8; 16]>>::from(addr.s6_addr)
        }
    }