summaryrefslogtreecommitdiffstats
path: root/common/os_calls.c
diff options
context:
space:
mode:
authorPavel Roskin <plroskin@gmail.com>2016-08-31 11:15:23 -0700
committerPavel Roskin <plroskin@gmail.com>2016-09-08 20:26:19 -0700
commit6f4ffa769c43a4d4bd8c9908fa371371ec4dfd87 (patch)
treedd6210d5d9f71af6bd5eea7343d5bdfa20c174f5 /common/os_calls.c
parentc02f18993a8865c0b58aff1e4a5862b5239c251f (diff)
downloadxrdp-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.c86
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
}