From 832191d36fd67aa08189d6e354b575f6ecac5b4d Mon Sep 17 00:00:00 2001 From: José Bollo Date: Thu, 21 Feb 2019 18:46:30 +0100 Subject: Add support for L4Re Virtio Sockets MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Change-Id: Ia47ef2fa8c650781d5a4545fa08360808291faf5 Signed-off-by: José Bollo --- CMakeLists.txt | 3 +- src/CMakeLists.txt | 1 + src/afb-socket.c | 114 +++++++++++++++++++++++++++++++++++++++++++++++++---- 3 files changed, 109 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7a7ab429..149a354f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -52,7 +52,7 @@ option(WITH_SIG_MONITOR_TIMERS "Activate monitoring of call expiration" ON) option(WITH_AFB_HOOK "Include hooking" ON) option(WITH_AFB_TRACE "Include monitoring trace" ON) option(WITH_SUPERVISOR "Activates installation of supervisor" OFF) -option(WITH_MONITORING "Activates installation of monitoring" OFF) +option(WITH_MONITORING "Activates installation of monitoring" OFF) option(WITH_DBUS_TRANSPARENCY "Allows API transparency over DBUS" OFF) option(WITH_LEGACY_BINDING_V1 "Includes the legacy Binding API version 1" OFF) option(WITH_LEGACY_BINDING_V2 "Includes the legacy Binding API version 2" ON) @@ -60,6 +60,7 @@ option(WITH_LEGACY_BINDING_VDYN "Includes the legacy Binding API version dynam option(WITH_DYNAMIC_BINDING "Allow to load dynamic bindings (shared libraries)" ON) option(WITH_LIBMICROHTTPD "Activates HTTP server through LIBMICROHTTPD" ON) option(WITH_FNMATCH "Use fnmatch where possible" ON) +option(WITH_L4VSOCK "Activates L4RE support of VIRTIO-SOCKS" OFF) ############################################################################ # legacy options diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 8d898328..46968946 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -44,6 +44,7 @@ add_definitions( -DWITH_LIBMICROHTTPD=$ -DWITH_MONITORING=$ -DWITH_FNMATCH=$ + -DWITH_L4VSOCK=$ ) if (WITH_SUPERVISOR) diff --git a/src/afb-socket.c b/src/afb-socket.c index 754baea0..f1eb561f 100644 --- a/src/afb-socket.c +++ b/src/afb-socket.c @@ -35,10 +35,7 @@ #include "fdev.h" #include "verbose.h" -#if WITH_SYSTEMD -#include "systemd.h" -#endif - +/******************************************************************************/ #define BACKLOG 5 /******************************************************************************/ @@ -53,6 +50,9 @@ enum type { /** type systemd */ Type_Systemd, + /** type virtual socket of L4 */ + Type_L4, + /** type Unix */ Type_Unix }; @@ -89,6 +89,10 @@ static struct entry entries[] = { .noreuseaddr = 1, .nolisten = 1 }, + { + .prefix = "l4vsock:", + .type = Type_L4 + }, { .prefix = "unix:", .type = Type_Unix @@ -219,6 +223,11 @@ static int open_tcp(const char *spec, int server, int reuseaddr) return -1; } +/******************************************************************************/ +#if WITH_SYSTEMD + +#include "systemd.h" + /** * open a systemd socket for server * @@ -228,14 +237,96 @@ static int open_tcp(const char *spec, int server, int reuseaddr) */ static int open_systemd(const char *spec) { -#if WITH_SYSTEMD return systemd_fds_for(spec); -#else - errno = EAFNOSUPPORT; - return -1; +} #endif + +/******************************************************************************/ +#if WITH_L4VSOCK + +struct sockaddr_l4 +{ + unsigned short sl4_family; + unsigned short port; + char name[8]; + char _pad[4]; +}; + +enum address_families_l4 +{ + AF_VIO_SOCK = 50, /* virtio-based sockets, must match the number in Linux */ + PF_VIO_SOCK = AF_VIO_SOCK, +}; + +#define DEFAULT_L4VSOCK_PORT 7777 + +/** + * open a L4 VSOCK socket for client or server + * + * @param spec the specification of the path (prefix with @ for abstract) + * @param server 0 for client, server otherwise + * + * @return the file descriptor number of the socket or -1 in case of error + */ +static int open_l4(const char *spec, int server) +{ + int fd, rc; + struct sockaddr_l4 addr; + const char *port, *slash; + unsigned short portnum; + size_t length; + + /* scan the spec */ + port = strchr(spec, ':'); + slash = strchr(spec, '/'); + if (port && slash && slash < port) { + errno = EINVAL; + return -1; + } + if (port) { + rc = atoi(port + 1); + if (rc <= 0 && rc > UINT16_MAX) { + errno = EINVAL; + return -1; + } + portnum = (unsigned short)rc; + length = port - spec; + } else { + portnum = DEFAULT_L4VSOCK_PORT; + length = slash ? slash - spec : strlen(spec); + } + + /* check the length */ + if (length >= sizeof addr.name) { + errno = ENAMETOOLONG; + return -1; + } + + /* create a socket */ + fd = socket(PF_VIO_SOCK, SOCK_STREAM, 0); + if (fd < 0) + return fd; + + /* prepare address */ + memset(&addr, 0, sizeof addr); + addr.sl4_family = AF_VIO_SOCK; + addr.port = portnum; + memcpy(addr.name, spec, length); + + if (server) { + rc = bind(fd, (struct sockaddr *) &addr, (socklen_t)(sizeof addr)); + } else { + rc = connect(fd, (struct sockaddr *) &addr, (socklen_t)(sizeof addr)); + } + if (rc < 0) { + close(fd); + return rc; + } + return fd; } +#endif + /******************************************************************************/ /** @@ -296,6 +387,7 @@ static int open_uri(const char *uri, int server) case Type_Inet: fd = open_tcp(uri, server, !e->noreuseaddr); break; +#if WITH_SYSTEMD case Type_Systemd: if (server) fd = open_systemd(uri); @@ -304,6 +396,12 @@ static int open_uri(const char *uri, int server) fd = -1; } break; +#endif +#if WITH_L4VSOCK + case Type_L4: + fd = open_l4(uri, server); + break; +#endif default: errno = EAFNOSUPPORT; fd = -1; -- cgit 1.2.3-korg