socket9 0.1.0-alpha.1

Extended untilities for the networking/unix sockets and raw network sockets
Documentation
use std::{os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd}, time::Duration};

use socket9::
{
    AsOsDescr, So9DomainRange, So9DomainUnix, So9Marker, So9MarkerBind, So9MarkerListener, 
    So9MarkerSockUnix, So9MsgFlags, So9SockDwFlags, So9SockProtocol, So9SockType, Socket9, 
    Socket9ExtSo, UnixSocketAddr
};

// This example is for UNIX SEQPKT.

/// A connection socket.
#[derive(Debug)]
pub struct UnixSeqpktConnectionTest(OwnedFd);

impl AsFd for UnixSeqpktConnectionTest
{
    fn as_fd(&self) -> BorrowedFd<'_> 
    {
        self.0.as_fd()
    }
}

impl AsRawFd for UnixSeqpktConnectionTest
{
    fn as_raw_fd(&self) -> RawFd 
    {
        self.0.as_raw_fd()
    }
}

impl UnixSeqpktConnectionTest
{
    
}

// Marking the OS socket descriptor
impl AsOsDescr for UnixSeqpktConnectionTest {}

// Unwrap from Socket9 into native type.
impl From<Socket9<UnixSeqpktConnectionTest>> for UnixSeqpktConnectionTest
{
    fn from(value: Socket9<UnixSeqpktConnectionTest>) -> Self 
    {
        let ofd: OwnedFd = value.into();
        return Self(ofd);
    }
}

// This is a unix socket (not network).
impl So9MarkerSockUnix for UnixSeqpktConnectionTest {}

// Allow to bind the instacne
impl So9MarkerBind for UnixSeqpktConnectionTest {}

// Socket 9 general marker for the connector.
impl So9Marker for UnixSeqpktConnectionTest
{
    // OwnedFd is socket wrapper
    type SockType = OwnedFd;

    // is this a passive socket?
    const IS_LISTENING: bool = false;

    // which domain it belongs to
    const SO_DOMAIN_GROUP: So9DomainRange = So9DomainRange::DoUnixs;

    // a type UNIX_SEQPKT
    const SO_TYPE: So9SockType = So9SockType::SEQPACKET;

    // default flags (when created)
    const SO_DEF_FLAGS: So9SockDwFlags = So9SockDwFlags::CLOEXEC;

    // no protocol (this is unix socket)
    const SO_PROTO: So9SockProtocol = So9SockProtocol::NONE;

    // default send flags
    const SOCK_SND_FLAGS: So9MsgFlags = So9MsgFlags::MSG_EOR;

    // default send vect flags
    const SOCK_SND_VECT_FLAGS: So9MsgFlags = So9MsgFlags::MSG_EOR;

    // default rcv flags
    const SOCK_RCV_FLAGS: So9MsgFlags = So9MsgFlags::empty();

    // default rcv vect flags
    const SOCK_RCV_VECT_FLAGS: So9MsgFlags = So9MsgFlags::empty();

    // Address type is unix address
    type SockAddrType = UnixSocketAddr;

    // Socket address domain.
    type SockAddrDomain = So9DomainUnix;
}



#[derive(Debug)]
pub struct UnixSeqpktListenerTest(OwnedFd);

impl AsFd for UnixSeqpktListenerTest
{
    fn as_fd(&self) -> BorrowedFd<'_> 
    {
        self.0.as_fd()
    }
}

impl AsRawFd for UnixSeqpktListenerTest
{
    fn as_raw_fd(&self) -> RawFd 
    {
        self.0.as_raw_fd()
    }
}

impl UnixSeqpktListenerTest
{
    
}

impl So9Marker for UnixSeqpktListenerTest
{
    type SockType = OwnedFd;

    const IS_LISTENING: bool = true;

    const SO_DOMAIN_GROUP: So9DomainRange = So9DomainRange::DoUnixs;

    const SO_TYPE: So9SockType = So9SockType::SEQPACKET;

    const SO_DEF_FLAGS: So9SockDwFlags = So9SockDwFlags::CLOEXEC;

    const SO_PROTO: So9SockProtocol = So9SockProtocol::NONE;

    const SOCK_SND_FLAGS: So9MsgFlags = So9MsgFlags::MSG_EOR;

    const SOCK_SND_VECT_FLAGS: So9MsgFlags = So9MsgFlags::MSG_EOR;

    const SOCK_RCV_FLAGS: So9MsgFlags = So9MsgFlags::empty();

    const SOCK_RCV_VECT_FLAGS: So9MsgFlags = So9MsgFlags::empty();

    type SockAddrType = UnixSocketAddr;

    type SockAddrDomain = So9DomainUnix;
}

impl So9MarkerBind for UnixSeqpktListenerTest {}

// This is passive socket, IS_LISTENING = true, so implement the listener.
impl So9MarkerListener for UnixSeqpktListenerTest 
{
    // default flags for accepted sockets.
    const SOCK_ACCEPT_FLAGS: i32 = libc::SOCK_CLOEXEC;

    // an accepted type.
    type AcceptedType = UnixSeqpktConnectionTest;
}

impl From<Socket9<UnixSeqpktListenerTest>> for UnixSeqpktListenerTest
{
    fn from(value: Socket9<UnixSeqpktListenerTest>) -> Self 
    {
        let ofd: OwnedFd = value.into();
        return Self(ofd);
    }
}

// for example implement the Socket9ExtSo for the listener.
impl Socket9ExtSo<UnixSeqpktListenerTest> for Socket9<UnixSeqpktListenerTest> {}
impl AsOsDescr for UnixSeqpktListenerTest {}

fn main()
{
    let dir = tempfile::tempdir().unwrap();
    let path = dir.path().join("seqpkt_sock_test.sock");

    let listener = 
        Socket9::<UnixSeqpktListenerTest>::new_with_bind(&path).unwrap();

    listener.listen(10).unwrap();

    let client =  Socket9::<UnixSeqpktConnectionTest>::connect_unbound(&path).unwrap();

    let (conn, addr) = listener.accept_timeout(Duration::from_secs(1)).unwrap();

    println!("incoming connection from: {}", addr);

    let buf = [1,2,3,4];

    let n= client.send(&buf).unwrap();

    println!("client sent {} bytes", n);

    let mut recv_buf = [0_u8; 10];
    let rcv_n = conn.recv(&mut recv_buf).unwrap();

    println!("connection received {} bytes", rcv_n);
}