X-Git-Url: https://gerrit.automotivelinux.org/gerrit/gitweb?a=blobdiff_plain;f=src%2Fafb-socket.c;h=73efaaca575b4af9e09a4c54c23ea15c83c749ce;hb=65353dce81a629e042800bb7b86fcd869a76727e;hp=77b5edf8e33e219162528cccba6ff58bc1b57c66;hpb=e11e8fbe65c6d57716c96bc6dd2b503a310dca67;p=src%2Fapp-framework-binder.git diff --git a/src/afb-socket.c b/src/afb-socket.c index 77b5edf8..73efaaca 100644 --- a/src/afb-socket.c +++ b/src/afb-socket.c @@ -1,5 +1,5 @@ /* - * Copyright (C) 2015-2018 "IoT.bzh" + * Copyright (C) 2015-2020 "IoT.bzh" * Author José Bollo * * Licensed under the Apache License, Version 2.0 (the "License"); @@ -31,7 +31,8 @@ #include "afb-fdev.h" #include "afb-socket.h" -#include "afb-systemd.h" + +#include "systemd.h" #include "fdev.h" #include "verbose.h" @@ -158,14 +159,14 @@ static int open_unix(const char *spec, int server) * * @return the file descriptor number of the socket or -1 in case of error */ -static int open_tcp(const char *spec, int server) +static int open_tcp(const char *spec, int server, int reuseaddr) { int rc, fd; const char *service, *host, *tail; struct addrinfo hint, *rai, *iai; /* scan the uri */ - tail = strchr(spec, '/'); + tail = strchrnul(spec, '/'); service = strchr(spec, ':'); if (tail == NULL || service == NULL || tail < service) { errno = EINVAL; @@ -178,6 +179,11 @@ static int open_tcp(const char *spec, int server) memset(&hint, 0, sizeof hint); hint.ai_family = AF_INET; hint.ai_socktype = SOCK_STREAM; + if (server) { + hint.ai_flags = AI_PASSIVE; + if (host[0] == 0 || (host[0] == '*' && host[1] == 0)) + host = NULL; + } rc = getaddrinfo(host, service, &hint, &rai); if (rc != 0) { errno = EINVAL; @@ -190,6 +196,10 @@ static int open_tcp(const char *spec, int server) fd = socket(iai->ai_family, iai->ai_socktype, iai->ai_protocol); if (fd >= 0) { if (server) { + if (reuseaddr) { + rc = 1; + setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &rc, sizeof rc); + } rc = bind(fd, iai->ai_addr, iai->ai_addrlen); } else { rc = connect(fd, iai->ai_addr, iai->ai_addrlen); @@ -219,7 +229,7 @@ static int open_systemd(const char *spec) errno = EAFNOSUPPORT; return -1; #else - return afb_systemd_fds_for(spec); + return systemd_fds_for(spec); #endif } @@ -230,25 +240,41 @@ static int open_systemd(const char *spec) * * @param uri the searched uri * @param offset where to store the prefix length + * @param scheme the default scheme to use if none is set in uri (can be NULL) * * @return the found entry or the default one */ -static struct entry *get_entry(const char *uri, int *offset) +static struct entry *get_entry(const char *uri, int *offset, const char *scheme) { - int l, i = (int)(sizeof entries / sizeof * entries); + int len, i, deflen; - for (;;) { - if (!i) { - l = 0; - break; - } + /* search as prefix of URI */ + i = (int)(sizeof entries / sizeof * entries); + while (i) { i--; - l = (int)strlen(entries[i].prefix); - if (!strncmp(uri, entries[i].prefix, l)) - break; + len = (int)strlen(entries[i].prefix); + if (!strncmp(uri, entries[i].prefix, len)) + goto end; /* found */ } - *offset = l; + /* not a prefix of uri */ + len = 0; + + /* search default scheme if given and valid */ + if (scheme && *scheme) { + deflen = (int)strlen(scheme); + deflen += (scheme[deflen - 1] != ':'); /* add virtual trailing colon */ + i = (int)(sizeof entries / sizeof * entries); + while (i) { + i--; + if (deflen == (int)strlen(entries[i].prefix) + && !strncmp(scheme, entries[i].prefix, deflen - 1)) + goto end; /* found */ + } + } + +end: + *offset = len; return &entries[i]; } @@ -257,17 +283,18 @@ static struct entry *get_entry(const char *uri, int *offset) * * @param uri the specification of the socket * @param server 0 for client, server otherwise + * @param scheme the default scheme to use if none is set in uri (can be NULL) * * @return the file descriptor number of the socket or -1 in case of error */ -static int open_uri(const char *uri, int server) +static int open_uri(const char *uri, int server, const char *scheme) { - int fd, rc, offset; + int fd, offset; struct entry *e; const char *api; /* search for the entry */ - e = get_entry(uri, &offset); + e = get_entry(uri, &offset, scheme); /* get the names */ uri += offset; @@ -281,7 +308,7 @@ static int open_uri(const char *uri, int server) fd = open_unix(uri, server); break; case Type_Inet: - fd = open_tcp(uri, server); + fd = open_tcp(uri, server, !e->noreuseaddr); break; case Type_Systemd: if (server) @@ -303,10 +330,6 @@ static int open_uri(const char *uri, int server) fcntl(fd, F_SETFD, FD_CLOEXEC); fcntl(fd, F_SETFL, O_NONBLOCK); if (server) { - if (!e->noreuseaddr) { - rc = 1; - setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &rc, sizeof rc); - } if (!e->nolisten) listen(fd, BACKLOG); } @@ -318,12 +341,13 @@ static int open_uri(const char *uri, int server) * * @param uri the specification of the socket * @param server 0 for client, server otherwise + * @param scheme the default scheme to use if none is set in uri (can be NULL) * * @return the file descriptor number of the socket or -1 in case of error */ -int afb_socket_open(const char *uri, int server) +int afb_socket_open_scheme(const char *uri, int server, const char *scheme) { - int fd = open_uri(uri, server); + int fd = open_uri(uri, server, scheme); if (fd < 0) ERROR("can't open %s socket for %s", server ? "server" : "client", uri); return fd; @@ -334,15 +358,16 @@ int afb_socket_open(const char *uri, int server) * * @param uri the specification of the socket * @param server 0 for client, server otherwise + * @param scheme the default scheme to use if none is set in uri (can be NULL) * * @return the fdev of the socket or NULL in case of error */ -struct fdev *afb_socket_open_fdev(const char *uri, int server) +struct fdev *afb_socket_open_fdev_scheme(const char *uri, int server, const char *scheme) { struct fdev *fdev; int fd; - fd = afb_socket_open(uri, server); + fd = afb_socket_open_scheme(uri, server, scheme); if (fd < 0) fdev = NULL; else { @@ -366,9 +391,11 @@ const char *afb_socket_api(const char *uri) { int offset; const char *api; + struct entry *entry; - get_entry(uri, &offset); + entry = get_entry(uri, &offset, NULL); uri += offset; + uri += (entry->type == Type_Unix && *uri == '@'); api = strstr(uri, as_api); if (api) api += sizeof as_api - 1;