#[cfg(feature = "async-std")]
pub(crate) mod async_std;
#[cfg(feature = "tokio")]
pub(crate) mod tokio;
#[cfg(feature = "smol")]
pub(crate) mod smol;
#[cfg(feature = "rustls")]
pub(crate) mod rustls;
#[cfg(feature = "native-tls")]
pub(crate) mod native_tls;
pub(crate) mod streamops;
pub(crate) mod unimpl_tls;
use crate::network::{CommonListenOptions, TcpListenOptions};
#[cfg(unix)]
use tor_error::warn_report;
const LISTEN_BACKLOG: i32 = u16::MAX as i32;
#[cfg(not(all(target_arch = "wasm32", target_os = "unknown")))]
pub(crate) fn tcp_listen(
addr: &std::net::SocketAddr,
options: &TcpListenOptions,
) -> std::io::Result<std::net::TcpListener> {
use socket2::{Domain, Socket, Type};
let TcpListenOptions {
common:
CommonListenOptions {
send_buffer_size,
recv_buffer_size,
},
} = options;
let socket = match addr {
std::net::SocketAddr::V4(_) => Socket::new(Domain::IPV4, Type::STREAM, None)?,
std::net::SocketAddr::V6(_) => {
let socket = Socket::new(Domain::IPV6, Type::STREAM, None)?;
#[cfg(unix)]
if let Err(e) = socket.set_only_v6(true) {
warn_report!(
e,
"Failed to set `IPV6_V6ONLY` on `AF_INET6` socket. \
Please report this bug at https://gitlab.torproject.org/tpo/core/arti/-/issues",
);
}
socket
}
};
socket.set_nonblocking(true)?;
#[cfg(unix)]
socket.set_reuse_address(true)?;
if let Some(send_buffer_size) = send_buffer_size {
socket.set_send_buffer_size(*send_buffer_size)?;
}
if let Some(recv_buffer_size) = recv_buffer_size {
socket.set_recv_buffer_size(*recv_buffer_size)?;
}
socket.bind(&(*addr).into())?;
socket.listen(LISTEN_BACKLOG)?;
Ok(socket.into())
}
#[cfg(all(target_arch = "wasm32", target_os = "unknown"))]
pub(crate) fn tcp_listen(
_addr: &std::net::SocketAddr,
_options: &TcpListenOptions,
) -> std::io::Result<std::net::TcpListener> {
Err(std::io::Error::from(std::io::ErrorKind::Unsupported))
}
#[cfg(not(unix))]
macro_rules! impl_unix_non_provider {
{ $for_type:ty } => {
#[async_trait]
impl crate::traits::NetStreamProvider<tor_general_addr::unix::SocketAddr> for $for_type {
type Stream = crate::unimpl::FakeStream;
type Listener = crate::unimpl::FakeListener<tor_general_addr::unix::SocketAddr>;
type ListenOptions = crate::network::UnixListenOptions;
async fn connect(&self, _a: &tor_general_addr::unix::SocketAddr) -> IoResult<Self::Stream> {
Err(tor_general_addr::unix::NoAfUnixSocketSupport::default().into())
}
async fn listen(&self,
_a: &tor_general_addr::unix::SocketAddr,
_options: &Self::ListenOptions,
) -> IoResult<Self::Listener> {
Err(tor_general_addr::unix::NoAfUnixSocketSupport::default().into())
}
}
}
}
#[cfg(not(unix))]
pub(crate) use impl_unix_non_provider;