diff --git a/src/include/network.h b/src/include/network.h index fca69dbb..0763aa10 100644 --- a/src/include/network.h +++ b/src/include/network.h @@ -157,6 +157,14 @@ pgagroal_socket_nonblocking(int fd, bool value); bool pgagroal_socket_is_nonblocking(int fd); +/** + * Does the socket have an error associated + * @param fd The descriptor + * @return 0 upon success, otherwise 1 + */ +int +pgagroal_socket_has_error(int fd); + #ifdef __cplusplus } #endif diff --git a/src/libpgagroal/network.c b/src/libpgagroal/network.c index 5beb4e0b..b658599f 100644 --- a/src/libpgagroal/network.c +++ b/src/libpgagroal/network.c @@ -463,6 +463,33 @@ pgagroal_socket_is_nonblocking(int fd) return flags & O_NONBLOCK; } +int +pgagroal_socket_has_error(int fd) +{ + int error = 0; + socklen_t length = sizeof(int); + + if (getsockopt(fd, SOL_SOCKET, SO_ERROR, &error, &length) == -1) + { + ZF_LOGV("error getting socket error code: %s (%d)", strerror(errno), fd); + errno = 0; + goto error; + } + + if (error != 0) + { + ZF_LOGV("socket error: %s (%d)", strerror(error), fd); + errno = 0; + goto error; + } + + return 0; + +error: + + return 1; +} + int pgagroal_tcp_nodelay(int fd, void* shmem) { diff --git a/src/libpgagroal/pool.c b/src/libpgagroal/pool.c index 97dac2e8..4b8c5eb5 100644 --- a/src/libpgagroal/pool.c +++ b/src/libpgagroal/pool.c @@ -445,7 +445,10 @@ pgagroal_kill_connection(void* shmem, int slot) if (fd != -1) { pgagroal_management_kill_connection(shmem, slot, fd); - pgagroal_disconnect(fd); + if (!pgagroal_socket_has_error(fd)) + { + pgagroal_disconnect(fd); + } } else {