#include <sys/types.h>
#include <netinet/in.h>
])
+AC_CHECK_HEADERS([linux/vm_sockets.h], [have_vm_sockets=true], [],
+[
+ #include <sys/socket.h>
+])
+AM_CONDITIONAL(USE_VM_SOCKETS, [test "x$have_vm_sockets" = xtrue])
AC_CHECK_MEMBERS([struct sockaddr.sa_len], [], [],
[
networking/streams/stream_service_unix.c
endif
+if USE_VM_SOCKETS
+ libstrongswan_la_SOURCES += \
+ networking/streams/stream_vsock.c \
+ networking/streams/stream_service_vsock.c
+endif
+
# private header files
noinst_HEADERS = \
settings/settings_types.h
utils/utils/atomics.h utils/utils/types.h utils/utils/byteorder.h \
utils/utils/string.h utils/utils/memory.h utils/utils/tty.h utils/utils/path.h \
utils/utils/status.h utils/utils/object.h utils/utils/time.h utils/utils/align.h
+if USE_VM_SOCKETS
+ nobase_strongswan_include_HEADERS += \
+ networking/streams/stream_vsock.h \
+ networking/streams/stream_service_vsock.h
+endif
endif
library.lo : $(top_builddir)/config.status
# include "stream_unix.h"
# include "stream_service_unix.h"
#endif
+#ifdef HAVE_LINUX_VM_SOCKETS_H
+# include "stream_vsock.h"
+# include "stream_service_vsock.h"
+#endif
#ifdef USE_SYSTEMD
# include "stream_service_systemd.h"
#endif
remove_stream(this, stream_create_unix);
remove_service(this, stream_service_create_unix);
#endif
+#ifdef HAVE_LINUX_VM_SOCKETS_H
+ remove_stream(this, stream_create_vsock);
+ remove_service(this, stream_service_create_vsock);
+#endif
#ifdef USE_SYSTEMD
remove_service(this, stream_service_create_systemd);
#endif
add_stream(this, "unix://", stream_create_unix);
add_service(this, "unix://", stream_service_create_unix);
#endif
+#ifdef HAVE_LINUX_VM_SOCKETS_H
+ add_stream(this, "vsock://", stream_create_vsock);
+ add_service(this, "vsock://", stream_service_create_vsock);
+#endif
#ifdef USE_SYSTEMD
add_service(this, "systemd://", stream_service_create_systemd);
#endif
--- /dev/null
+/*
+ * Copyright (C) 2024 Thomas Egerer
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include <library.h>
+
+#include "stream_service_vsock.h"
+#include "stream_vsock.h"
+
+/*
+ * Described in header
+ */
+stream_service_t *stream_service_create_vsock(char *uri, int backlog)
+{
+ int fd = stream_initialize_socket_vsock(uri, &backlog);
+
+ return (fd == -1) ? NULL : stream_service_create_from_fd(fd);
+}
--- /dev/null
+/*
+ * Copyright (C) 2024 Thomas Egerer
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup stream_service_vsock stream_service_vsock
+ * @{ @ingroup stream
+ */
+
+#ifndef STREAM_SERVICE_VSOCK_H_
+#define STREAM_SERVICE_VSOCK_H_
+
+/**
+ * Create a service instance for VSOCK sockets.
+ *
+ * @param uri VSOCK socket specific URI, must start with "vsock://"
+ * @param backlog size of the backlog queue, as passed to listen()
+ * @return stream_service instance, NULL on failure
+ */
+stream_service_t *stream_service_create_vsock(char *uri, int backlog);
+
+#endif /** STREAM_SERVICE_VSOCK_H_ @}*/
--- /dev/null
+/*
+ * Copyright (C) 2024 Thomas Egerer
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+#include <errno.h>
+#include <limits.h>
+#include <sys/socket.h>
+#include <linux/vm_sockets.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <library.h>
+
+#include "stream_vsock.h"
+
+/**
+ * Helper function to parse a vsock:// URI to a sockaddr.
+ * Returns the length of the sockaddr or -1.
+ */
+static int stream_parse_uri_vsock(char *uri, struct sockaddr_vm *addr)
+{
+ unsigned long cid, port;
+
+ if (!strpfx(uri, "vsock://"))
+ {
+ return -1;
+ }
+
+ uri += strlen("vsock://");
+ cid = strtoul(uri, &uri, 10);
+
+ if (*uri != ':' || cid > UINT_MAX)
+ {
+ return -1;
+ }
+
+ port = strtoul(uri + 1, &uri, 10);
+ if (port > UINT_MAX || *uri)
+ {
+ return -1;
+ }
+
+ *addr = (struct sockaddr_vm){
+ .svm_family = AF_VSOCK,
+ .svm_port = port,
+ .svm_cid = cid,
+ };
+ return sizeof(*addr);
+}
+
+/*
+ * Described in header
+ */
+int stream_initialize_socket_vsock(char *uri, int *backlog)
+{
+ int fd, len;
+ struct sockaddr_vm addr;
+
+ len = stream_parse_uri_vsock(uri, &addr);
+ if (len == -1)
+ {
+ DBG1(DBG_NET, "invalid stream URI: '%s'", uri);
+ return -1;
+ }
+
+ fd = socket(AF_VSOCK, SOCK_STREAM, 0);
+ if (fd == -1)
+ {
+ DBG1(DBG_NET, "opening socket '%s' failed: %s", uri, strerror(errno));
+ return -1;
+ }
+
+ if (backlog)
+ {
+ if (bind(fd, (struct sockaddr*)&addr, len) < 0)
+ {
+ DBG1(DBG_NET, "binding socket '%s' failed: %s", uri,
+ strerror(errno));
+ close(fd);
+ return -1;
+ }
+
+ if (listen(fd, *backlog) < 0)
+ {
+ DBG1(DBG_NET, "listen on socket '%s' failed: %s", uri,
+ strerror(errno));
+ close(fd);
+ return -1;
+ }
+ }
+ else
+ {
+ if (connect(fd, (struct sockaddr*)&addr, len) < 0)
+ {
+ DBG1(DBG_NET, "connecting to '%s' failed: %s", uri,
+ strerror(errno));
+ close(fd);
+ return -1;
+ }
+ }
+ return fd;
+}
+
+/*
+ * Described in header
+ */
+stream_t *stream_create_vsock(char *uri)
+{
+ int fd = stream_initialize_socket_vsock(uri, NULL);
+
+ return (fd == -1) ? NULL : stream_create_from_fd(fd);
+}
--- /dev/null
+/*
+ * Copyright (C) 2024 Thomas Egerer
+ *
+ * Copyright (C) secunet Security Networks AG
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
+ *
+ * This program 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 General Public License
+ * for more details.
+ */
+
+/**
+ * @defgroup stream_vsock stream_vsock
+ * @{ @ingroup streams
+ */
+
+#ifndef STREAM_VSOCK_H_
+#define STREAM_VSOCK_H_
+
+/**
+ * Create a stream for VSOCK sockets.
+ *
+ * VSOCK URIs start with vsock://, followed by an integer address (context
+ * identifier, CID), followed by a colon separated port. CID as well as port
+ * are 32-bit unsigned integers. A full VSOCK uri looks something like:
+ *
+ * vsock://2:12345
+ *
+ * There is no default port, so a colon after vsock:// is mandatory.
+ *
+ * @param uri VSOCK socket specific URI, must start with "vsock://"
+ * @return stream instance, NULL on failure
+ */
+stream_t *stream_create_vsock(char *uri);
+
+/**
+ * Create and initialize a VSOCK socket.
+ *
+ * @param uri VSOCK socket specific URI, must start with "vsock://"
+ * @param backlog pointer to value for backlog for listen(2) if a service
+ * socket shall be created (bind/listen); use NULL for a
+ * VSOCK socket that just connects to \p uri
+ * @return file descriptor for created socket, -1 on error
+ */
+int stream_initialize_socket_vsock(char *uri, int *backlog);
+
+#endif /** STREAM_VSOCK_H_ @}*/