1mod listener_config;
5pub mod tcp;
6pub mod udp;
7#[cfg(unix)]
8pub mod unix;
9
10pub use listener_config::ListenerOpts;
11#[deprecated(since = "0.2.0", note = "use ListenerOpts")]
12pub use listener_config::ListenerOpts as ListenerConfig;
13pub use tcp::{TcpConnectOpts, TcpListener, TcpStream};
14#[cfg(unix)]
15pub use unix::{Pipe, UnixDatagram, UnixListener, UnixStream};
16#[cfg(windows)]
17use {
18 std::os::windows::prelude::RawSocket,
19 windows_sys::Win32::{
20 Foundation::NO_ERROR,
21 Networking::WinSock::{
22 closesocket, ioctlsocket, socket, WSACleanup, WSAStartup, ADDRESS_FAMILY, FIONBIO,
23 INVALID_SOCKET, WINSOCK_SOCKET_TYPE,
24 },
25 },
26};
27
28#[cfg(unix)]
30pub(crate) fn new_socket(
31 domain: libc::c_int,
32 socket_type: libc::c_int,
33) -> std::io::Result<libc::c_int> {
34 #[cfg(any(
35 target_os = "android",
36 target_os = "dragonfly",
37 target_os = "freebsd",
38 target_os = "illumos",
39 target_os = "netbsd",
40 target_os = "openbsd"
41 ))]
42 let socket_type = socket_type | libc::SOCK_NONBLOCK | libc::SOCK_CLOEXEC;
43
44 #[cfg(target_os = "linux")]
45 let socket_type = {
46 if crate::driver::op::is_legacy() {
47 socket_type | libc::SOCK_CLOEXEC | libc::SOCK_NONBLOCK
48 } else {
49 socket_type | libc::SOCK_CLOEXEC
50 }
51 };
52
53 #[allow(clippy::let_and_return)]
55 #[cfg(unix)]
56 let socket = crate::syscall!(socket@RAW(domain, socket_type, 0));
57
58 #[cfg(target_vendor = "apple")]
60 let socket = socket.and_then(|socket| {
61 crate::syscall!(setsockopt@RAW(
62 socket,
63 libc::SOL_SOCKET,
64 libc::SO_NOSIGPIPE,
65 &1 as *const libc::c_int as *const libc::c_void,
66 std::mem::size_of::<libc::c_int>() as libc::socklen_t
67 ))
68 .map(|_| socket)
69 });
70
71 #[cfg(any(target_os = "ios", target_os = "macos"))]
73 let socket = socket.and_then(|socket| {
74 crate::syscall!(fcntl@RAW(socket, libc::F_SETFL, libc::O_NONBLOCK))
77 .and_then(|_| {
78 crate::syscall!(fcntl@RAW(socket, libc::F_SETFD, libc::FD_CLOEXEC)).map(|_| socket)
79 })
80 .inspect_err(|_| {
81 let _ = crate::syscall!(close@RAW(socket));
84 })
85 });
86
87 socket
88}
89
90#[allow(non_snake_case, missing_docs)]
91#[cfg(windows)]
92#[inline]
93pub fn MAKEWORD(a: u8, b: u8) -> u16 {
94 (a as u16) | ((b as u16) << 8)
95}
96
97#[cfg(windows)]
98pub(crate) fn new_socket(
99 domain: ADDRESS_FAMILY,
100 socket_type: WINSOCK_SOCKET_TYPE,
101) -> std::io::Result<RawSocket> {
102 let _: i32 = crate::syscall!(
103 WSAStartup@RAW(MAKEWORD(2, 2), std::ptr::null_mut()),
104 PartialEq::eq,
105 NO_ERROR as _
106 )?;
107 let socket = crate::syscall!(
108 socket@RAW(domain as _, socket_type, 0),
109 PartialEq::eq,
110 INVALID_SOCKET
111 )?;
112 crate::syscall!(
113 ioctlsocket@RAW(socket, FIONBIO, &mut 1),
114 PartialEq::ne,
115 NO_ERROR as _
116 )
117 .map(|_: i32| socket as RawSocket)
118 .inspect_err(|_| {
119 unsafe {
122 closesocket(socket);
123 WSACleanup();
124 }
125 })
126}