diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2024-07-25 16:48:19 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-07-25 16:48:19 +0200 |
| commit | d1070df553d84d8409f890745a9fdb2eb10cbb64 (patch) | |
| tree | aed0706d1d7fec02764727f1633b4301382a677b | |
| parent | ae71900ef6e68a8b497f9b5ab255977fcfb64d36 (diff) | |
| parent | 17b4fbc388ec11a3c1cdf7e33ff00a0322edaf98 (diff) | |
| download | rust-d1070df553d84d8409f890745a9fdb2eb10cbb64.tar.gz rust-d1070df553d84d8409f890745a9fdb2eb10cbb64.zip | |
Rollup merge of #127300 - biabbas:fix_connect_timeout, r=tgross35
Fix connect timeout for non-linux targets, read readiness of socket connection, Read readiness to detect errors. `Fixes #127018` Fixes #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.  Thank you.
| -rw-r--r-- | library/std/src/sys/pal/unix/net.rs | 29 |
1 files changed, 19 insertions, 10 deletions
diff --git a/library/std/src/sys/pal/unix/net.rs b/library/std/src/sys/pal/unix/net.rs index bedb06043a7..eafde51c608 100644 --- a/library/std/src/sys/pal/unix/net.rs +++ b/library/std/src/sys/pal/unix/net.rs @@ -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(()); |
