#![cfg(unix)]
mod common;
use std::{fs, io::{ErrorKind, IoSlice, IoSliceMut, Read, Write}, net::{TcpListener, TcpStream, UdpSocket}, os::{fd::OwnedFd, unix::net::{UnixDatagram, UnixListener, UnixStream}}, path::{Path, PathBuf}, time::Duration};
use socket9::{So9MsgFlags, Socket9ExtSo, address::{So9DomainInets, So9DomainUnix}, socket::Socket9};
use uds_fork::{UnixSeqpacketConn, UnixSeqpacketListener};
#[test]
fn check_cloexec()
{
let val = Socket9::<UdpSocket>::new_unbound(So9DomainInets::Inet).unwrap();
assert_eq!(val.is_cloexec_sock().unwrap(), true);
val.set_cloexec_sock(false).unwrap();
assert_eq!(val.is_cloexec_sock().unwrap(), false);
val.set_cloexec_sock(true).unwrap();
assert_eq!(val.is_cloexec_sock().unwrap(), true);
}
#[test]
fn check_new_unbound_by_addr()
{
let sock = Socket9::<TcpStream>::new_unbound_by_addr("127.0.0.1:0").unwrap();
drop(sock);
}
#[test]
fn check_udp_vecotred_large()
{
let p1 = "127.0.0.1:0";
let sender = Socket9::<UdpSocket>::new_with_bind(&p1).unwrap();
let receiver = Socket9::<UdpSocket>::new_with_bind(&p1).unwrap();
let sock_addr_rcv = receiver.local_addr().unwrap();
let buf0 = vec![1_u8; 65307];
let buf1 = vec![2_u8; 200];
let n = sender.send_to_vectored(&[IoSlice::new(&buf0), IoSlice::new(&buf1)], &sock_addr_rcv).unwrap();
let mut rbuf0 = vec![0_u8; 65307];
let mut rbuf1 = vec![0_u8; 1000];
let rcv_io0 = IoSliceMut::new(&mut rbuf0);
let rcv_io1 = IoSliceMut::new(&mut rbuf1);
let rn = receiver.recv_from_vectored(&mut [rcv_io0, rcv_io1]).unwrap();
println!("{} {}", n, rn.0);
assert_eq!(n, rn.0);
assert_eq!(rbuf0[0], 1);
assert_eq!(rbuf1[0], 2);
}
#[test]
fn check_nonblocking()
{
let val = Socket9::<UdpSocket>::new_unbound(So9DomainInets::Inet).unwrap();
assert_eq!(val.is_nonblocking().unwrap(), false);
val.set_nonblocking(true).unwrap();
assert_eq!(val.is_nonblocking().unwrap(), true);
val.set_nonblocking(false).unwrap();
assert_eq!(val.is_nonblocking().unwrap(), false);
}
#[test]
fn test_tcp_bind_connect()
{
let tcp_listen = Socket9::<TcpListener>::new_with_bind_listen(&"127.0.0.2:8888", 1).unwrap();
let tcp_conn = Socket9::<TcpStream>::new_unbound(So9DomainInets::Inet).unwrap();
tcp_conn.connect("127.0.0.2:8888").unwrap();
let accepted_conn = tcp_listen.accept().unwrap();
let data = [1,2,3, 9];
accepted_conn.0.send(&data[..3]).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = tcp_conn.recv(&mut rcv_data).unwrap();
assert_eq!(rcv_n, 3);
assert_eq!(&data[0..rcv_n], &rcv_data[0..rcv_n]);
drop(accepted_conn);
drop(tcp_conn);
drop(tcp_listen);
}
#[test]
fn test_tcp_bind_connect_with_timeout()
{
let tcp_listen = Socket9::<TcpListener>::new_with_bind_listen(&"127.0.0.2:8889", 1).unwrap();
let tcp_conn = Socket9::<TcpStream>::new_unbound(So9DomainInets::Inet).unwrap();
tcp_conn.connect_timeout("127.0.0.2:8889", Duration::from_millis(200)).unwrap();
let accepted_conn = tcp_listen.accept().unwrap();
let data = [1,2,3, 9];
accepted_conn.0.send(&data[..3]).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = tcp_conn.recv(&mut rcv_data).unwrap();
assert_eq!(rcv_n, 3);
assert_eq!(&data[0..rcv_n], &rcv_data[0..rcv_n]);
drop(accepted_conn);
drop(tcp_conn);
drop(tcp_listen);
}
#[test]
fn test_tcp_bind_connect_timmeout()
{
let tcp_conn = Socket9::<TcpStream>::new_unbound(So9DomainInets::Inet).unwrap();
let res = tcp_conn.connect_timeout("10.255.255.1:80", Duration::from_secs(1));
assert_eq!(res.is_err(), true);
assert_eq!(res.err().as_ref().unwrap().kind(), ErrorKind::TimedOut);
}
#[test]
fn test_try_from_ownedfd_udpsock()
{
let udp = UdpSocket::bind("127.0.0.1:0").unwrap();
let val = Socket9::<UdpSocket>::try_from(OwnedFd::from(udp)).unwrap();
let _udp: UdpSocket = val.into();
}
#[test]
fn test_try_from_ownedfd_unixdg()
{
let(test_path, _dir) = common::make_temp_dir("sock123.sock");
let unix_dgram = UnixDatagram::bind(&test_path).unwrap();
let val = Socket9::<UnixDatagram>::try_from(OwnedFd::from(unix_dgram)).unwrap();
let _unix_dgram: UnixDatagram = val.into();
}
#[test]
fn test_try_from_pair_ownedfd_unixdg()
{
let (a, b) = Socket9::<UnixDatagram>::pair().unwrap();
let a: UnixDatagram = a.into();
let data = [1,2,3,4];
let snd_n = a.send(&data[..3]).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = b.recv(&mut rcv_data).unwrap();
assert_eq!(rcv_n, snd_n);
assert_eq!(&data[0..snd_n], &rcv_data[0..rcv_n]);
}
#[test]
fn test_pair_unixdg()
{
let (a, b) = Socket9::<UnixDatagram>::pair().unwrap();
let data = [1,2,3,4];
let snd_n = a.send(&data[..3]).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = b.recv(&mut rcv_data).unwrap();
assert_eq!(rcv_n, snd_n);
assert_eq!(&data[0..snd_n], &rcv_data[0..rcv_n]);
}
#[test]
fn test_try_from_ownedfd_unixlistener()
{
let(test_path, _dir) = common::make_temp_dir("sock123.sock");
let unix_stream = UnixListener::bind(&test_path).unwrap();
let val = Socket9::<UnixListener>::try_from(OwnedFd::from(unix_stream)).unwrap();
let _unix_stream: UnixListener = val.into();
}
#[test]
fn test_try_from_ownedfd_unixlistener_conn()
{
let(test_path, _dir) = common::make_temp_dir("sock123.sock");
let unix_listen = UnixListener::bind(&test_path).unwrap();
let unix_listen_conn = UnixStream::connect(&test_path).unwrap();
let val = Socket9::<UnixStream>::try_from(OwnedFd::from(unix_listen_conn)).unwrap();
let unix_stream: UnixStream = val.into();
drop(unix_stream);
drop(unix_listen);
}
#[test]
fn pair_unixstream()
{
let (a, b) = Socket9::<UnixStream>::pair().unwrap();
let data = [1,2,3,4];
let snd_n = a.send(&data[..3]).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = b.recv(&mut rcv_data).unwrap();
assert_eq!(rcv_n, snd_n);
assert_eq!(&data[0..snd_n], &rcv_data[0..rcv_n]);
}
#[test]
fn test_try_from_pair_ownedfd_unixstream()
{
let (a, b) = Socket9::<UnixStream>::pair().unwrap();
let mut a: UnixStream = a.into();
let data = [1,2,3,4];
let snd_n = a.write(&data[..3]).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = b.recv(&mut rcv_data).unwrap();
assert_eq!(rcv_n, snd_n);
assert_eq!(&data[0..snd_n], &rcv_data[0..rcv_n]);
let snd_n = b.send(&data[1..4]).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = a.read(&mut rcv_data).unwrap();
assert_eq!(rcv_n, snd_n);
assert_eq!(&data[1..1+snd_n], &rcv_data[0..rcv_n]);
}
#[test]
fn test_try_from_ownedfd_unixseqpktlis()
{
let(test_path, _dir) = common::make_temp_dir("sock123.sock");
let unix_listen = UnixSeqpacketListener::bind(&test_path).unwrap();
let val = Socket9::<UnixSeqpacketListener>::try_from(OwnedFd::from(unix_listen)).unwrap();
let _unix_stream: UnixSeqpacketListener = val.into();
}
#[test]
fn test_try_from_ownedfd_unixseqpkt_conn()
{
let(test_path, _dir) = common::make_temp_dir("sock123.sock");
let unix_listen = UnixSeqpacketListener::bind(&test_path).unwrap();
let unix_listen_conn = UnixSeqpacketConn::connect(&test_path).unwrap();
let val = Socket9::<UnixSeqpacketConn>::try_from(OwnedFd::from(unix_listen_conn)).unwrap();
let unix_stream: UnixSeqpacketConn = val.into();
drop(unix_stream);
drop(unix_listen);
}
#[test]
fn pair_unixseqpkt()
{
let (a, b) = Socket9::<UnixSeqpacketConn>::pair().unwrap();
let data = [1,2,3,4];
let snd_n = a.send(&data[..3]).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = b.recv(&mut rcv_data).unwrap();
assert_eq!(rcv_n, snd_n);
assert_eq!(&data[0..snd_n], &rcv_data[0..rcv_n]);
}
#[test]
fn test_try_from_pair_ownedfd_unixseqpkt()
{
let (a, b) = Socket9::<UnixSeqpacketConn>::pair().unwrap();
let a: UnixSeqpacketConn = a.into();
let data = [1,2,3,4];
let snd_n = a.send(&data[..3]).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = b.recv(&mut rcv_data).unwrap();
assert_eq!(rcv_n, snd_n);
assert_eq!(&data[0..snd_n], &rcv_data[0..rcv_n]);
}
#[test]
fn test_try_from_ownedfd_tcp_listener()
{
let tcp_listen = TcpListener::bind("127.0.0.1:0").unwrap();
let val = Socket9::<TcpListener>::try_from(OwnedFd::from(tcp_listen)).unwrap();
let _tcp_listen: TcpListener = val.into();
}
#[test]
fn test_try_from_ownedfd_tcp_connection()
{
let tcp_listen = TcpListener::bind("127.0.0.1:0").unwrap();
let addr = tcp_listen.local_addr().unwrap();
let tcp_stream = TcpStream::connect_timeout(&addr, Duration::from_secs(1)).unwrap();
let accpt = tcp_listen.accept().unwrap();
let val = Socket9::<TcpListener>::try_from(OwnedFd::from(tcp_listen)).unwrap();
let tcp_listen: TcpListener = val.into();
drop(tcp_stream);
drop(accpt);
drop(tcp_listen);
}
#[test]
fn test_unixdatagram_send_to()
{
let(test_path, _dir) = common::make_temp_dir("sock123.sock");
let rcv_part = Socket9::<UnixDatagram>::new_with_bind(&test_path).unwrap();
let snd_part = Socket9::<UnixDatagram>::new_unbound(So9DomainUnix::Unix).unwrap();
let data = [1,2,3,4];
let snt_n = snd_part.send_to(&data[..3], &test_path).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = rcv_part.recv(&mut rcv_data).unwrap();
assert_eq!(snt_n, rcv_n);
assert_eq!(&data[0..snt_n], &rcv_data[0..rcv_n]);
}
#[test]
fn test_unixdatagram_send_to2()
{
let test_path = "@unixdg_ex";
let rcv_part = Socket9::<UnixDatagram>::new_with_bind(&test_path).unwrap();
let snd_part = Socket9::<UnixDatagram>::new_unbound(So9DomainUnix::Unix).unwrap();
let data = [1,2,3,4];
let snt_n = snd_part.send_to(&data[..3], &test_path).unwrap();
let mut rcv_data = [0_u8; 4];
let rcv_n = rcv_part.recv(&mut rcv_data).unwrap();
assert_eq!(snt_n, rcv_n);
assert_eq!(&data[0..snt_n], &rcv_data[0..rcv_n]);
}
#[test]
fn test_unixdatagram_recv_from()
{
let test_path_snd = "@unixdg_ex";
let test_path_rcv = "@unixdg_ex_rcv";
let snd_part = Socket9::<UnixDatagram>::new_with_bind(&test_path_snd).unwrap();
let rcv_part = Socket9::<UnixDatagram>::new_with_bind(&test_path_rcv).unwrap();
let data = [1,2,3,4];
let snt_n = snd_part.send_to(&data[..3], &test_path_rcv).unwrap();
assert_eq!(snt_n, 3);
let mut rcv_data = [0_u8; 4];
let rcv = rcv_part.recv_from_flags_timeout(&mut rcv_data, So9MsgFlags::empty(), Duration::from_secs(1)).unwrap();
assert_eq!(snt_n, rcv.0);
println!("{}", rcv.1);
assert_eq!(&data[0..snt_n], &rcv_data[0..rcv.0]);
}
#[test]
fn test_unixdatagram_recv_from_timeout()
{
let test_path_snd = "@unixdg_ex1";
let test_path_rcv = "@unixdg_ex1_rcv";
let snd_part = Socket9::<UnixDatagram>::new_with_bind(&test_path_snd).unwrap();
let rcv_part = Socket9::<UnixDatagram>::new_with_bind(&test_path_rcv).unwrap();
let data = [1,2,3,4];
let snt_n = snd_part.send_to(&data[..3], &test_path_snd).unwrap();
assert_eq!(snt_n, 3);
let mut rcv_data = [0_u8; 4];
let rcv = rcv_part.recv_from_flags_timeout(&mut rcv_data, So9MsgFlags::empty(), Duration::from_secs(1));
assert_eq!(rcv.is_err(), true);
assert_eq!(rcv.err().as_ref().unwrap().kind(), ErrorKind::TimedOut);
}
#[test]
fn test_unixstream_io_listen()
{
let tcp_listen = Socket9::<UnixListener>::new_with_bind_listen(&"@teest", 1).unwrap();
let serv_addr = tcp_listen.local_addr().unwrap();
println!("{}", serv_addr);
assert_eq!("@teest", serv_addr.to_string().as_str());
}
#[test]
fn test_tcp_io_listen()
{
let tcp_listen = Socket9::<TcpListener>::new_with_bind_listen(&"0.0.0.0:0", 1).unwrap();
let serv_addr = tcp_listen.local_addr().unwrap();
assert_eq!(serv_addr.is_ipv4(), true);
assert_eq!(serv_addr.ip().is_unspecified(), true);
}
#[test]
fn test_tcp_io_listen_accept_timeout()
{
let tcp_listen = Socket9::<TcpListener>::new_with_bind_hostname_listen("localhost:0", 128).unwrap();
let serv_addr = tcp_listen.local_addr().unwrap();
println!("{}", serv_addr);
let thandler =
std::thread::spawn(move ||
{
let sock = Socket9::<TcpStream>::new_unbound_into(&serv_addr).unwrap();
sock.connect(&serv_addr).unwrap();
println!("conncected");
std::thread::sleep(Duration::from_secs(2));
drop(sock);
}
);
println!("accepting");
let res = tcp_listen.accept().unwrap();
println!("accepted");
let res2 = tcp_listen.accept_timeout(Duration::from_secs(1));
println!("{:?}", res2);
assert_eq!(res2.is_err(), true);
assert_eq!(res2.err().unwrap().kind(), ErrorKind::TimedOut);
drop(res);
thandler.join().unwrap();
}
#[test]
fn test_tcp_io()
{
let tcp_listen = Socket9::<TcpListener>::new_with_bind_listen(&"127.0.0.1:0", 1).unwrap();
let serv_addr = tcp_listen.local_addr().unwrap();
let mut tcp_stream = Socket9::<TcpStream>::new_with_bind(&"127.0.0.1:0").unwrap();
let client_addr = tcp_stream.local_addr().unwrap();
tcp_stream.connect_timeout(&serv_addr, Duration::from_secs(1)).unwrap();
let (rem_sock, rem_addr) = tcp_listen.accept().unwrap();
println!("accepted connection from: {} exp: {}", rem_addr, client_addr);
assert_eq!(client_addr, rem_addr);
let test_str = "test!";
write!(&rem_sock, "{}", test_str).unwrap();
let mut buf = vec![0_u8; 20];
let rcv_n = tcp_stream.read(&mut buf).unwrap();
let rcv_str = str::from_utf8(&buf[..rcv_n]).unwrap();
assert_eq!(rcv_n, test_str.as_bytes().len());
assert_eq!(rcv_str, test_str);
drop(tcp_stream);
drop(rem_sock);
drop(tcp_listen);
}
#[test]
fn test_tcp_io_unbound()
{
let tcp_listen = Socket9::<TcpListener>::new_with_bind_listen(&"127.0.0.1:0", 1).unwrap();
let serv_addr = tcp_listen.local_addr().unwrap();
let mut tcp_stream = Socket9::<TcpStream>::connect_unbound(&serv_addr).unwrap();
let client_addr = tcp_stream.local_addr().unwrap();
let (rem_sock, rem_addr) = tcp_listen.accept().unwrap();
println!("accepted connection from: {} exp: {}", rem_addr, client_addr);
assert_eq!(client_addr, rem_addr);
let test_str = "test!";
write!(&rem_sock, "{}", test_str).unwrap();
let mut buf = vec![0_u8; 20];
let rcv_n = tcp_stream.read(&mut buf).unwrap();
let rcv_str = str::from_utf8(&buf[..rcv_n]).unwrap();
assert_eq!(rcv_n, test_str.as_bytes().len());
assert_eq!(rcv_str, test_str);
drop(tcp_stream);
drop(rem_sock);
drop(tcp_listen);
}
#[test]
fn test_unixdg_timeout_rcv()
{
let test_path_snd = "@unixdg_ex";
let unix_dg = Socket9::<UnixDatagram>::new_with_bind(&test_path_snd).unwrap();
unix_dg.set_so_recv_timeout(Some(Duration::from_millis(500))).unwrap();
unix_dg.set_so_send_timeout(Some(Duration::from_millis(500))).unwrap();
let mut rcv_buf = [0_u8; 8];
let res = unix_dg.recv(&mut rcv_buf);
assert_eq!(res.is_err(), true);
assert_eq!(res.err().unwrap().kind(), ErrorKind::WouldBlock);
let res = unix_dg.send(&rcv_buf);
assert_eq!(res.is_err(), true);
assert_eq!(res.err().unwrap().kind(), ErrorKind::NotConnected);
}
#[test]
fn test_unixdg_vect()
{
let test_path_snd = "@unixdg2_ex";
let unix_dg = Socket9::<UnixDatagram>::new_with_bind(&test_path_snd).unwrap();
unix_dg.set_so_recv_timeout(Some(Duration::from_millis(500))).unwrap();
unix_dg.set_so_send_timeout(Some(Duration::from_millis(500))).unwrap();
let snd_dg = Socket9::<UnixDatagram>::new_unbound(So9DomainUnix::Unix).unwrap();
snd_dg.connect(test_path_snd).unwrap();
let snd_data = [b'5'; 10];
let snd_n = snd_dg.send_vectored(&mut[IoSlice::new(&snd_data)]).unwrap();
let mut rcv_data = [0; 10];
let mut rcv_vects = [IoSliceMut::new(&mut rcv_data)];
let rcv_n = unix_dg.recv_vectored(&mut rcv_vects).unwrap();
println!("{} {}", snd_n, rcv_n);
assert_eq!(snd_n, rcv_n);
assert_eq!(rcv_data, snd_data);
}
#[test]
fn test_unixdg_fd()
{
let (a, b) = Socket9::<UnixDatagram>::pair().unwrap();
let fd_to_send = OwnedFd::from(UnixDatagram::unbound().unwrap());
let snd_n = a.send_fd(fd_to_send).unwrap();
assert_eq!(snd_n, 0);
println!("{}", snd_n);
let fdrecv = b.recv_fd().unwrap();
let _dg = UnixDatagram::from(fdrecv);
}