diff --git a/CHANGES b/CHANGES index 125f624..c3cc466 100644 --- a/CHANGES +++ b/CHANGES @@ -13,6 +13,9 @@ Corrections: SOCKET-LISTEN:1:1:'"/tmp/sock"' Test: DALAN_NO_SIGSEGV + The retry option with some address types (TCP) did not close() the + sockets after failed attempts, resulting in an FD leak. + Coding: New Environment variable SOCAT_TRANSFER_WAIT that Socat sleep before starting the data transfer loop. Useful, e.g., to accumulate multiple diff --git a/xio-socket.c b/xio-socket.c index 2783a49..1af7ca7 100644 --- a/xio-socket.c +++ b/xio-socket.c @@ -826,12 +826,14 @@ int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen, if (result < 0) { Msg4(level, "xiopoll({%d,POLLOUT|POLLERR},,{"F_tv_sec"."F_tv_usec"): %s", xfd->fd, timeout.tv_sec, timeout.tv_usec, strerror(errno)); + Close(xfd->fd); return STAT_RETRYLATER; } if (result == 0) { Msg2(level, "connecting to %s: %s", sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), strerror(ETIMEDOUT)); + Close(xfd->fd); return STAT_RETRYLATER; } if (writefd.revents & POLLERR) { @@ -847,6 +849,7 @@ int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen, xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(errno)); #endif + Close(xfd->fd); return STAT_RETRYLATER; } /* otherwise OK or network error */ @@ -854,6 +857,7 @@ int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen, if (result != 0) { Msg2(level, "getsockopt(%d, SOL_SOCKET, SO_ERROR, ...): %s", xfd->fd, strerror(err)); + Close(xfd->fd); return STAT_RETRYLATER; } Debug2("getsockopt(%d, SOL_SOCKET, SO_ERROR, { %d }) -> 0", @@ -862,6 +866,7 @@ int _xioopen_connect(struct single *xfd, union sockaddr_union *us, size_t uslen, Msg4(level, "connect(%d, %s, "F_Zd"): %s", xfd->fd, sockaddr_info(them, themlen, infobuff, sizeof(infobuff)), themlen, strerror(err)); + Close(xfd->fd); return STAT_RETRYLATER; } Fcntl_l(xfd->fd, F_SETFL, fcntl_flags);