Skip to content

Commit 7b2fd4e

Browse files
committed
Replace socket2 calls with rustix
socket2 is our last libc-using dependency. By replacing it with rustix calls, we can make this crate libc-free. This doesn't set the inherit disable property on Windows yet, as rustix does not support it. Signed-off-by: John Nunley <dev@notgull.net>
1 parent d9c9ed8 commit 7b2fd4e

File tree

2 files changed

+83
-19
lines changed

2 files changed

+83
-19
lines changed

Cargo.toml

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,8 @@ futures-io = { version = "0.3.28", default-features = false, features = ["std"]
3030
futures-lite = { version = "1.11.0", default-features = false }
3131
parking = "2.0.0"
3232
polling = "2.6.0"
33-
rustix = { version = "0.38.2", default-features = false, features = ["std", "fs"] }
33+
rustix = { version = "0.38.2", default-features = false, features = ["fs", "net", "std"] }
3434
slab = "0.4.2"
35-
socket2 = { version = "0.5.3", features = ["all"] }
3635
tracing = { version = "0.1.37", default-features = false }
3736
waker-fn = "1.1.0"
3837

src/lib.rs

Lines changed: 82 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,9 @@ use std::os::windows::io::{AsSocket, BorrowedSocket, OwnedSocket};
8787
use futures_io::{AsyncRead, AsyncWrite};
8888
use futures_lite::stream::{self, Stream};
8989
use futures_lite::{future, pin, ready};
90-
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
90+
91+
use rustix::io as rio;
92+
use rustix::net as rn;
9193

9294
use crate::reactor::{Reactor, Source};
9395

@@ -1386,10 +1388,15 @@ impl Async<TcpStream> {
13861388
/// # std::io::Result::Ok(()) });
13871389
/// ```
13881390
pub async fn connect<A: Into<SocketAddr>>(addr: A) -> io::Result<Async<TcpStream>> {
1389-
// Begin async connect.
1391+
// Figure out how to handle this address.
13901392
let addr = addr.into();
1391-
let domain = Domain::for_address(addr);
1392-
let socket = connect(addr.into(), domain, Some(Protocol::TCP))?;
1393+
let (domain, sock_addr) = match addr {
1394+
SocketAddr::V4(v4) => (rn::AddressFamily::INET, rn::SocketAddrAny::V4(v4)),
1395+
SocketAddr::V6(v6) => (rn::AddressFamily::INET6, rn::SocketAddrAny::V6(v6)),
1396+
};
1397+
1398+
// Begin async connect.
1399+
let socket = connect(sock_addr, domain, Some(rn::ipproto::TCP))?;
13931400
let stream = Async::new(TcpStream::from(socket))?;
13941401

13951402
// The stream becomes writable when connected.
@@ -1718,7 +1725,11 @@ impl Async<UnixStream> {
17181725
/// ```
17191726
pub async fn connect<P: AsRef<Path>>(path: P) -> io::Result<Async<UnixStream>> {
17201727
// Begin async connect.
1721-
let socket = connect(SockAddr::unix(path)?, Domain::UNIX, None)?;
1728+
let socket = connect(
1729+
rn::SocketAddrUnix::new(path.as_ref())?.into(),
1730+
rn::AddressFamily::UNIX,
1731+
None,
1732+
)?;
17221733
let stream = Async::new(UnixStream::from(socket))?;
17231734

17241735
// The stream becomes writable when connected.
@@ -1928,8 +1939,11 @@ async fn optimistic(fut: impl Future<Output = io::Result<()>>) -> io::Result<()>
19281939
.await
19291940
}
19301941

1931-
fn connect(addr: SockAddr, domain: Domain, protocol: Option<Protocol>) -> io::Result<Socket> {
1932-
let sock_type = Type::STREAM;
1942+
fn connect(
1943+
addr: rn::SocketAddrAny,
1944+
domain: rn::AddressFamily,
1945+
protocol: Option<rn::Protocol>,
1946+
) -> io::Result<rustix::fd::OwnedFd> {
19331947
#[cfg(any(
19341948
target_os = "android",
19351949
target_os = "dragonfly",
@@ -1940,10 +1954,13 @@ fn connect(addr: SockAddr, domain: Domain, protocol: Option<Protocol>) -> io::Re
19401954
target_os = "netbsd",
19411955
target_os = "openbsd"
19421956
))]
1943-
// If we can, set nonblocking at socket creation for unix
1944-
let sock_type = sock_type.nonblocking();
1945-
// This automatically handles cloexec on unix, no_inherit on windows and nosigpipe on macos
1946-
let socket = Socket::new(domain, sock_type, protocol)?;
1957+
let socket = rn::socket_with(
1958+
domain,
1959+
rn::SocketType::STREAM,
1960+
rn::SocketFlags::CLOEXEC | rn::SocketFlags::NONBLOCK,
1961+
protocol,
1962+
)?;
1963+
19471964
#[cfg(not(any(
19481965
target_os = "android",
19491966
target_os = "dragonfly",
@@ -1954,14 +1971,62 @@ fn connect(addr: SockAddr, domain: Domain, protocol: Option<Protocol>) -> io::Re
19541971
target_os = "netbsd",
19551972
target_os = "openbsd"
19561973
)))]
1957-
// If the current platform doesn't support nonblocking at creation, enable it after creation
1958-
socket.set_nonblocking(true)?;
1959-
match socket.connect(&addr) {
1974+
let socket = {
1975+
#[cfg(not(any(
1976+
target_os = "macos",
1977+
target_os = "ios",
1978+
target_os = "tvos",
1979+
target_os = "watchos",
1980+
windows,
1981+
target_os = "aix",
1982+
target_os = "haiku"
1983+
)))]
1984+
let flags = rn::SocketFlags::CLOEXEC;
1985+
#[cfg(any(
1986+
target_os = "macos",
1987+
target_os = "ios",
1988+
target_os = "tvos",
1989+
target_os = "watchos",
1990+
windows,
1991+
target_os = "aix",
1992+
target_os = "haiku"
1993+
))]
1994+
let flags = rn::SocketFlags::empty();
1995+
1996+
// Create the socket.
1997+
let socket = rn::socket_with(domain, rn::SocketFlags::STREAM, flags, protocol)?;
1998+
1999+
// Set cloexec if necessary.
2000+
#[cfg(any(
2001+
target_os = "macos",
2002+
target_os = "ios",
2003+
target_os = "tvos",
2004+
target_os = "watchos"
2005+
))]
2006+
rio::fcntl_setfd(&socket, rio::fcntl_getfd(&socket)? | rio::FdFlags::CLOEXEC)?;
2007+
2008+
// Set non-blocking mode.
2009+
rio::ioctl_fionbio(&socket, true)?;
2010+
2011+
socket
2012+
};
2013+
2014+
// Set nosigpipe if necessary.
2015+
#[cfg(any(
2016+
target_os = "macos",
2017+
target_os = "ios",
2018+
target_os = "tvos",
2019+
target_os = "watchos",
2020+
target_os = "freebsd"
2021+
))]
2022+
rn::sockopt::set_socket_nosigpipe(&socket, true)?;
2023+
2024+
match rn::connect_any(&socket, &addr) {
19602025
Ok(_) => {}
19612026
#[cfg(unix)]
1962-
Err(err) if err.raw_os_error() == Some(rustix::io::Errno::INPROGRESS.raw_os_error()) => {}
1963-
Err(err) if err.kind() == io::ErrorKind::WouldBlock => {}
1964-
Err(err) => return Err(err),
2027+
Err(rio::Errno::INPROGRESS) => {}
2028+
Err(rio::Errno::AGAIN) => {}
2029+
Err(err) => return Err(err.into()),
19652030
}
19662031
Ok(socket)
19672032
}

0 commit comments

Comments
 (0)