diff options
author | Pavel Roskin <plroskin@gmail.com> | 2016-08-31 11:15:23 -0700 |
---|---|---|
committer | Pavel Roskin <plroskin@gmail.com> | 2016-09-08 20:26:19 -0700 |
commit | 6f4ffa769c43a4d4bd8c9908fa371371ec4dfd87 (patch) | |
tree | dd6210d5d9f71af6bd5eea7343d5bdfa20c174f5 /common/os_calls.c | |
parent | c02f18993a8865c0b58aff1e4a5862b5239c251f (diff) | |
download | xrdp-proprietary-6f4ffa769c43a4d4bd8c9908fa371371ec4dfd87.tar.gz xrdp-proprietary-6f4ffa769c43a4d4bd8c9908fa371371ec4dfd87.zip |
Improve debug information when closing a socket
Don't assume AF_INET family. Don't assume the socket is connected. Report
local address and port. Don't try to close non-sockets and invalid file
descriptors. Report errors getting socket information and closing the
socket. Use more appropriate log levels.
Diffstat (limited to 'common/os_calls.c')
-rw-r--r-- | common/os_calls.c | 86 |
1 files changed, 76 insertions, 10 deletions
diff --git a/common/os_calls.c b/common/os_calls.c index c58ebd60..4608f6b0 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -662,19 +662,85 @@ g_sck_get_peer_cred(int sck, int *pid, int *uid, int *gid) void APP_CC g_sck_close(int sck) { - char ip[256]; - - if (sck == 0) - { - return; - } #if defined(_WIN32) closesocket(sck); #else - g_write_ip_address(sck, ip, 255); - log_message(LOG_LEVEL_INFO, "An established connection closed to " - "endpoint: %s", ip); - close(sck); + char sockname[128]; + union + { + struct sockaddr sock_addr; + struct sockaddr_in sock_addr_in; +#if defined(XRDP_ENABLE_IPV6) + struct sockaddr_in6 sock_addr_in6; +#endif + } sock_info; + socklen_t sock_len = sizeof(sock_info); + + memset(&sock_info, 0, sizeof(sock_info)); + + if (getsockname(sck, &sock_info.sock_addr, &sock_len) == 0) + { + switch (sock_info.sock_addr.sa_family) + { + case AF_INET: + { + struct sockaddr_in *sock_addr_in = &sock_info.sock_addr_in; + + g_snprintf(sockname, sizeof(sockname), "AF_INET %s:%d", + inet_ntoa(sock_addr_in->sin_addr), + ntohs(sock_addr_in->sin_port)); + break; + } + +#if defined(XRDP_ENABLE_IPV6) + + case AF_INET6: + { + char addr[48]; + struct sockaddr_in6 *sock_addr_in6 = &sock_info.sock_addr_in6; + + g_snprintf(sockname, sizeof(sockname), "AF_INET6 %s:%d", + inet_ntop(sock_addr_in6->sin6_family, + &sock_addr_in6->sin6_addr, addr, sizeof(addr)), + ntohs(sock_addr_in6->sin6_port)); + break; + } + +#endif + + case AF_UNIX: + g_snprintf(sockname, sizeof(sockname), "AF_UNIX"); + break; + + default: + g_snprintf(sockname, sizeof(sockname), "unknown family %d", + sock_info.sock_addr.sa_family); + break; + } + } + else + { + log_message(LOG_LEVEL_WARNING, "getsockname() failed on socket %d: %s", + sck, strerror(errno)); + + if (errno == EBADF || errno == ENOTSOCK) + { + return; + } + + g_snprintf(sockname, sizeof(sockname), "unknown"); + } + + if (close(sck) == 0) + { + log_message(LOG_LEVEL_DEBUG, "Closed socket %d (%s)", sck, sockname); + } + else + { + log_message(LOG_LEVEL_WARNING, "Cannot close socket %d (%s): %s", sck, + sockname, strerror(errno)); + } + #endif } |