From 9405801f6b1b4b6b3e2d7ed984a4310a138205d3 Mon Sep 17 00:00:00 2001 From: DcruBro Date: Fri, 15 May 2026 19:28:21 +0200 Subject: [PATCH] con timeout --- src/main.c | 7 ++++++- src/tcpd/tcpclient.c | 49 +++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 52 insertions(+), 4 deletions(-) diff --git a/src/main.c b/src/main.c index 8a7a255..2df1eee 100644 --- a/src/main.c +++ b/src/main.c @@ -11,6 +11,7 @@ #include #include #include +#include #include @@ -1059,7 +1060,11 @@ int main(int argc, char* argv[]) { } if (Node_ConnectPeer(node, ipStr, LISTEN_PORT) != 0) { - printf("failed to connect to %s:%u\n", ipStr, (unsigned int)LISTEN_PORT); + if (errno == ETIMEDOUT) { + printf("failed to connect to %s:%u (timeout)\n", ipStr, (unsigned int)LISTEN_PORT); + } else { + printf("failed to connect to %s:%u\n", ipStr, (unsigned int)LISTEN_PORT); + } continue; } diff --git a/src/tcpd/tcpclient.c b/src/tcpd/tcpclient.c index fdaa59f..23c6ae0 100644 --- a/src/tcpd/tcpclient.c +++ b/src/tcpd/tcpclient.c @@ -9,6 +9,8 @@ #include #include #include +#include +#include static void* TcpClient_ThreadProc(void* arg) { tcp_client_t* client = (tcp_client_t*)arg; @@ -95,11 +97,52 @@ int TcpClient_Connect( return -1; } - if (connect(sockFd, (struct sockaddr*)&peerAddr, sizeof(peerAddr)) < 0) { - close(sockFd); - return -1; + // Use non-blocking connect with a timeout to avoid long blocking in the CLI. + int flags = fcntl(sockFd, F_GETFL, 0); + if (flags == -1) flags = 0; + fcntl(sockFd, F_SETFL, flags | O_NONBLOCK); + + int rc = connect(sockFd, (struct sockaddr*)&peerAddr, sizeof(peerAddr)); + if (rc < 0) { + if (errno != EINPROGRESS) { + close(sockFd); + return -1; + } + + // Wait up to 5 seconds for the socket to become writable (connected) + struct timeval tv; + tv.tv_sec = 5; + tv.tv_usec = 0; + fd_set wfds; + FD_ZERO(&wfds); + FD_SET(sockFd, &wfds); + int sel = select(sockFd + 1, NULL, &wfds, NULL, &tv); + if (sel <= 0) { + // timeout or error + if (sel == 0) { + errno = ETIMEDOUT; + } + close(sockFd); + return -1; + } + + // Check for socket error + int so_error = 0; + socklen_t len = sizeof(so_error); + if (getsockopt(sockFd, SOL_SOCKET, SO_ERROR, &so_error, &len) < 0) { + close(sockFd); + return -1; + } + if (so_error != 0) { + errno = so_error; + close(sockFd); + return -1; + } } + // Restore blocking mode + fcntl(sockFd, F_SETFL, flags & ~O_NONBLOCK); + tcp_connection_t* conn = (tcp_connection_t*)malloc(sizeof(*conn)); if (!conn) { close(sockFd);