summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/logger.c2
-rw-r--r--src/sd-daemon.c69
-rw-r--r--src/sd-daemon.h34
3 files changed, 69 insertions, 36 deletions
diff --git a/src/logger.c b/src/logger.c
index c486a8acd1..2e036dd77b 100644
--- a/src/logger.c
+++ b/src/logger.c
@@ -428,7 +428,7 @@ static int server_init(Server *s, unsigned n_sockets) {
fd = SD_LISTEN_FDS_START+i;
- if ((r = sd_is_socket(fd, SOCK_STREAM, 1)) < 0) {
+ if ((r = sd_is_socket(fd, AF_UNSPEC, SOCK_STREAM, 1)) < 0) {
log_error("Failed to determine file descriptor type: %s", strerror(-r));
goto fail;
}
diff --git a/src/sd-daemon.c b/src/sd-daemon.c
index ad2bfa82e7..eec4722709 100644
--- a/src/sd-daemon.c
+++ b/src/sd-daemon.c
@@ -133,7 +133,7 @@ int sd_is_fifo(int fd, const char *path) {
return 1;
}
-int sd_is_socket(int fd, int type, int listening) {
+static int sd_is_socket_internal(int fd, int type, int listening) {
struct stat st_fd;
if (fd < 0 || type < 0)
@@ -176,18 +176,51 @@ int sd_is_socket(int fd, int type, int listening) {
return 1;
}
-int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) {
- union {
- struct sockaddr sa;
- struct sockaddr_in in4;
- struct sockaddr_in6 in6;
- struct sockaddr_un un;
- struct sockaddr_storage storage;
- } sockaddr;
+union sockaddr_union {
+ struct sockaddr sa;
+ struct sockaddr_in in4;
+ struct sockaddr_in6 in6;
+ struct sockaddr_un un;
+ struct sockaddr_storage storage;
+};
+
+int sd_is_socket(int fd, int family, int type, int listening) {
+ int r;
+
+ if (family < 0)
+ return -EINVAL;
+
+ if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
+ return r;
+
+ if (family > 0) {
+ union sockaddr_union sockaddr;
+ socklen_t l;
+
+ memset(&sockaddr, 0, sizeof(sockaddr));
+ l = sizeof(sockaddr);
+
+ if (getsockname(fd, &sockaddr.sa, &l) < 0)
+ return -errno;
+
+ if (l < sizeof(sa_family_t))
+ return -EINVAL;
+
+ return sockaddr.sa.sa_family == family;
+ }
+
+ return 1;
+}
+
+int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port) {
+ union sockaddr_union sockaddr;
socklen_t l;
int r;
- if ((r = sd_is_socket(fd, type, listening)) <= 0)
+ if (family != 0 && family != AF_INET && family != AF_INET6)
+ return -EINVAL;
+
+ if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
return r;
memset(&sockaddr, 0, sizeof(sockaddr));
@@ -196,13 +229,17 @@ int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) {
if (getsockname(fd, &sockaddr.sa, &l) < 0)
return -errno;
- if (l < sizeof(struct sockaddr))
+ if (l < sizeof(sa_family_t))
return -EINVAL;
if (sockaddr.sa.sa_family != AF_INET &&
sockaddr.sa.sa_family != AF_INET6)
return 0;
+ if (family > 0)
+ if (sockaddr.sa.sa_family != family)
+ return 0;
+
if (port > 0) {
if (sockaddr.sa.sa_family == AF_INET) {
if (l < sizeof(struct sockaddr_in))
@@ -221,17 +258,11 @@ int sd_is_socket_inet(int fd, int type, int listening, uint16_t port) {
}
int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length) {
- union {
- struct sockaddr sa;
- struct sockaddr_in in4;
- struct sockaddr_in6 in6;
- struct sockaddr_un un;
- struct sockaddr_storage storage;
- } sockaddr;
+ union sockaddr_union sockaddr;
socklen_t l;
int r;
- if ((r = sd_is_socket(fd, type, listening)) <= 0)
+ if ((r = sd_is_socket_internal(fd, type, listening)) <= 0)
return r;
memset(&sockaddr, 0, sizeof(sockaddr));
diff --git a/src/sd-daemon.h b/src/sd-daemon.h
index ab69364c26..e209af6489 100644
--- a/src/sd-daemon.h
+++ b/src/sd-daemon.h
@@ -73,24 +73,26 @@ int sd_listen_fds(int unset_environment);
int sd_is_fifo(int fd, const char *path);
/* Helper call for identifying a passed file descriptor. Returns 1 if
- * the file descriptor is a socket of the specified type (SOCK_DGRAM,
- * SOCK_STREAM, ...), 0 otherwise. If type is 0 a socket type check
- * will not be done and the call only verifies if the file descriptor
- * refers to a socket. If listening is > 0 it is verified that the
- * socket is in listening mode. (i.e. listen() has been called) If
- * listening is == 0 it is verified that the socket is not in
- * listening mode. If listening is < 0 no listening mode check is
- * done. Returns a negative errno style error code on failure. */
-int sd_is_socket(int fd, int type, int listening);
+ * the file descriptor is a socket of the specified family (AF_INET,
+ * ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If
+ * family is 0 a socket family check will not be done. If type is 0 a
+ * socket type check will not be done and the call only verifies if
+ * the file descriptor refers to a socket. If listening is > 0 it is
+ * verified that the socket is in listening mode. (i.e. listen() has
+ * been called) If listening is == 0 it is verified that the socket is
+ * not in listening mode. If listening is < 0 no listening mode check
+ * is done. Returns a negative errno style error code on failure. */
+int sd_is_socket(int fd, int family, int type, int listening);
/* Helper call for identifying a passed file descriptor. Returns 1 if
- * the file descriptor is an Internet socket (either AF_INET or
- * AF_INET6) of the specified type (SOCK_DGRAM, SOCK_STREAM, ...), 0
- * otherwise. If type is 0 a socket type check will not be done. If
- * port is 0 a socket port check will not be done. The listening flag
- * is used the same way as in sd_is_socket(). Returns a negative errno
- * style error code on failure. */
-int sd_is_socket_inet(int fd, int type, int listening, uint16_t port);
+ * the file descriptor is an Internet socket, of the specified family
+ * (either AF_INET or AF_INET6) of the specified type (SOCK_DGRAM,
+ * SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version
+ * check is not done. If type is 0 a socket type check will not be
+ * done. If port is 0 a socket port check will not be done. The
+ * listening flag is used the same way as in sd_is_socket(). Returns a
+ * negative errno style error code on failure. */
+int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port);
/* Helper call for identifying a passed file descriptor. Returns 1 if
* the file descriptor is an AF_UNIX socket of the specified type