pub(crate) async fn tokio_create(addr: std::net::SocketAddr) -> std::io::Result<tokio::net::TcpStream> {
#[cfg(target_os = "android")]
{
let socket = if addr.is_ipv4() {
tokio::net::TcpSocket::new_v4()?
} else {
tokio::net::TcpSocket::new_v6()?
};
use std::os::unix::io::AsRawFd;
crate::android::protect_socket(socket.as_raw_fd())?;
Ok(socket.connect(addr).await?)
}
#[cfg(not(target_os = "android"))]
tokio::net::TcpStream::connect(addr).await
}
pub(crate) fn std_create(addr: std::net::SocketAddr, timeout: Option<std::time::Duration>) -> std::io::Result<std::net::TcpStream> {
use socket2::{Domain, SockAddr, Socket, Type};
let domain = if addr.is_ipv4() { Domain::IPV4 } else { Domain::IPV6 };
let socket = Socket::new(domain, Type::STREAM, None)?;
#[cfg(target_os = "android")]
{
use std::os::unix::io::AsRawFd;
crate::android::protect_socket(socket.as_raw_fd())?;
}
if let Some(timeout) = timeout {
socket.connect_timeout(&SockAddr::from(addr), timeout)?;
} else {
socket.connect(&SockAddr::from(addr))?;
}
#[cfg(unix)]
{
use std::os::unix::io::{FromRawFd, IntoRawFd};
Ok(unsafe { std::net::TcpStream::from_raw_fd(socket.into_raw_fd()) })
}
#[cfg(windows)]
{
use std::os::windows::io::{FromRawSocket, IntoRawSocket};
Ok(unsafe { std::net::TcpStream::from_raw_socket(socket.into_raw_socket()) })
}
}