From b39945394dfeb32345ece3f2719adca671ca015c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Revol?= Date: Tue, 24 Sep 2024 15:37:44 +0200 Subject: [PATCH] Fix tcp_ping for non-existent local network hosts Fixes #2042 We can't just assume select() exiting before the timeout to be a success, since connect() can actually tell us there's no route to host or other errors. --- src/read_tcpip.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/read_tcpip.cc b/src/read_tcpip.cc index 0b26edeb7..dccd30106 100644 --- a/src/read_tcpip.cc +++ b/src/read_tcpip.cc @@ -133,10 +133,12 @@ void print_tcp_ping(struct text_object *obj, char *p, unsigned int p_max_size) { if (errno == EINPROGRESS) { // but EINPROGRESS is only a "false fail" gettimeofday(&tv1, nullptr); if (select(sock + 1, nullptr, &writefds, nullptr, &timeout) != -1) { + int ret = 0; + socklen_t len = sizeof(ret); gettimeofday(&tv2, nullptr); usecdiff = ((tv2.tv_sec - tv1.tv_sec) * 1000000) + tv2.tv_usec - tv1.tv_usec; - if (usecdiff <= TCP_PING_TIMEOUT * 1000000) { + if (getsockopt(sock, SOL_SOCKET, SO_ERROR, &ret, &len) == 0 && ret == 0) { snprintf(p, p_max_size, "%llu", (usecdiff / 1000U)); } else { #define TCP_PING_FAILED "down"