5726 add vsock support for client and server
This commit is contained in:
parent
b77be28514
commit
52606929fb
@ -2315,7 +2315,13 @@ static int parse_host_options(rdpSettings* settings, const COMMAND_LINE_ARGUMENT
|
||||
/* ipv4 */
|
||||
if (!p)
|
||||
{
|
||||
p = strchr(arg->Value, ':');
|
||||
const char scheme[] = "://";
|
||||
const char* val = strstr(arg->Value, scheme);
|
||||
if (val)
|
||||
val += strnlen(scheme, sizeof(scheme));
|
||||
else
|
||||
val = arg->Value;
|
||||
p = strchr(val, ':');
|
||||
|
||||
if (p)
|
||||
{
|
||||
|
@ -187,4 +187,6 @@
|
||||
#cmakedefine WITH_PROXY_MODULES
|
||||
#cmakedefine WITH_PROXY_EMULATE_SMARTCARD
|
||||
|
||||
#cmakedefine HAVE_AF_VSOCK_H
|
||||
|
||||
#endif /* FREERDP_CONFIG_H */
|
||||
|
@ -18,6 +18,8 @@
|
||||
set(MODULE_NAME "freerdp-core")
|
||||
set(MODULE_PREFIX "FREERDP_CORE")
|
||||
|
||||
CHECK_INCLUDE_FILES("ctype.h;linux/vm_sockets.h" HAVE_AF_VSOCK_H)
|
||||
|
||||
freerdp_definition_add(-DEXT_PATH="${FREERDP_EXTENSION_PATH}")
|
||||
|
||||
freerdp_include_directory_add(${OPENSSL_INCLUDE_DIR})
|
||||
|
@ -40,12 +40,85 @@
|
||||
#include <net/if.h>
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_AF_VSOCK_H)
|
||||
#include <ctype.h>
|
||||
#include <linux/vm_sockets.h>
|
||||
#endif
|
||||
|
||||
#include <winpr/handle.h>
|
||||
|
||||
#include "listener.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define TAG FREERDP_TAG("core.listener")
|
||||
|
||||
static BOOL freerdp_listener_open_from_vsock(freerdp_listener* instance, const char* bind_address,
|
||||
UINT16 port)
|
||||
{
|
||||
#if defined(HAVE_AF_VSOCK_H)
|
||||
rdpListener* listener = (rdpListener*)instance->listener;
|
||||
const int sockfd = socket(AF_VSOCK, SOCK_STREAM, 0);
|
||||
if (sockfd == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "Error creating socket: %s", strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
const int flags = fcntl(sockfd, F_GETFL, 0);
|
||||
if (fcntl(sockfd, F_SETFL, flags | O_NONBLOCK) == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "Error making socket nonblocking: %s", strerror(errno));
|
||||
closesocket((SOCKET)sockfd);
|
||||
return FALSE;
|
||||
}
|
||||
struct sockaddr_vm addr = { 0 };
|
||||
|
||||
addr.svm_family = AF_VSOCK;
|
||||
addr.svm_port = port;
|
||||
|
||||
errno = 0;
|
||||
char* ptr = NULL;
|
||||
unsigned long val = strtoul(bind_address, &ptr, 10);
|
||||
if (errno || (val > UINT32_MAX))
|
||||
{
|
||||
WLog_ERR(TAG, "could not extract port from '%s', value=%ul, error=%s", bind_address, val,
|
||||
strerror(errno));
|
||||
return FALSE;
|
||||
}
|
||||
addr.svm_cid = val;
|
||||
if (bind(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_vm)) == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "Error binding vsock at cid %d port %d: %s", addr.svm_cid, port,
|
||||
strerror(errno));
|
||||
closesocket((SOCKET)sockfd);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (listen(sockfd, 10) == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "Error listening to socket at cid %d port %d: %s", addr.svm_cid, port,
|
||||
strerror(errno));
|
||||
closesocket((SOCKET)sockfd);
|
||||
return FALSE;
|
||||
}
|
||||
listener->sockfds[listener->num_sockfds] = sockfd;
|
||||
listener->events[listener->num_sockfds] = WSACreateEvent();
|
||||
|
||||
if (!listener->events[listener->num_sockfds])
|
||||
{
|
||||
listener->num_sockfds = 0;
|
||||
}
|
||||
|
||||
WSAEventSelect(sockfd, listener->events[listener->num_sockfds], FD_READ | FD_ACCEPT | FD_CLOSE);
|
||||
listener->num_sockfds++;
|
||||
|
||||
WLog_INFO(TAG, "Listening on %s:%d", bind_address, port);
|
||||
return TRUE;
|
||||
#else
|
||||
WLog_ERR(TAG, "compiled without AF_VSOCK, '%s' not supported", bind_address);
|
||||
return FALSE;
|
||||
#endif
|
||||
}
|
||||
|
||||
static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_address, UINT16 port)
|
||||
{
|
||||
int ai_flags = 0;
|
||||
@ -64,6 +137,12 @@ static BOOL freerdp_listener_open(freerdp_listener* instance, const char* bind_a
|
||||
if (!bind_address)
|
||||
ai_flags = AI_PASSIVE;
|
||||
|
||||
if (utils_is_vsock(bind_address))
|
||||
{
|
||||
bind_address = utils_is_vsock(bind_address);
|
||||
return freerdp_listener_open_from_vsock(instance, bind_address, port);
|
||||
}
|
||||
|
||||
res = freerdp_tcp_resolve_host(bind_address, port, ai_flags);
|
||||
|
||||
if (!res)
|
||||
@ -322,7 +401,7 @@ BOOL freerdp_peer_set_local_and_hostname(freerdp_peer* client,
|
||||
}
|
||||
|
||||
#ifndef _WIN32
|
||||
#ifdef AF_VSOCK
|
||||
#if defined(HAVE_AF_VSOCK_H)
|
||||
else if (peer_addr->ss_family == AF_UNIX || peer_addr->ss_family == AF_VSOCK)
|
||||
#else
|
||||
else if (peer_addr->ss_family == AF_UNIX)
|
||||
|
@ -85,6 +85,11 @@
|
||||
#include "tcp.h"
|
||||
#include "../crypto/opensslcompat.h"
|
||||
|
||||
#if defined(HAVE_AF_VSOCK_H)
|
||||
#include <ctype.h>
|
||||
#include <linux/vm_sockets.h>
|
||||
#endif
|
||||
|
||||
#define TAG FREERDP_TAG("core")
|
||||
|
||||
/* Simple Socket BIO */
|
||||
@ -1090,6 +1095,7 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
|
||||
if (hostname[0] == '|')
|
||||
useExternalDefinedSocket = TRUE;
|
||||
|
||||
const char* vsock = utils_is_vsock(hostname);
|
||||
if (ipcSocket)
|
||||
{
|
||||
sockfd = freerdp_uds_connect(hostname);
|
||||
@ -1103,6 +1109,40 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
|
||||
}
|
||||
else if (useExternalDefinedSocket)
|
||||
sockfd = port;
|
||||
else if (vsock)
|
||||
{
|
||||
#if defined(HAVE_AF_VSOCK_H)
|
||||
hostname = vsock;
|
||||
sockfd = socket(AF_VSOCK, SOCK_STREAM, 0);
|
||||
struct sockaddr_vm addr = { 0 };
|
||||
|
||||
addr.svm_family = AF_VSOCK;
|
||||
addr.svm_port = port;
|
||||
|
||||
errno = 0;
|
||||
char* ptr = NULL;
|
||||
unsigned long val = strtoul(hostname, &ptr, 10);
|
||||
if (errno || (val > UINT32_MAX))
|
||||
{
|
||||
WLog_ERR(TAG, "could not extract port from '%s', value=%ul, error=%s", hostname, val,
|
||||
strerror(errno));
|
||||
return -1;
|
||||
}
|
||||
addr.svm_cid = val;
|
||||
if (addr.svm_cid == 2)
|
||||
{
|
||||
addr.svm_flags = VMADDR_FLAG_TO_HOST;
|
||||
}
|
||||
if ((connect(sockfd, (struct sockaddr*)&addr, sizeof(struct sockaddr_vm))) == -1)
|
||||
{
|
||||
WLog_ERR(TAG, "failed to connect to %s", hostname);
|
||||
return -1;
|
||||
}
|
||||
#else
|
||||
WLog_ERR(TAG, "Compiled without AF_VSOCK, '%s' not supported", hostname);
|
||||
return -1;
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
sockfd = -1;
|
||||
@ -1185,18 +1225,21 @@ int freerdp_tcp_default_connect(rdpContext* context, rdpSettings* settings, cons
|
||||
}
|
||||
}
|
||||
|
||||
free(settings->ClientAddress);
|
||||
settings->ClientAddress = freerdp_tcp_get_ip_address(sockfd, &settings->IPv6Enabled);
|
||||
|
||||
if (!settings->ClientAddress)
|
||||
if (!vsock)
|
||||
{
|
||||
if (!useExternalDefinedSocket)
|
||||
close(sockfd);
|
||||
free(settings->ClientAddress);
|
||||
settings->ClientAddress = freerdp_tcp_get_ip_address(sockfd, &settings->IPv6Enabled);
|
||||
|
||||
freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
|
||||
if (!settings->ClientAddress)
|
||||
{
|
||||
if (!useExternalDefinedSocket)
|
||||
close(sockfd);
|
||||
|
||||
WLog_ERR(TAG, "Couldn't get socket ip address");
|
||||
return -1;
|
||||
freerdp_set_last_error_if_not(context, FREERDP_ERROR_CONNECT_FAILED);
|
||||
|
||||
WLog_ERR(TAG, "Couldn't get socket ip address");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
optval = 1;
|
||||
|
@ -288,3 +288,14 @@ BOOL utils_abort_event_is_set(rdpRdp* rdp)
|
||||
status = WaitForSingleObject(rdp->abortEvent, 0);
|
||||
return status == WAIT_OBJECT_0;
|
||||
}
|
||||
|
||||
const char* utils_is_vsock(const char* hostname)
|
||||
{
|
||||
if (!hostname)
|
||||
return NULL;
|
||||
|
||||
const char vsock[8] = "vsock://";
|
||||
if (strncmp(hostname, vsock, sizeof(vsock)) == 0)
|
||||
return &hostname[sizeof(vsock)];
|
||||
return NULL;
|
||||
}
|
||||
|
@ -45,4 +45,6 @@ BOOL utils_sync_credentials(rdpSettings* settings, BOOL toGateway);
|
||||
BOOL utils_str_is_empty(const char* str);
|
||||
BOOL utils_str_copy(const char* value, char** dst);
|
||||
|
||||
const char* utils_is_vsock(const char* hostname);
|
||||
|
||||
#endif /* FREERDP_LIB_CORE_UTILS_H */
|
||||
|
Loading…
Reference in New Issue
Block a user