Skip to content

Commit

Permalink
Rollup merge of rust-lang#127300 - biabbas:fix_connect_timeout, r=tgr…
Browse files Browse the repository at this point in the history
…oss35

Fix connect timeout for non-linux targets, read readiness of socket connection, Read readiness to detect errors. `Fixes rust-lang#127018`

Fixes rust-lang#127018
Connect_timeout would call `poll` and check `pollfd.revents` for POLLHUP error, rather that checking readiness. This behavior was meant for Linux as it returns POLLHUP | POLLOUT | POLLERR in case of errors. But on targets that do not return POLLHUP in `pollfd.revents`, this would indicate a false success and result in this issue. To resolve this we will check readiness of socket using  `getsockopt():`  and return success from connect_timeout when there are no errors.
Changes were tested on Linux and an rtos.
![Screenshot 2024-07-04 105820](https://github.com/rust-lang/rust/assets/88673422/5ef5a87f-f2af-4fb7-98da-7612d5e27e9a)
Thank you.
  • Loading branch information
matthiaskrgr authored Jul 25, 2024
2 parents 09bda4f + 3a18110 commit 886fe5b
Showing 1 changed file with 19 additions and 10 deletions.
29 changes: 19 additions & 10 deletions std/src/sys/pal/unix/net.rs
Original file line number Diff line number Diff line change
Expand Up @@ -214,16 +214,25 @@ impl Socket {
}
0 => {}
_ => {
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
// for POLLHUP rather than read readiness
if pollfd.revents & libc::POLLHUP != 0 {
let e = self.take_error()?.unwrap_or_else(|| {
io::const_io_error!(
io::ErrorKind::Uncategorized,
"no error set after POLLHUP",
)
});
return Err(e);
if cfg!(target_os = "vxworks") {
// VxWorks poll does not return POLLHUP or POLLERR in revents. Check if the
// connnection actually succeeded and return ok only when the socket is
// ready and no errors were found.
if let Some(e) = self.take_error()? {
return Err(e);
}
} else {
// linux returns POLLOUT|POLLERR|POLLHUP for refused connections (!), so look
// for POLLHUP or POLLERR rather than read readiness
if pollfd.revents & (libc::POLLHUP | libc::POLLERR) != 0 {
let e = self.take_error()?.unwrap_or_else(|| {
io::const_io_error!(
io::ErrorKind::Uncategorized,
"no error set after POLLHUP",
)
});
return Err(e);
}
}

return Ok(());
Expand Down

0 comments on commit 886fe5b

Please sign in to comment.