Skip to content

Update to socket2 v0.4.0 #2472

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Mar 22, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ want = "0.3"
# Optional

libc = { version = "0.2", optional = true }
socket2 = { version = "0.3.16", optional = true }
socket2 = { version = "0.4", optional = true }

[dev-dependencies]
futures-util = { version = "0.3", default-features = false, features = ["alloc"] }
Expand Down
12 changes: 5 additions & 7 deletions src/client/connect/http.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,14 +584,11 @@ fn connect(
// TODO(eliza): if Tokio's `TcpSocket` gains support for setting the
// keepalive timeout, it would be nice to use that instead of socket2,
// and avoid the unsafe `into_raw_fd`/`from_raw_fd` dance...
use socket2::{Domain, Protocol, Socket, Type};
use socket2::{Domain, Protocol, Socket, TcpKeepalive, Type};
use std::convert::TryInto;

let domain = match *addr {
SocketAddr::V4(_) => Domain::ipv4(),
SocketAddr::V6(_) => Domain::ipv6(),
};
let socket = Socket::new(domain, Type::stream(), Some(Protocol::tcp()))
let domain = Domain::for_address(*addr);
let socket = Socket::new(domain, Type::STREAM, Some(Protocol::TCP))
.map_err(ConnectError::m("tcp open error"))?;

// When constructing a Tokio `TcpSocket` from a raw fd/socket, the user is
Expand All @@ -601,7 +598,8 @@ fn connect(
.map_err(ConnectError::m("tcp set_nonblocking error"))?;

if let Some(dur) = config.keep_alive_timeout {
if let Err(e) = socket.set_keepalive(Some(dur)) {
let conf = TcpKeepalive::new().with_time(dur);
if let Err(e) = socket.set_tcp_keepalive(&conf) {
warn!("tcp set_keepalive error: {}", e);
}
}
Expand Down
41 changes: 3 additions & 38 deletions src/server/tcp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,46 +108,11 @@ impl AddrIncoming {
match ready!(self.listener.poll_accept(cx)) {
Ok((socket, addr)) => {
if let Some(dur) = self.tcp_keepalive_timeout {
// Convert the Tokio `TcpStream` into a `socket2` socket
// so we can call `set_keepalive`.
// TODO(eliza): if Tokio's `TcpSocket` API grows a few
// more methods in the future, hopefully we shouldn't
// have to do the `from_raw_fd` dance any longer...
#[cfg(unix)]
let socket = unsafe {
// Safety: `socket2`'s socket will try to close the
// underlying fd when it's dropped. However, we
// can't take ownership of the fd from the tokio
// TcpStream, so instead we will call `into_raw_fd`
// on the socket2 socket before dropping it. This
// prevents it from trying to close the fd.
use std::os::unix::io::{AsRawFd, FromRawFd};
socket2::Socket::from_raw_fd(socket.as_raw_fd())
};
#[cfg(windows)]
let socket = unsafe {
// Safety: `socket2`'s socket will try to close the
// underlying SOCKET when it's dropped. However, we
// can't take ownership of the SOCKET from the tokio
// TcpStream, so instead we will call `into_raw_socket`
// on the socket2 socket before dropping it. This
// prevents it from trying to close the SOCKET.
use std::os::windows::io::{AsRawSocket, FromRawSocket};
socket2::Socket::from_raw_socket(socket.as_raw_socket())
};

// Actually set the TCP keepalive timeout.
if let Err(e) = socket.set_keepalive(Some(dur)) {
let socket = socket2::SockRef::from(&socket);
let conf = socket2::TcpKeepalive::new().with_time(dur);
if let Err(e) = socket.set_tcp_keepalive(&conf) {
trace!("error trying to set TCP keepalive: {}", e);
}

// Take ownershop of the fd/socket back from the socket2
// `Socket`, so that socket2 doesn't try to close it
// when it's dropped.
#[cfg(unix)]
drop(std::os::unix::io::IntoRawFd::into_raw_fd(socket));
#[cfg(windows)]
drop(std::os::windows::io::IntoRawSocket::into_raw_socket(socket));
}
if let Err(e) = socket.set_nodelay(self.tcp_nodelay) {
trace!("error trying to set TCP nodelay: {}", e);
Expand Down