diff --git a/docs/reference/gio/gio-docs.xml b/docs/reference/gio/gio-docs.xml
index 9cd3d0e39f28e446269a070a8ac2f765a1191cc0..ec1e48bb5ac08e87654a14a92ab803e8c7738a28 100644
--- a/docs/reference/gio/gio-docs.xml
+++ b/docs/reference/gio/gio-docs.xml
@@ -122,6 +122,7 @@
+
@@ -139,6 +140,7 @@
+
diff --git a/docs/reference/gio/gio-sections-common.txt b/docs/reference/gio/gio-sections-common.txt
index 945c26adeaad6d566039bb2cbb8b931e4b1fb19a..5d46c25e667c72e8a767781bb948a7a948e1afad 100644
--- a/docs/reference/gio/gio-sections-common.txt
+++ b/docs/reference/gio/gio-sections-common.txt
@@ -1880,6 +1880,27 @@ G_TYPE_NATIVE_SOCKET_ADDRESS_TYPE
g_native_socket_address_get_type
+
+gvsocksocketaddress
+GVsockSocketAddress
+GVsockSocketAddress
+g_vsock_socket_address_new
+g_vsock_socket_address_get_cid
+g_vsock_socket_address_get_port
+
+GVsockSocketAddressClass
+GVsockSocketAddressPrivate
+G_IS_VSOCK_SOCKET_ADDRESS
+G_IS_VSOCK_SOCKET_ADDRESS_CLASS
+G_TYPE_VSOCK_SOCKET_ADDRESS
+G_VSOCK_SOCKET_ADDRESS
+G_VSOCK_SOCKET_ADDRESS_CLASS
+G_VSOCK_SOCKET_ADDRESS_GET_CLASS
+G_TYPE_VSOCK_SOCKET_ADDRESS_TYPE
+
+g_vsock_socket_address_get_type
+
+
gresolver
GResolver
@@ -2266,6 +2287,24 @@ GUnixConnectionPrivate
g_unix_connection_get_type
+
+gvsockconnection
+GVsockConnection
+GVsockConnection
+
+GVsockConnectionClass
+G_IS_VSOCK_CONNECTION
+G_IS_VSOCK_CONNECTION_CLASS
+G_TYPE_VSOCK_CONNECTION
+G_VSOCK_CONNECTION
+G_VSOCK_CONNECTION_CLASS
+G_VSOCK_CONNECTION_GET_CLASS
+
+GVsockConnectionPrivate
+g_vsock_connection_get_type
+
+
+GUnixConnection
gtcpconnection
GTcpConnection
diff --git a/docs/reference/glib/glib-sections.txt b/docs/reference/glib/glib-sections.txt
index d20f419afabb5e653353e9ed41a4fe9e80c46f7e..fb31280930ccf44694ec5e46ba465ca4f2444d9e 100644
--- a/docs/reference/glib/glib-sections.txt
+++ b/docs/reference/glib/glib-sections.txt
@@ -922,6 +922,7 @@ GLIB_SYSDEF_POLLPRI
GLIB_SYSDEF_AF_INET
GLIB_SYSDEF_AF_INET6
GLIB_SYSDEF_AF_UNIX
+GLIB_SYSDEF_AF_VSOCK
GLIB_SYSDEF_MSG_DONTROUTE
GLIB_SYSDEF_MSG_OOB
GLIB_SYSDEF_MSG_PEEK
diff --git a/gio/gdbusaddress.c b/gio/gdbusaddress.c
index d26c4d25f1f4bc9ebc818d287e9d4895adc7c0f7..a28b46e97b6435a57ea396672bf7bef52df9d2c4 100644
--- a/gio/gdbusaddress.c
+++ b/gio/gdbusaddress.c
@@ -46,6 +46,10 @@
#include
#include
#endif
+#ifdef HAVE_VSOCK
+#include
+#include
+#endif
#ifdef G_OS_WIN32
#include
@@ -191,6 +195,80 @@ is_valid_unix (const gchar *address_entry,
return ret;
}
+#ifdef HAVE_VSOCK
+static gboolean
+is_valid_vsock (const gchar *address_entry,
+ GHashTable *key_value_pairs,
+ GError **error)
+{
+ gboolean ret;
+ GList *keys;
+ GList *l;
+ const gchar *cid;
+ const gchar *port;
+ gchar *endp;
+
+ ret = FALSE;
+ cid = NULL;
+ port = NULL;
+
+ keys = g_hash_table_get_keys (key_value_pairs);
+ for (l = keys; l != NULL; l = l->next)
+ {
+ const gchar *key = l->data;
+ if (g_strcmp0 (key, "cid") == 0)
+ cid = g_hash_table_lookup (key_value_pairs, key);
+ else if (g_strcmp0 (key, "port") == 0)
+ port = g_hash_table_lookup (key_value_pairs, key);
+ else if (g_strcmp0 (key, "guid") != 0)
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Unsupported key “%s” in address entry “%s”"),
+ key,
+ address_entry);
+ goto out;
+ }
+ }
+
+ if (port != NULL)
+ {
+ strtoul (port, &endp, 10);
+ if ((*port == '\0' || *endp != '\0'))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Error in address “%s” — the “%s” attribute is malformed"),
+ address_entry, "port");
+ goto out;
+ }
+ }
+
+ if (cid != NULL)
+ {
+ strtoul (port, &endp, 10);
+ if ((*port == '\0' || *endp != '\0'))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Error in address “%s” — the “%s” attribute is malformed"),
+ address_entry, "cid");
+ goto out;
+ }
+ }
+
+ ret = TRUE;
+
+ out:
+ g_list_free (keys);
+
+ return ret;
+}
+#endif
+
static gboolean
is_valid_nonce_tcp (const gchar *address_entry,
GHashTable *key_value_pairs,
@@ -413,6 +491,10 @@ g_dbus_is_supported_address (const gchar *string,
supported = is_valid_nonce_tcp (a[n], key_value_pairs, error);
else if (g_strcmp0 (a[n], "autolaunch:") == 0)
supported = TRUE;
+#ifdef HAVE_VSOCK
+ else if (g_strcmp0 (transport_name, "vsock") == 0)
+ supported = is_valid_vsock (a[n], key_value_pairs, error);
+#endif
else
g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
_("Unknown or unsupported transport “%s” for address “%s”"),
@@ -605,6 +687,45 @@ g_dbus_address_connect (const gchar *address_entry,
g_assert_not_reached ();
}
}
+#endif
+#ifdef HAVE_VSOCK
+ else if (g_strcmp0 (transport_name, "vsock") == 0)
+ {
+ const gchar *s;
+ struct sockaddr_vm svm;
+ gchar *endp;
+
+ memset (&svm, 0, sizeof (svm));
+ svm.svm_family = AF_VSOCK;
+
+ s = g_hash_table_lookup (key_value_pairs, "cid");
+ if (s != NULL)
+ svm.svm_cid = strtoul (s, &endp, 10);
+ if (s == NULL || (*s == '\0' || *endp != '\0'))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Error in address “%s” — the cid attribute is missing or malformed"),
+ address_entry);
+ goto out;
+ }
+
+ s = g_hash_table_lookup (key_value_pairs, "port");
+ if (s != NULL)
+ svm.svm_port = strtoul (s, &endp, 10);
+ if (s == NULL || (*s == '\0' || *endp != '\0'))
+ {
+ g_set_error (error,
+ G_IO_ERROR,
+ G_IO_ERROR_INVALID_ARGUMENT,
+ _("Error in address “%s” — the port attribute is missing or malformed"),
+ address_entry);
+ goto out;
+ }
+
+ connectable = G_SOCKET_CONNECTABLE (g_socket_address_new_from_native (&svm, sizeof (svm)));
+ }
#endif
else if (g_strcmp0 (transport_name, "tcp") == 0 || g_strcmp0 (transport_name, "nonce-tcp") == 0)
{
diff --git a/gio/gdbusserver.c b/gio/gdbusserver.c
index 9009734d521d7ed763874e4b42a37193a2239cf1..7e37ae03db08f1e614daf1421b4b40994a6109b1 100644
--- a/gio/gdbusserver.c
+++ b/gio/gdbusserver.c
@@ -54,6 +54,10 @@
#ifdef G_OS_UNIX
#include "gunixsocketaddress.h"
#endif
+#ifdef HAVE_VSOCK
+#include
+#include
+#endif
#include "glibintl.h"
@@ -813,6 +817,63 @@ try_unix (GDBusServer *server,
}
#endif
+#ifdef HAVE_VSOCK
+/* note that address_entry has already been validated */
+static gboolean
+try_vsock (GDBusServer *server,
+ const gchar *address_entry,
+ GHashTable *key_value_pairs,
+ GError **error)
+{
+ GSocketAddress *socket_address;
+ GSocketAddress *effective_address;
+ gboolean ret;
+ struct sockaddr_vm svm;
+ const gchar *cid;
+ const gchar *port;
+
+ ret = FALSE;
+
+ cid = g_hash_table_lookup (key_value_pairs, "cid");
+ port = g_hash_table_lookup (key_value_pairs, "port");
+
+ memset (&svm, 0, sizeof (svm));
+ svm.svm_family = AF_VSOCK;
+ svm.svm_cid = VMADDR_CID_LOCAL;
+ if (cid != NULL)
+ svm.svm_cid = strtoul (cid, NULL, 10);
+ svm.svm_port = VMADDR_PORT_ANY;
+ if (port != NULL)
+ svm.svm_port = strtoul (port, NULL, 10);
+
+ socket_address = g_socket_address_new_from_native (&svm, sizeof (svm));
+ if (!g_socket_listener_add_address (server->listener,
+ socket_address,
+ G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_DEFAULT,
+ NULL, /* GObject *source_object */
+ &effective_address,
+ error))
+ {
+ g_object_unref (socket_address);
+ goto out;
+ }
+
+ if (svm.svm_port == VMADDR_PORT_ANY)
+ svm.svm_port = g_vsock_socket_address_get_port (G_VSOCK_SOCKET_ADDRESS (effective_address));
+
+ g_object_unref (effective_address);
+ g_object_unref (socket_address);
+
+ server->client_address = g_strdup_printf ("vsock:cid=%u,port=%u", svm.svm_cid, svm.svm_port);
+ server->is_using_listener = TRUE;
+ ret = TRUE;
+
+ out:
+ return ret;
+}
+#endif
+
/* ---------------------------------------------------------------------------------------------------- */
/* note that address_entry has already been validated =>
@@ -1131,6 +1192,10 @@ initable_init (GInitable *initable,
#ifdef G_OS_UNIX
else if (g_strcmp0 (transport_name, "unix") == 0)
ret = try_unix (server, address_entry, key_value_pairs, &this_error);
+#endif
+#ifdef HAVE_VSOCK
+ else if (g_strcmp0 (transport_name, "vsock") == 0)
+ ret = try_vsock (server, address_entry, key_value_pairs, &this_error);
#endif
else if (g_strcmp0 (transport_name, "tcp") == 0)
ret = try_tcp (server, address_entry, key_value_pairs, FALSE, &this_error);
diff --git a/gio/gio.h b/gio/gio.h
index f5d2dd5a36a4cbbbd255160bba2b770e17554617..f8b745428e4d03391e620c5b6fdc88e3e9f53123 100644
--- a/gio/gio.h
+++ b/gio/gio.h
@@ -167,6 +167,8 @@
#include
#include
#include
+#include
+#include
#include
#include
diff --git a/gio/gioenums.h b/gio/gioenums.h
index 2692b746d72052e680841347ecce76c0d1201984..8efaef32d48d3b87dcf378cbd50d85dd2f7ced97 100644
--- a/gio/gioenums.h
+++ b/gio/gioenums.h
@@ -507,6 +507,7 @@ typedef enum {
* value, which has this more logical name. Since 2.44.
* @G_IO_ERROR_NOT_CONNECTED: Transport endpoint is not connected. Since 2.44
* @G_IO_ERROR_MESSAGE_TOO_LARGE: Message too large. Since 2.48.
+ * @G_IO_ERROR_ADDRESS_NOT_AVAILABLE: Cannot assign requested address. Since 2.68.
*
* Error codes returned by GIO functions.
*
@@ -575,7 +576,8 @@ typedef enum {
G_IO_ERROR_BROKEN_PIPE,
G_IO_ERROR_CONNECTION_CLOSED = G_IO_ERROR_BROKEN_PIPE,
G_IO_ERROR_NOT_CONNECTED,
- G_IO_ERROR_MESSAGE_TOO_LARGE
+ G_IO_ERROR_MESSAGE_TOO_LARGE,
+ G_IO_ERROR_ADDRESS_NOT_AVAILABLE
} GIOErrorEnum;
@@ -812,10 +814,11 @@ typedef enum /*< flags >*/ {
* @G_SOCKET_FAMILY_IPV4: the IPv4 family
* @G_SOCKET_FAMILY_IPV6: the IPv6 family
* @G_SOCKET_FAMILY_UNIX: the UNIX domain family
+ * @G_SOCKET_FAMILY_VSOCK: the VSOCK domain family. Since: 2.68
*
* The protocol family of a #GSocketAddress. (These values are
- * identical to the system defines %AF_INET, %AF_INET6 and %AF_UNIX,
- * if available.)
+ * identical to the system defines %AF_INET, %AF_INET6, %AF_UNIX,
+ * and %AF_VSOCK if available.)
*
* Since: 2.22
*/
@@ -823,7 +826,8 @@ typedef enum {
G_SOCKET_FAMILY_INVALID,
G_SOCKET_FAMILY_UNIX = GLIB_SYSDEF_AF_UNIX,
G_SOCKET_FAMILY_IPV4 = GLIB_SYSDEF_AF_INET,
- G_SOCKET_FAMILY_IPV6 = GLIB_SYSDEF_AF_INET6
+ G_SOCKET_FAMILY_IPV6 = GLIB_SYSDEF_AF_INET6,
+ G_SOCKET_FAMILY_VSOCK = GLIB_SYSDEF_AF_VSOCK
} GSocketFamily;
/**
diff --git a/gio/gioerror.c b/gio/gioerror.c
index 477906c0c606b85e8e670d251dd5a3f14fc3f8c1..120c234ff3dc28b3bd1ce7ccae2324eac5d50a8b 100644
--- a/gio/gioerror.c
+++ b/gio/gioerror.c
@@ -278,6 +278,12 @@ g_io_error_from_errno (gint err_no)
break;
#endif
+#ifdef EADDRNOTAVAIL
+ case EADDRNOTAVAIL:
+ return G_IO_ERROR_ADDRESS_NOT_AVAILABLE;
+ break;
+#endif
+
default:
return G_IO_ERROR_FAILED;
break;
@@ -366,6 +372,11 @@ g_io_error_from_win32_error (gint error_code)
case WSAEMSGSIZE:
return G_IO_ERROR_MESSAGE_TOO_LARGE;
+#ifdef WSAEADDRNOTAVAIL
+ case WSAEADDRNOTAVAIL:
+ return G_IO_ERROR_ADDRESS_NOT_AVAILABLE;
+#endif
+
default:
return G_IO_ERROR_FAILED;
}
diff --git a/gio/giotypes.h b/gio/giotypes.h
index 995c9cb152aeefb76a07eb520ab869d1c4badf89..d7f0a67d3d2d4cdb49127f537c45eb49848fa7dc 100644
--- a/gio/giotypes.h
+++ b/gio/giotypes.h
@@ -105,6 +105,7 @@ typedef struct _GInetAddress GInetAddress;
typedef struct _GInetAddressMask GInetAddressMask;
typedef struct _GInetSocketAddress GInetSocketAddress;
typedef struct _GNativeSocketAddress GNativeSocketAddress;
+typedef struct _GVsockSocketAddress GVsockSocketAddress;
typedef struct _GInputStream GInputStream;
typedef struct _GInitable GInitable;
typedef struct _GIOModule GIOModule;
diff --git a/gio/gnetworkaddress.c b/gio/gnetworkaddress.c
index ef1940a920083b9e7a0a6ca8617e4cc956e078be..baf1d5e2afafa99de7615ed3d14aee7025735507 100644
--- a/gio/gnetworkaddress.c
+++ b/gio/gnetworkaddress.c
@@ -702,6 +702,7 @@ list_split_families (GList *list,
break;
case G_SOCKET_FAMILY_INVALID:
case G_SOCKET_FAMILY_UNIX:
+ case G_SOCKET_FAMILY_VSOCK:
g_assert_not_reached ();
}
diff --git a/gio/gsocket.c b/gio/gsocket.c
index 52a198378ca83f73ff028f11ab3232a3d39cf539..c0252b578159552ceadf24be5dc7fd110ff9c89c 100644
--- a/gio/gsocket.c
+++ b/gio/gsocket.c
@@ -540,8 +540,9 @@ g_socket_details_from_fd (GSocket *socket)
}
break;
+ case G_SOCKET_FAMILY_VSOCK:
case G_SOCKET_FAMILY_UNIX:
- socket->priv->family = G_SOCKET_FAMILY_UNIX;
+ socket->priv->family = family;
socket->priv->protocol = G_SOCKET_PROTOCOL_DEFAULT;
break;
diff --git a/gio/gsocketaddress.c b/gio/gsocketaddress.c
index 2b7e83ccf98a2aae5e3087fd8d545542280335a3..5fbc5ef3675e4bb84d558608a01567b9c6cacff9 100644
--- a/gio/gsocketaddress.c
+++ b/gio/gsocketaddress.c
@@ -27,6 +27,7 @@
#include "ginetaddress.h"
#include "ginetsocketaddress.h"
#include "gnativesocketaddress.h"
+#include "gvsocksocketaddress.h"
#include "gnetworkingprivate.h"
#include "gproxyaddress.h"
#include "gproxyaddressenumerator.h"
@@ -39,6 +40,10 @@
#include "gunixsocketaddress.h"
#endif
+#ifdef HAVE_VSOCK
+#include
+#endif
+
/**
* SECTION:gsocketaddress
@@ -300,6 +305,14 @@ g_socket_address_new_from_native (gpointer native,
return g_unix_socket_address_new (addr->sun_path);
}
#endif
+#ifdef HAVE_VSOCK
+ if (family == AF_VSOCK)
+ {
+ struct sockaddr_vm *addr = (struct sockaddr_vm *) native;
+
+ return g_vsock_socket_address_new (addr->svm_cid, addr->svm_port);
+ }
+#endif
return g_native_socket_address_new (native, len);
}
diff --git a/gio/gsocketconnection.c b/gio/gsocketconnection.c
index 37d5d330cf4ca9e0cab7210565727705c8b2bac9..36c4d3ee4c5fe190b58b5fe82da63fce5401b04f 100644
--- a/gio/gsocketconnection.c
+++ b/gio/gsocketconnection.c
@@ -34,6 +34,7 @@
#include
#include "gunixconnection.h"
#include "gtcpconnection.h"
+#include "gvsockconnection.h"
#include "glibintl.h"
@@ -615,6 +616,9 @@ g_socket_connection_factory_register_type (GType g_type,
static void
init_builtin_types (void)
{
+#ifdef HAVE_VSOCK
+ g_type_ensure (G_TYPE_VSOCK_CONNECTION);
+#endif
#ifndef G_OS_WIN32
g_type_ensure (G_TYPE_UNIX_CONNECTION);
#endif
diff --git a/gio/gvsockconnection.c b/gio/gvsockconnection.c
new file mode 100644
index 0000000000000000000000000000000000000000..3db53cce0989f88dea9f12d553414b615c2b460a
--- /dev/null
+++ b/gio/gvsockconnection.c
@@ -0,0 +1,55 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ *
+ * Authors: Marc-André Lureau
+ */
+
+#include "config.h"
+
+#include "gvsockconnection.h"
+
+/**
+ * SECTION:gvsockconnection
+ * @title: GVsockConnection
+ * @short_description: A VSOCK domain GSocketConnection
+ * @include: gio/gvsockconnection.h
+ * @see_also: #GSocketConnection.
+ *
+ * This is the subclass of #GSocketConnection that is created
+ * for VSOCK domain sockets.
+ *
+ * Since: 2.68
+ */
+
+/**
+ * GVsockConnection:
+ *
+ * #GVsockConnection is an opaque data structure.
+ **/
+
+G_DEFINE_TYPE_WITH_CODE (GVsockConnection,
+ g_vsock_connection,
+ G_TYPE_SOCKET_CONNECTION,
+ g_socket_connection_factory_register_type (g_define_type_id,
+ G_SOCKET_FAMILY_VSOCK,
+ G_SOCKET_TYPE_STREAM,
+ G_SOCKET_PROTOCOL_DEFAULT);
+);
+
+static void
+g_vsock_connection_init (GVsockConnection *connection)
+{
+}
+
+static void
+g_vsock_connection_class_init (GVsockConnectionClass *class)
+{
+}
diff --git a/gio/gvsockconnection.h b/gio/gvsockconnection.h
new file mode 100644
index 0000000000000000000000000000000000000000..32dd9fc120ae2e69e95fe87c9926b64ebc1148a2
--- /dev/null
+++ b/gio/gvsockconnection.h
@@ -0,0 +1,63 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright © 2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see .
+ *
+ * Authors: Marc-André Lureau
+ */
+
+#ifndef __G_VSOCK_CONNECTION_H__
+#define __G_VSOCK_CONNECTION_H__
+
+#include
+
+G_BEGIN_DECLS
+
+#define G_TYPE_VSOCK_CONNECTION (g_vsock_connection_get_type ())
+#define G_VSOCK_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_CAST ((inst), \
+ G_TYPE_VSOCK_CONNECTION, GVsockConnection))
+#define G_VSOCK_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_CAST ((class), \
+ G_TYPE_VSOCK_CONNECTION, GVsockConnectionClass))
+#define G_IS_VSOCK_CONNECTION(inst) (G_TYPE_CHECK_INSTANCE_TYPE ((inst), \
+ G_TYPE_VSOCK_CONNECTION))
+#define G_IS_VSOCK_CONNECTION_CLASS(class) (G_TYPE_CHECK_CLASS_TYPE ((class), \
+ G_TYPE_VSOCK_CONNECTION))
+#define G_VSOCK_CONNECTION_GET_CLASS(inst) (G_TYPE_INSTANCE_GET_CLASS ((inst), \
+ G_TYPE_VSOCK_CONNECTION, GVsockConnectionClass))
+
+typedef struct _GVsockConnection GVsockConnection;
+typedef struct _GVsockConnectionPrivate GVsockConnectionPrivate;
+typedef struct _GVsockConnectionClass GVsockConnectionClass;
+
+G_DEFINE_AUTOPTR_CLEANUP_FUNC(GVsockConnection, g_object_unref)
+
+struct _GVsockConnectionClass
+{
+ GSocketConnectionClass parent_class;
+};
+
+struct _GVsockConnection
+{
+ GSocketConnection parent_instance;
+ GVsockConnectionPrivate *priv;
+};
+
+GLIB_AVAILABLE_IN_2_68
+GType g_vsock_connection_get_type (void);
+
+
+G_END_DECLS
+
+#endif /* __G_VSOCK_CONNECTION_H__ */
diff --git a/gio/gvsocksocketaddress.c b/gio/gvsocksocketaddress.c
new file mode 100644
index 0000000000000000000000000000000000000000..78155b892fa860fe706ac5c9aad919eb0c550e6a
--- /dev/null
+++ b/gio/gvsocksocketaddress.c
@@ -0,0 +1,300 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see .
+ *
+ * Authors: Marc-André Lureau
+ */
+
+#include
+#include
+#include
+
+#include "gvsocksocketaddress.h"
+#include "gnetworkingprivate.h"
+#include "gsocketconnectable.h"
+#include "gioerror.h"
+#include "glibintl.h"
+
+#ifdef HAVE_VSOCK
+#include
+#endif
+
+/**
+ * SECTION:gvsocksocketaddress
+ * @short_description: VSOCK GSocketAddress
+ * @include: gio/gio.h
+ *
+ * An VSOCK socket address; that is, the combination of a Context Identifier
+ * (CID) and a port number.
+ */
+
+/**
+ * GVsockSocketAddress:
+ *
+ * A VSOCK socket address, corresponding to a struct sockaddr_vm.
+ *
+ * Since: 2.68
+ */
+
+struct _GVsockSocketAddressPrivate
+{
+ guint cid;
+ guint port;
+};
+
+static void g_vsock_socket_address_connectable_iface_init (GSocketConnectableIface *iface);
+static gchar *g_vsock_socket_address_connectable_to_string (GSocketConnectable *connectable);
+
+G_DEFINE_TYPE_WITH_CODE (GVsockSocketAddress, g_vsock_socket_address, G_TYPE_SOCKET_ADDRESS,
+ G_ADD_PRIVATE (GVsockSocketAddress)
+ G_IMPLEMENT_INTERFACE (G_TYPE_SOCKET_CONNECTABLE,
+ g_vsock_socket_address_connectable_iface_init))
+
+enum {
+ PROP_0,
+ PROP_CID,
+ PROP_PORT,
+};
+
+static void
+g_vsock_socket_address_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ GVsockSocketAddress *address = G_VSOCK_SOCKET_ADDRESS (object);
+
+ switch (prop_id)
+ {
+ case PROP_CID:
+ g_value_set_uint (value, address->priv->cid);
+ break;
+
+ case PROP_PORT:
+ g_value_set_uint (value, address->priv->port);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+g_vsock_socket_address_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ GVsockSocketAddress *address = G_VSOCK_SOCKET_ADDRESS (object);
+
+ switch (prop_id)
+ {
+ case PROP_CID:
+ address->priv->cid = g_value_get_uint (value);
+ break;
+
+ case PROP_PORT:
+ address->priv->port = g_value_get_uint (value);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static GSocketFamily
+g_vsock_socket_address_get_family (GSocketAddress *address)
+{
+ g_return_val_if_fail (G_IS_VSOCK_SOCKET_ADDRESS (address), 0);
+
+ return G_SOCKET_FAMILY_VSOCK;
+}
+
+static gssize
+g_vsock_socket_address_get_native_size (GSocketAddress *address)
+{
+#ifdef HAVE_VSOCK
+ g_return_val_if_fail (G_IS_VSOCK_SOCKET_ADDRESS (address), 0);
+
+ return sizeof (struct sockaddr_vm);
+#else
+ g_warning_once ("VSOCK is not supported on this platform yet.");
+ return -1;
+#endif
+}
+
+static gboolean
+g_vsock_socket_address_to_native (GSocketAddress *address,
+ gpointer dest,
+ gsize destlen,
+ GError **error)
+{
+#ifdef HAVE_VSOCK
+ GVsockSocketAddress *addr;
+ struct sockaddr_vm *sock = (struct sockaddr_vm *) dest;
+
+ g_return_val_if_fail (G_IS_VSOCK_SOCKET_ADDRESS (address), FALSE);
+
+ addr = G_VSOCK_SOCKET_ADDRESS (address);
+ if (destlen < sizeof (*sock))
+ {
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NO_SPACE,
+ _("Not enough space for socket address"));
+ return FALSE;
+ }
+
+ memset (sock, 0, sizeof (*sock));
+ sock->svm_family = AF_VSOCK;
+ sock->svm_cid = addr->priv->cid;
+ sock->svm_port = addr->priv->port;
+ return TRUE;
+#else
+ g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
+ _("VSOCK is not support for this platform yet."));
+ return FALSE;
+#endif
+}
+
+static void
+g_vsock_socket_address_class_init (GVsockSocketAddressClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GSocketAddressClass *gsocketaddress_class = G_SOCKET_ADDRESS_CLASS (klass);
+
+ gobject_class->set_property = g_vsock_socket_address_set_property;
+ gobject_class->get_property = g_vsock_socket_address_get_property;
+
+ gsocketaddress_class->get_family = g_vsock_socket_address_get_family;
+ gsocketaddress_class->to_native = g_vsock_socket_address_to_native;
+ gsocketaddress_class->get_native_size = g_vsock_socket_address_get_native_size;
+
+ /**
+ * GVsockSocketAddress:cid:
+ *
+ * The `svm_cid` field, for VSOCK addresses.
+ *
+ * Since: 2.68
+ */
+ g_object_class_install_property (gobject_class, PROP_CID,
+ g_param_spec_uint ("cid",
+ P_("CID"),
+ P_("The Context Identifier (CID)"),
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
+ * GVsockSocketAddress:port:
+ *
+ * The `svm_port` field, for VSOCK addresses.
+ *
+ * Since: 2.68
+ */
+ g_object_class_install_property (gobject_class, PROP_PORT,
+ g_param_spec_uint ("port",
+ P_("Port"),
+ P_("The port"),
+ 0,
+ G_MAXUINT,
+ 0,
+ G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+}
+
+static void
+g_vsock_socket_address_connectable_iface_init (GSocketConnectableIface *iface)
+{
+ GSocketConnectableIface *parent_iface = g_type_interface_peek_parent (iface);
+
+ iface->enumerate = parent_iface->enumerate;
+ iface->proxy_enumerate = parent_iface->proxy_enumerate;
+ iface->to_string = g_vsock_socket_address_connectable_to_string;
+}
+
+static gchar *
+g_vsock_socket_address_connectable_to_string (GSocketConnectable *connectable)
+{
+ GVsockSocketAddress *sa = G_VSOCK_SOCKET_ADDRESS (connectable);
+
+ return g_strdup_printf ("vsock:cid=%u,port=%u", sa->priv->cid, sa->priv->port);
+}
+
+static void
+g_vsock_socket_address_init (GVsockSocketAddress *address)
+{
+ address->priv = g_vsock_socket_address_get_instance_private (address);
+}
+
+/**
+ * g_vsock_socket_address_new:
+ * @cid: a Context Identifier (CID)
+ * @port: a port number
+ *
+ * Creates a new #GVsockSocketAddress for @cid and @port.
+ *
+ * Returns: a new #GVsockSocketAddress
+ *
+ * Since: 2.68
+ */
+GSocketAddress *
+g_vsock_socket_address_new (guint cid,
+ guint port)
+{
+ return g_object_new (G_TYPE_VSOCK_SOCKET_ADDRESS,
+ "cid", cid,
+ "port", port,
+ NULL);
+}
+
+/**
+ * g_vsock_socket_address_get_cid:
+ * @address: a #GVsockSocketAddress
+ *
+ * Gets @address's Context Identifier (CID).
+ *
+ * Returns: the Context Identifier (CID) for @address
+ *
+ * Since: 2.68
+ */
+guint
+g_vsock_socket_address_get_cid (GVsockSocketAddress *address)
+{
+ g_return_val_if_fail (G_IS_VSOCK_SOCKET_ADDRESS (address), 0);
+
+ return address->priv->cid;
+}
+
+/**
+ * g_vsock_socket_address_get_port:
+ * @address: a #GVsockSocketAddress
+ *
+ * Gets @address's port.
+ *
+ * Returns: the port for @address
+ *
+ * Since: 2.68
+ */
+guint
+g_vsock_socket_address_get_port (GVsockSocketAddress *address)
+{
+ g_return_val_if_fail (G_IS_VSOCK_SOCKET_ADDRESS (address), 0);
+
+ return address->priv->port;
+}
diff --git a/gio/gvsocksocketaddress.h b/gio/gvsocksocketaddress.h
new file mode 100644
index 0000000000000000000000000000000000000000..8e76d70686c5ee3f290a8f6e8c960f0655d22426
--- /dev/null
+++ b/gio/gvsocksocketaddress.h
@@ -0,0 +1,70 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2021 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, see .
+ *
+ * Authors: Marc-André Lureau
+ */
+
+#ifndef __G_VSOCK_SOCKET_ADDRESS_H__
+#define __G_VSOCK_SOCKET_ADDRESS_H__
+
+#if !defined (__GIO_GIO_H_INSIDE__) && !defined (GIO_COMPILATION)
+#error "Only can be included directly."
+#endif
+
+#include
+
+G_BEGIN_DECLS
+
+#define G_TYPE_VSOCK_SOCKET_ADDRESS (g_vsock_socket_address_get_type ())
+#define G_VSOCK_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_VSOCK_SOCKET_ADDRESS, GVsockSocketAddress))
+#define G_VSOCK_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_VSOCK_SOCKET_ADDRESS, GVsockSocketAddressClass))
+#define G_IS_VSOCK_SOCKET_ADDRESS(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_VSOCK_SOCKET_ADDRESS))
+#define G_IS_VSOCK_SOCKET_ADDRESS_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_VSOCK_SOCKET_ADDRESS))
+#define G_VSOCK_SOCKET_ADDRESS_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_VSOCK_SOCKET_ADDRESS, GVsockSocketAddressClass))
+
+typedef struct _GVsockSocketAddressClass GVsockSocketAddressClass;
+typedef struct _GVsockSocketAddressPrivate GVsockSocketAddressPrivate;
+
+struct _GVsockSocketAddress
+{
+ GSocketAddress parent_instance;
+
+ /*< private >*/
+ GVsockSocketAddressPrivate *priv;
+};
+
+struct _GVsockSocketAddressClass
+{
+ GSocketAddressClass parent_class;
+};
+
+GLIB_AVAILABLE_IN_2_68
+GType g_vsock_socket_address_get_type (void) G_GNUC_CONST;
+
+GLIB_AVAILABLE_IN_2_68
+GSocketAddress *g_vsock_socket_address_new (guint cid,
+ guint port);
+
+GLIB_AVAILABLE_IN_2_68
+guint g_vsock_socket_address_get_cid (GVsockSocketAddress *address);
+
+GLIB_AVAILABLE_IN_2_68
+guint g_vsock_socket_address_get_port (GVsockSocketAddress *address);
+
+G_END_DECLS
+
+#endif /* __G_VSOCK_SOCKET_ADDRESS_H__ */
diff --git a/gio/meson.build b/gio/meson.build
index 8e039b68c61c89d816698ab2110f6a61ecfab31f..b4cca8d1ab186df34ce939391c5962d798bea806 100644
--- a/gio/meson.build
+++ b/gio/meson.build
@@ -580,6 +580,8 @@ gio_sources = files(
'gvfs.c',
'gvolume.c',
'gvolumemonitor.c',
+ 'gvsockconnection.c',
+ 'gvsocksocketaddress.c',
'gzlibcompressor.c',
'gzlibdecompressor.c',
'glistmodel.c',
@@ -714,6 +716,8 @@ gio_headers = files(
'gvfs.h',
'gvolume.h',
'gvolumemonitor.h',
+ 'gvsockconnection.h',
+ 'gvsocksocketaddress.h',
'gzlibcompressor.h',
'gzlibdecompressor.h',
'glistmodel.h',
diff --git a/gio/tests/gdbus-peer.c b/gio/tests/gdbus-peer.c
index 23a22981a05151c8f59a367d18ee9f2d32e8f55f..ac8538d9408ec3290e5c8bdc0f619253d3ab7435 100644
--- a/gio/tests/gdbus-peer.c
+++ b/gio/tests/gdbus-peer.c
@@ -1736,6 +1736,98 @@ test_tcp_anonymous (void)
g_free (test_guid);
}
+#ifdef HAVE_VSOCK
+static gpointer
+vsock_service_thread_func (gpointer user_data)
+{
+ gboolean *seen_connection = user_data;
+ GMainContext *service_context;
+ GError *error;
+
+ service_context = g_main_context_new ();
+ g_main_context_push_thread_default (service_context);
+
+ error = NULL;
+ server = g_dbus_server_new_sync ("vsock:",
+ G_DBUS_SERVER_FLAGS_AUTHENTICATION_ALLOW_ANONYMOUS,
+ test_guid,
+ NULL, /* GDBusObserver* */
+ NULL, /* GCancellable* */
+ &error);
+ if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_ADDRESS_NOT_AVAILABLE))
+ {
+ g_test_skip ("VSOCK not enabled or not avaialble");
+ goto run_loop;
+ }
+ g_assert_no_error (error);
+
+ g_signal_connect (server,
+ "new-connection",
+ G_CALLBACK (tcp_anonymous_on_new_connection),
+ seen_connection);
+
+ g_dbus_server_start (server);
+
+run_loop:
+ run_service_loop (service_context);
+
+ g_main_context_pop_thread_default (service_context);
+
+ teardown_service_loop ();
+ g_main_context_unref (service_context);
+
+ return NULL;
+}
+
+static void
+test_vsock (void)
+{
+ gboolean seen_connection;
+ GThread *service_thread;
+ GDBusConnection *connection;
+ GError *error;
+
+ test_guid = g_dbus_generate_guid ();
+ loop = g_main_loop_new (NULL, FALSE);
+
+ seen_connection = FALSE;
+ service_thread = g_thread_new ("vsock-service",
+ vsock_service_thread_func,
+ &seen_connection);
+ await_service_loop ();
+ if (server == NULL)
+ goto end;
+
+ error = NULL;
+ connection = g_dbus_connection_new_for_address_sync (g_dbus_server_get_client_address (server),
+ G_DBUS_CONNECTION_FLAGS_AUTHENTICATION_CLIENT,
+ NULL, /* GDBusAuthObserver* */
+ NULL, /* GCancellable */
+ &error);
+ g_assert_no_error (error);
+ g_assert (connection != NULL);
+
+ while (!seen_connection)
+ g_thread_yield ();
+
+ g_object_unref (connection);
+
+end:
+ g_main_loop_quit (service_loop);
+ if (server)
+ {
+ g_dbus_server_stop (server);
+ g_object_unref (server);
+ server = NULL;
+ }
+
+ g_thread_join (service_thread);
+
+ g_main_loop_unref (loop);
+ g_free (test_guid);
+}
+#endif
+
/* ---------------------------------------------------------------------------------------------------- */
static GDBusServer *codegen_server = NULL;
@@ -2017,6 +2109,9 @@ main (int argc,
g_test_add_func ("/gdbus/tcp-anonymous", test_tcp_anonymous);
g_test_add_func ("/gdbus/credentials", test_credentials);
g_test_add_func ("/gdbus/codegen-peer-to-peer", codegen_test_peer);
+#ifdef HAVE_VSOCK
+ g_test_add_func ("/gdbus/vsock", test_vsock);
+#endif
ret = g_test_run ();
diff --git a/gio/tests/socket.c b/gio/tests/socket.c
index 683866ede37ff809ea5534ad7857aa4a8c6d0049..7a272c8d3cd9c4123b53ca28ce2813439b76a26c 100644
--- a/gio/tests/socket.c
+++ b/gio/tests/socket.c
@@ -16,6 +16,7 @@
* Public License along with this library; if not, see .
*/
+#include "config.h"
#include
#include
@@ -27,8 +28,10 @@
#include
#include
#endif
-
-#include "gnetworkingprivate.h"
+#include
+#ifdef HAVE_VSOCK
+#include
+#endif
static gboolean ipv6_supported;
@@ -1306,6 +1309,9 @@ static void
test_sockaddr (void)
{
struct sockaddr_in6 sin6, gsin6;
+#ifdef HAVE_VSOCK
+ struct sockaddr_vm svm;
+#endif
GSocketAddress *saddr;
GInetSocketAddress *isaddr;
GInetAddress *iaddr;
@@ -1339,8 +1345,68 @@ test_sockaddr (void)
g_assert_cmpint (sin6.sin6_flowinfo, ==, gsin6.sin6_flowinfo);
g_object_unref (saddr);
+
+#ifdef HAVE_VSOCK
+ memset (&svm, 0, sizeof (svm));
+ svm.svm_family = AF_VSOCK;
+ svm.svm_port = 42;
+ svm.svm_cid = 1729;
+
+ saddr = g_socket_address_new_from_native (&svm, sizeof (svm));
+ g_assert (G_IS_VSOCK_SOCKET_ADDRESS (saddr));
+ g_assert_cmpint (g_socket_address_get_family (saddr), ==, AF_VSOCK);
+ g_object_unref (saddr);
+#endif
+}
+
+#ifdef HAVE_VSOCK
+static void
+test_vsock_from_fd (void)
+{
+ gint fd;
+ GError *error;
+ GSocket *s;
+
+ fd = socket (AF_VSOCK, SOCK_STREAM, 0);
+ g_assert_cmpint (fd, !=, -1);
+
+ error = NULL;
+ s = g_socket_new_from_fd (fd, &error);
+ g_assert_no_error (error);
+ g_assert_cmpint (g_socket_get_family (s), ==, G_SOCKET_FAMILY_VSOCK);
+ g_assert_cmpint (g_socket_get_socket_type (s), ==, G_SOCKET_TYPE_STREAM);
+ g_assert_cmpint (g_socket_get_protocol (s), ==, G_SOCKET_PROTOCOL_DEFAULT);
+ g_object_unref (s);
}
+static void
+test_vsock_connection (void)
+{
+ gint fd;
+ GError *error;
+ GSocket *s;
+ GSocketConnection *c;
+ GSocketAddress *addr;
+
+ fd = socket (AF_VSOCK, SOCK_STREAM, 0);
+ g_assert_cmpint (fd, !=, -1);
+
+ error = NULL;
+ s = g_socket_new_from_fd (fd, &error);
+ g_assert_no_error (error);
+ c = g_socket_connection_factory_create_connection (s);
+ g_assert (G_IS_VSOCK_CONNECTION (c));
+
+ addr = g_socket_connection_get_local_address (c, &error);
+ g_assert_no_error (error);
+ g_assert (G_IS_VSOCK_SOCKET_ADDRESS (addr));
+
+ g_object_unref (addr);
+ g_object_unref (c);
+ g_object_unref (s);
+}
+#endif
+
#ifdef G_OS_UNIX
static void
test_unix_from_fd (void)
@@ -2154,6 +2220,10 @@ main (int argc,
g_test_add_func ("/socket/unix-connection", test_unix_connection);
g_test_add_func ("/socket/unix-connection-ancillary-data", test_unix_connection_ancillary_data);
g_test_add_func ("/socket/source-postmortem", test_source_postmortem);
+#endif
+#ifdef HAVE_VSOCK
+ g_test_add_func ("/socket/vsock-from-fd", test_vsock_from_fd);
+ g_test_add_func ("/socket/vsock-connection", test_vsock_connection);
#endif
g_test_add_func ("/socket/reuse/tcp", test_reuse_tcp);
g_test_add_func ("/socket/reuse/udp", test_reuse_udp);
diff --git a/glib/glibconfig.h.in b/glib/glibconfig.h.in
index 873cb03142dcc346003e19fa655079e861eea091..613f1be17ab7d595ad6c2206531467db30c40f0c 100644
--- a/glib/glibconfig.h.in
+++ b/glib/glibconfig.h.in
@@ -193,6 +193,7 @@ typedef @g_pid_type@ GPid;
#define GLIB_SYSDEF_AF_UNIX @g_af_unix@
#define GLIB_SYSDEF_AF_INET @g_af_inet@
#define GLIB_SYSDEF_AF_INET6 @g_af_inet6@
+#define GLIB_SYSDEF_AF_VSOCK @g_af_vsock@
#define GLIB_SYSDEF_MSG_OOB @g_msg_oob@
#define GLIB_SYSDEF_MSG_PEEK @g_msg_peek@
diff --git a/meson.build b/meson.build
index d7d64118d75a91fe8f1e0fd040ee1dc08016bed4..f66c7f0f18cee207e0fda0ed5f80b52cb4e8440c 100644
--- a/meson.build
+++ b/meson.build
@@ -333,6 +333,9 @@ endif
if cc.has_header('linux/netlink.h')
glib_conf.set('HAVE_NETLINK', 1)
endif
+if cc.has_header('linux/vm_sockets.h')
+ glib_conf.set('HAVE_VSOCK', 1)
+endif
# Is statx() supported? Android systems don’t reliably support it as of August 2020.
statx_code = '''
@@ -1761,6 +1764,27 @@ inet_defines = [
[ 'MSG_PEEK', 'g_msg_peek' ],
[ 'MSG_DONTROUTE', 'g_msg_dontroute' ],
]
+
+if glib_conf.has('HAVE_VSOCK')
+ vsock_defines = [
+ [ 'VMADDR_CID_ANY', '-1U' ],
+ [ 'VMADDR_PORT_ANY', '-1U' ],
+ [ 'VMADDR_CID_HYPERVISOR', '0' ],
+ [ 'VMADDR_CID_LOCAL', '1' ],
+ [ 'VMADDR_CID_HOST', '2' ],
+ ]
+ foreach d : vsock_defines
+ if not cc.has_header_symbol('linux/vm_sockets.h', d[0], prefix: inet_includes)
+ glib_conf.set(d[0], d[1])
+ endif
+ endforeach
+ inet_defines += [ [ 'AF_VSOCK', 'g_af_vsock' ] ]
+ inet_includes += '''
+ #include '''
+else
+ glibconfig_conf.set('g_af_vsock', '-1')
+endif
+
foreach d : inet_defines
val = cc.compute_int(d[0], prefix: inet_includes)
glibconfig_conf.set(d[1], val)