X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-socket.c;h=f1eb561f9bcd84ba7ce726ec07c3759b7bfc46f8;hb=refs%2Fheads%2Fsandbox%2Fjobol%2Fl4sock;hp=754baea002b4232939240254a02aafe2560be17f;hpb=caea0053d2abc141ab585324fb51f8c536db249b;p=src%2Fapp-framework-binder.git 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;