raw_socket/
lib.rs

1// Copyright (C) 2020 - Will Glozer. All rights reserved.
2
3pub use crate::socket::RawSocket;
4
5pub use socket2::Domain;
6pub use socket2::Type;
7pub use socket2::Protocol;
8
9pub mod control;
10pub mod ffi;
11pub mod option;
12pub mod prelude;
13
14mod socket;
15
16#[cfg(feature = "async-tokio")]
17pub mod tokio;
18
19#[cfg(test)]
20mod test {
21    use std::io::{Error, ErrorKind, IoSlice, IoSliceMut, Result};
22    use std::net::{IpAddr, SocketAddr};
23    use std::thread::sleep;
24    use std::time::Duration;
25    use libc::{c_int, SOCK_DGRAM, SOCK_STREAM};
26    use crate::{RawSocket, Domain, Type};
27    use crate::option::{Level, Name};
28
29    #[test]
30    fn get_sockopt() -> Result<()> {
31        let ipv4  = Domain::ipv4();
32
33        let sock0 = RawSocket::new(ipv4, Type::dgram(),  None)?;
34        let sock1 = RawSocket::new(ipv4, Type::stream(), None)?;
35
36        assert_eq!(SOCK_DGRAM,  sock0.get_sockopt(Level::SOCKET, Name::SO_TYPE)?);
37        assert_eq!(SOCK_STREAM, sock1.get_sockopt(Level::SOCKET, Name::SO_TYPE)?);
38
39        Ok(())
40    }
41
42    #[test]
43    fn set_sockopt() -> Result<()> {
44        let level = Level::SOCKET;
45        let name  = Name::SO_KEEPALIVE;
46
47        let sock = RawSocket::new(Domain::ipv4(), Type::stream(), None)?;
48
49        let mut get: c_int;
50        get = sock.get_sockopt(level, name)?;
51        assert!(get == 0);
52
53        let set: c_int = 1;
54        sock.set_sockopt(level, name, &set)?;
55
56        get = sock.get_sockopt(level, name)?;
57        assert!(get != 0);
58
59        Ok(())
60    }
61
62    #[test]
63    fn send_recv_msg() -> Result<()> {
64        let addr = SocketAddr::new(IpAddr::from([127, 0, 0, 1]), 0);
65
66        let send = RawSocket::new(Domain::ipv4(), Type::dgram(), None)?;
67        let recv = RawSocket::new(Domain::ipv4(), Type::dgram(), None)?;
68
69        send.bind(&addr)?;
70        recv.bind(&addr)?;
71
72        let sent = [0u8; 64];
73        let addr = recv.local_addr()?;
74        let n = send.send_msg(&addr, &[IoSlice::new(&sent)], &[])?;
75
76        assert_eq!(n, sent.len());
77
78        let mut data = [0u8; 64];
79
80        let (n, from) = loop {
81            let iovec = &[IoSliceMut::new(&mut data)];
82            let delay = Duration::from_secs(1);
83
84            let is_wb = |e: &Error| e.kind() == ErrorKind::WouldBlock;
85
86            match recv.recv_msg(iovec, &mut []) {
87                Ok((n, from))          => break (n, from),
88                Err(ref e) if is_wb(e) => sleep(delay),
89                Err(e)                 => return Err(e),
90            }
91        };
92
93        assert_eq!(n, data.len());
94        assert_eq!(&sent[..], &data[..]);
95        assert_eq!(from, send.local_addr()?);
96
97        Ok(())
98    }
99}