From 983820006889d329d03ad1d5312dbbd6e6ca2ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Moreau?= Date: Wed, 6 Aug 2014 12:08:00 -0400 Subject: [PATCH] libfreerdp-core: fix unix domain socket support --- include/freerdp/server/shadow.h | 1 + libfreerdp/core/tcp.c | 23 +++++++++++++++++------ libfreerdp/core/tcp.h | 1 + server/shadow/shadow_server.c | 19 ++++++++++++++++++- 4 files changed, 37 insertions(+), 7 deletions(-) diff --git a/include/freerdp/server/shadow.h b/include/freerdp/server/shadow.h index 17820b996..3124bdac3 100644 --- a/include/freerdp/server/shadow.h +++ b/include/freerdp/server/shadow.h @@ -97,6 +97,7 @@ struct rdp_shadow_server DWORD port; BOOL mayView; BOOL mayInteract; + char* ipcSocket; char* ConfigPath; char* CertificateFile; char* PrivateKeyFile; diff --git a/libfreerdp/core/tcp.c b/libfreerdp/core/tcp.c index ce76d569e..6cecdca71 100644 --- a/libfreerdp/core/tcp.c +++ b/libfreerdp/core/tcp.c @@ -496,16 +496,21 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) return FALSE; if (hostname[0] == '/') + tcp->ipcSocket = TRUE; + + if (tcp->ipcSocket) { tcp->sockfd = freerdp_uds_connect(hostname); if (tcp->sockfd < 0) return FALSE; - tcp->socketBio = BIO_new_fd(tcp->sockfd, 1); + tcp->socketBio = BIO_new(BIO_s_simple_socket()); if (!tcp->socketBio) return FALSE; + + BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE); } else { @@ -568,7 +573,7 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) tcp->socketBio = BIO_new(BIO_s_simple_socket()); if (!tcp->socketBio) - return -1; + return FALSE; BIO_set_fd(tcp->socketBio, tcp->sockfd, BIO_CLOSE); } @@ -581,8 +586,11 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) option_value = 1; option_len = sizeof(option_value); - if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0) - fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__); + if (!tcp->ipcSocket) + { + if (setsockopt(tcp->sockfd, IPPROTO_TCP, TCP_NODELAY, (void*) &option_value, option_len) < 0) + fprintf(stderr, "%s: unable to set TCP_NODELAY\n", __FUNCTION__); + } /* receive buffer must be a least 32 K */ if (getsockopt(tcp->sockfd, SOL_SOCKET, SO_RCVBUF, (void*) &option_value, &option_len) == 0) @@ -600,8 +608,11 @@ BOOL tcp_connect(rdpTcp* tcp, const char* hostname, int port, int timeout) } } - if (!tcp_set_keep_alive_mode(tcp)) - return FALSE; + if (!tcp->ipcSocket) + { + if (!tcp_set_keep_alive_mode(tcp)) + return FALSE; + } tcp->bufferedBio = BIO_new(BIO_s_buffered_socket()); diff --git a/libfreerdp/core/tcp.h b/libfreerdp/core/tcp.h index 9f65522f3..bfb0f8d00 100644 --- a/libfreerdp/core/tcp.h +++ b/libfreerdp/core/tcp.h @@ -46,6 +46,7 @@ typedef struct rdp_tcp rdpTcp; struct rdp_tcp { int sockfd; + BOOL ipcSocket; char ip_address[32]; BYTE mac_address[6]; rdpSettings* settings; diff --git a/server/shadow/shadow_server.c b/server/shadow/shadow_server.c index d4faaa6b6..cdb290701 100644 --- a/server/shadow/shadow_server.c +++ b/server/shadow/shadow_server.c @@ -51,6 +51,7 @@ extern rdpShadowSubsystem* Win_ShadowCreateSubsystem(rdpShadowServer* server); static COMMAND_LINE_ARGUMENT_A shadow_args[] = { { "port", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Server port" }, + { "ipc-socket", COMMAND_LINE_VALUE_REQUIRED, "", NULL, NULL, -1, NULL, "Server IPC socket" }, { "monitors", COMMAND_LINE_VALUE_OPTIONAL, "<0,1,2...>", NULL, NULL, -1, NULL, "Select or list monitors" }, { "may-view", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may view without prompt" }, { "may-interact", COMMAND_LINE_VALUE_BOOL, NULL, BoolValueTrue, NULL, -1, NULL, "Clients may interact without prompt" }, @@ -175,6 +176,10 @@ int shadow_server_parse_command_line(rdpShadowServer* server, int argc, char** a { server->port = (DWORD) atoi(arg->Value); } + CommandLineSwitchCase(arg, "ipc-socket") + { + server->ipcSocket = _strdup(arg->Value); + } CommandLineSwitchCase(arg, "may-view") { server->mayView = arg->Value ? TRUE : FALSE; @@ -312,6 +317,7 @@ void* shadow_server_thread(rdpShadowServer* server) int shadow_server_start(rdpShadowServer* server) { + BOOL status; WSADATA wsaData; if (WSAStartup(MAKEWORD(2, 2), &wsaData) != 0) @@ -321,7 +327,12 @@ int shadow_server_start(rdpShadowServer* server) signal(SIGPIPE, SIG_IGN); #endif - if (server->listener->Open(server->listener, NULL, (UINT16) server->port)) + if (!server->ipcSocket) + status = server->listener->Open(server->listener, NULL, (UINT16) server->port); + else + status = server->listener->OpenLocal(server->listener, server->ipcSocket); + + if (status) { server->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) shadow_server_thread, (void*) server, 0, NULL); @@ -483,6 +494,12 @@ int shadow_server_uninit(rdpShadowServer* server) server->PrivateKeyFile = NULL; } + if (server->ipcSocket) + { + free(server->ipcSocket); + server->ipcSocket = NULL; + } + return 1; }