Add support for L4Re Virtio Sockets sandbox/jobol/l4sock
authorJosé Bollo <jose.bollo@iot.bzh>
Thu, 21 Feb 2019 17:46:30 +0000 (18:46 +0100)
committerJosé Bollo <jose.bollo@iot.bzh>
Fri, 22 Mar 2019 11:21:54 +0000 (12:21 +0100)
Change-Id: Ia47ef2fa8c650781d5a4545fa08360808291faf5
Signed-off-by: José Bollo <jose.bollo@iot.bzh>
CMakeLists.txt
src/CMakeLists.txt
src/afb-socket.c

index 7a7ab42..149a354 100644 (file)
@@ -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
index 8d89832..4696894 100644 (file)
@@ -44,6 +44,7 @@ add_definitions(
   -DWITH_LIBMICROHTTPD=$<BOOL:${WITH_LIBMICROHTTPD}>
   -DWITH_MONITORING=$<BOOL:${WITH_MONITORING}>
   -DWITH_FNMATCH=$<BOOL:${WITH_FNMATCH}>
+  -DWITH_L4VSOCK=$<BOOL:${WITH_L4VSOCK}>
 )
 
 if (WITH_SUPERVISOR)
index 754baea..f1eb561 100644 (file)
 #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;