From 36a1a33b84fe938501b38c93b25b86d19a228167 Mon Sep 17 00:00:00 2001 From: Keith Gable Date: Sat, 23 Sep 2023 21:24:57 -0700 Subject: [PATCH 1/5] Define XRDP_ENABLE_VSOCK when requested in FreeBSD --- configure.ac | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 3e3557db..696b0658 100644 --- a/configure.ac +++ b/configure.ac @@ -407,10 +407,18 @@ fi if test "x$enable_vsock" = "xyes" then enable_vsock=yes - AC_CHECK_HEADERS([linux/socket.h linux/vm_sockets.h], - [AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_VSOCK])], - [], - [#include ]) + if test "x$freebsd" = "xyes" + then + # unconditionally define XRDP_ENABLE_VSOCK because there are no headers + # to check for. AF_HYPERV is present in FreeBSD 13 and may be present in + # earlier versions. + AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_HYPERV]) + else + AC_CHECK_HEADERS([linux/socket.h linux/vm_sockets.h], + [AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_VSOCK])], + [], + [#include ]) + fi fi if test "x$enable_ipv6only" = "xyes" From 572ee7686df9c67659c05473a0ffe7988b9afcd3 Mon Sep 17 00:00:00 2001 From: Keith Gable Date: Sat, 23 Sep 2023 21:28:24 -0700 Subject: [PATCH 2/5] On FreeBSD, use AF_HYPERV in place of vsock --- common/os_calls.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 55 insertions(+) diff --git a/common/os_calls.c b/common/os_calls.c index 68687f95..f6632b98 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -42,7 +42,17 @@ #include #include #if defined(XRDP_ENABLE_VSOCK) +#if defined(__linux__) #include +#elif defined(__FreeBSD__) +// sockaddr_hvs is not available outside the kernel for whatever reason +struct sockaddr_hvs { + unsigned char sa_len; + sa_family_t sa_family; + unsigned int hvs_port; + unsigned char hvs_zero[sizeof(struct sockaddr) - sizeof(sa_family_t) - sizeof(unsigned char) - sizeof(unsigned int)]; +}; +#endif #endif #include #include @@ -124,7 +134,11 @@ union sock_info #endif struct sockaddr_un sa_un; #if defined(XRDP_ENABLE_VSOCK) +#if defined(__linux__) struct sockaddr_vm sa_vm; +#elif defined(__FreeBSD__) + struct sockaddr_hvs sa_hvs; +#endif #endif }; @@ -580,8 +594,15 @@ int g_sck_vsock_socket(void) { #if defined(XRDP_ENABLE_VSOCK) +#if defined(__linux__) + LOG(LOG_LEVEL_DEBUG, "g_sck_vsock_socket: returning Linux vsock socket"); return socket(PF_VSOCK, SOCK_STREAM, 0); +#elif defined(__FreeBSD__) + LOG(LOG_LEVEL_DEBUG, "g_sck_vsock_socket: returning FreeBSD Hyper-V socket"); + return socket(AF_HYPERV, SOCK_STREAM, 0); // docs say to use AF_HYPERV here - PF_HYPERV does not exist +#endif #else + LOG(LOG_LEVEL_DEBUG, "g_sck_vsock_socket: vsock disabled at compile time"); return -1; #endif } @@ -702,6 +723,7 @@ get_peer_description(const union sock_info *sock_info, } #if defined(XRDP_ENABLE_VSOCK) +#if defined(__linux__) case AF_VSOCK: { @@ -713,6 +735,18 @@ get_peer_description(const union sock_info *sock_info, break; } +#elif defined(__FreeBSD__) + + case AF_HYPERV: + { + const struct sockaddr_hvs *sa_hvs = &sock_info->sa_hvs; + + g_snprintf(desc, bytes, "AF_HYPERV:port=%u", sa_hvs->hvs_port); + + break; + } + +#endif #endif default: g_snprintf(desc, bytes, "Unknown address family %d", family); @@ -1034,6 +1068,7 @@ int g_sck_vsock_bind(int sck, const char *port) { #if defined(XRDP_ENABLE_VSOCK) +#if defined(__linux__) struct sockaddr_vm s; g_memset(&s, 0, sizeof(struct sockaddr_vm)); @@ -1042,6 +1077,15 @@ g_sck_vsock_bind(int sck, const char *port) s.svm_cid = VMADDR_CID_ANY; return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_vm)); +#elif defined(__FreeBSD__) + struct sockaddr_hvs s; + + g_memset(&s, 0, sizeof(struct sockaddr_hvs)); + s.sa_family = AF_HYPERV; + s.hvs_port = atoi(port); + + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_hvs)); +#endif #else return -1; #endif @@ -1052,6 +1096,7 @@ int g_sck_vsock_bind_address(int sck, const char *port, const char *address) { #if defined(XRDP_ENABLE_VSOCK) +#if defined(__linux__) struct sockaddr_vm s; g_memset(&s, 0, sizeof(struct sockaddr_vm)); @@ -1060,6 +1105,16 @@ g_sck_vsock_bind_address(int sck, const char *port, const char *address) s.svm_cid = atoi(address); return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_vm)); +#elif defined(__FreeBSD__) + struct sockaddr_hvs s; + + g_memset(&s, 0, sizeof(struct sockaddr_hvs)); + s.sa_family = AF_HYPERV; + s.hvs_port = atoi(port); + // channel/address currently unsupported in FreeBSD 13. + + return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_hvs)); +#endif #else return -1; #endif From 5ffca14b2fadd7b6db1ede89a22a3701126d9057 Mon Sep 17 00:00:00 2001 From: Keith Gable Date: Sun, 24 Sep 2023 12:27:00 -0700 Subject: [PATCH 3/5] Change indent style to allman --- common/os_calls.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/common/os_calls.c b/common/os_calls.c index f6632b98..1bd86a63 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -46,7 +46,8 @@ #include #elif defined(__FreeBSD__) // sockaddr_hvs is not available outside the kernel for whatever reason -struct sockaddr_hvs { +struct sockaddr_hvs +{ unsigned char sa_len; sa_family_t sa_family; unsigned int hvs_port; From 9305008ba8886ad40576124dce06b642445f8eba Mon Sep 17 00:00:00 2001 From: Keith Gable Date: Sun, 24 Sep 2023 12:32:10 -0700 Subject: [PATCH 4/5] Tolerate XRDP_ENABLE_VSOCK being defined but the platform is neither FreeBSD nor Linux --- common/os_calls.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/common/os_calls.c b/common/os_calls.c index 1bd86a63..a58051a5 100644 --- a/common/os_calls.c +++ b/common/os_calls.c @@ -601,6 +601,9 @@ g_sck_vsock_socket(void) #elif defined(__FreeBSD__) LOG(LOG_LEVEL_DEBUG, "g_sck_vsock_socket: returning FreeBSD Hyper-V socket"); return socket(AF_HYPERV, SOCK_STREAM, 0); // docs say to use AF_HYPERV here - PF_HYPERV does not exist +#else + LOG(LOG_LEVEL_DEBUG, "g_sck_vsock_socket: vsock enabled at compile time, but platform is unsupported"); + return -1; #endif #else LOG(LOG_LEVEL_DEBUG, "g_sck_vsock_socket: vsock disabled at compile time"); @@ -1086,6 +1089,8 @@ g_sck_vsock_bind(int sck, const char *port) s.hvs_port = atoi(port); return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_hvs)); +#else + return -1; #endif #else return -1; @@ -1115,6 +1120,8 @@ g_sck_vsock_bind_address(int sck, const char *port, const char *address) // channel/address currently unsupported in FreeBSD 13. return bind(sck, (struct sockaddr *)&s, sizeof(struct sockaddr_hvs)); +#else + return -1; #endif #else return -1; From 6decef6046da91a878a6da691137aca730406d4f Mon Sep 17 00:00:00 2001 From: Keith Gable Date: Sun, 24 Sep 2023 12:52:11 -0700 Subject: [PATCH 5/5] Change vsock to actually check for AF_HYPERV --- configure.ac | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/configure.ac b/configure.ac index 696b0658..414ce3b9 100644 --- a/configure.ac +++ b/configure.ac @@ -409,10 +409,8 @@ then enable_vsock=yes if test "x$freebsd" = "xyes" then - # unconditionally define XRDP_ENABLE_VSOCK because there are no headers - # to check for. AF_HYPERV is present in FreeBSD 13 and may be present in - # earlier versions. - AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_HYPERV]) + # Determine if we have AF_HYPERV defined (FreeBSD 13+) + AC_CHECK_DECL([AF_HYPERV], [AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_HYPERV])], [], [#include ]) else AC_CHECK_HEADERS([linux/socket.h linux/vm_sockets.h], [AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_VSOCK])],