Skip to content

Commit

Permalink
On FreeBSD, use AF_HYPERV in place of vsock
Browse files Browse the repository at this point in the history
  • Loading branch information
ziggythehamster committed Sep 24, 2023
1 parent 36a1a33 commit 572ee76
Showing 1 changed file with 55 additions and 0 deletions.
55 changes: 55 additions & 0 deletions common/os_calls.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,17 @@
#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 +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
};

Expand Down Expand Up @@ -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
}
Expand Down Expand Up @@ -702,6 +723,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 +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);
Expand Down Expand Up @@ -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));
Expand All @@ -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
Expand All @@ -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));
Expand All @@ -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
Expand Down

0 comments on commit 572ee76

Please sign in to comment.