Skip to content
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

Don't ignore EAGAIN in UDS connect call #1564

Merged
merged 3 commits into from
Apr 11, 2022

Conversation

Thomasdezeeuw
Copy link
Collaborator

Per the Linux manual:

EAGAIN For nonblocking UNIX domain sockets, the socket is
nonblocking, and the connection cannot be completed
immediately.

Previously the code incorrectly assumed that the connection was now in
progress, which is incorrect. If that were the case EINPROGRESS
would/should be returned by the OS.

Also documents that connect calls can return a WouldBlock error.
This is a reflect of the Linux manual, which unfortunately doesn't
specify how to determine when the connect call should be retried.

Fixes #1560

@@ -13,7 +13,7 @@ pub(crate) fn connect(path: &Path) -> io::Result<net::UnixStream> {

match syscall!(connect(socket, sockaddr, socklen)) {
Ok(_) => {}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
Err(ref err) if err.raw_os_error() == Some(libc::EINPROGRESS) => {}
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added EINPROGRESS instead because I can't really tell from the macOS manual if they guarantee that EAGAIN is always returned (unlike e.g. Linux).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I can't tell either; that manual isn't great.

@@ -13,7 +13,7 @@ pub(crate) fn connect(path: &Path) -> io::Result<net::UnixStream> {

match syscall!(connect(socket, sockaddr, socklen)) {
Ok(_) => {}
Err(ref e) if e.kind() == io::ErrorKind::WouldBlock => {}
Err(ref err) if err.raw_os_error() == Some(libc::EINPROGRESS) => {}

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately I can't tell either; that manual isn't great.

Per the Linux manual:
> EAGAIN For nonblocking UNIX domain sockets, the socket is
>        nonblocking, and the connection cannot be completed
>        immediately.

Previously the code incorrectly assumed that the connection was now in
progress, which is incorrect. If that were the case EINPROGRESS
would/should be returned by the OS
This is a reflect of the Linux manual, which unfortunately doesn't
specify how to determine when the connect call should be retried.
src/net/uds/stream.rs Outdated Show resolved Hide resolved
@Thomasdezeeuw Thomasdezeeuw merged commit d4cbf76 into tokio-rs:master Apr 11, 2022
@Thomasdezeeuw Thomasdezeeuw deleted the issue#1560 branch April 11, 2022 14:51
@piscisaureus
Copy link
Contributor

Thanks @Thomasdezeeuw !

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

UnixStream::connect() returns unconnected socket on Linux
3 participants