Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement vsock support for FreeBSD #2798

Merged
merged 5 commits into from
Sep 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
63 changes: 63 additions & 0 deletions common/os_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,18 @@
#include <netinet/tcp.h>
#include <sys/socket.h>
#if defined(XRDP_ENABLE_VSOCK)
#if defined(__linux__)
#include <linux/vm_sockets.h>
#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 <poll.h>
#include <sys/un.h>
Expand Down Expand Up @@ -124,7 +135,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
};

Expand Down Expand Up @@ -580,8 +595,18 @@ 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
#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");
return -1;
#endif
}
Expand Down Expand Up @@ -702,6 +727,7 @@ get_peer_description(const union sock_info *sock_info,
}

#if defined(XRDP_ENABLE_VSOCK)
#if defined(__linux__)

case AF_VSOCK:
{
Expand All @@ -713,6 +739,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);
Expand Down Expand Up @@ -1034,6 +1072,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));
Expand All @@ -1042,6 +1081,17 @@ 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));
#else
return -1;
#endif
#else
return -1;
#endif
Expand All @@ -1052,6 +1102,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));
Expand All @@ -1060,6 +1111,18 @@ 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));
#else
return -1;
#endif
#else
return -1;
#endif
Expand Down
14 changes: 10 additions & 4 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -407,10 +407,16 @@ 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 <sys/socket.h>])
if test "x$freebsd" = "xyes"
then
# Determine if we have AF_HYPERV defined (FreeBSD 13+)
AC_CHECK_DECL([AF_HYPERV], [AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_HYPERV])], [], [#include <sys/socket.h>])
else
AC_CHECK_HEADERS([linux/socket.h linux/vm_sockets.h],
[AC_DEFINE([XRDP_ENABLE_VSOCK], 1, [Enable AF_VSOCK])],
[],
[#include <sys/socket.h>])
fi
fi

if test "x$enable_ipv6only" = "xyes"
Expand Down