#include "bus-error.h"
#include "bus-util.h"
#include "chase-symlinks.h"
+#include "constants.h"
#include "copy.h"
#include "dbus-socket.h"
#include "dbus-unit.h"
-#include "def.h"
#include "errno-list.h"
#include "exit-status.h"
#include "fd-util.h"
#include "ip-protocol-list.h"
#include "label.h"
#include "log.h"
-#include "mkdir.h"
+#include "mkdir-label.h"
#include "parse-util.h"
#include "path-util.h"
#include "process-util.h"
if (s->control_pid <= 0)
return;
- unit_unwatch_pid(UNIT(s), s->control_pid);
- s->control_pid = 0;
+ unit_unwatch_pid(UNIT(s), TAKE_PID(s->control_pid));
}
static void socket_cleanup_fd_list(SocketPort *p) {
}
static bool have_non_accept_socket(Socket *s) {
- SocketPort *p;
-
assert(s);
if (!s->accept)
}
static int socket_add_mount_dependencies(Socket *s) {
- SocketPort *p;
int r;
assert(s);
static const char *socket_find_symlink_target(Socket *s) {
const char *found = NULL;
- SocketPort *p;
LIST_FOREACH(port, p, s->ports) {
const char *f = NULL;
if (r != 0)
return r;
- switch(x->peer.sa.sa_family) {
+ switch (x->peer.sa.sa_family) {
case AF_INET:
return memcmp(&x->peer.in.sin_addr, &y->peer.in.sin_addr, sizeof(x->peer.in.sin_addr));
case AF_INET6:
assert(u);
assert(u->load_state == UNIT_STUB);
- r = set_ensure_allocated(&s->peers_by_address, &peer_address_hash_ops);
- if (r < 0)
- return r;
-
r = unit_load_fragment_and_dropin(u, true);
if (r < 0)
return r;
static SocketPeer *socket_peer_new(void) {
SocketPeer *p;
- p = new0(SocketPeer, 1);
+ p = new(SocketPeer, 1);
if (!p)
return NULL;
- p->n_ref = 1;
-
+ *p = (SocketPeer) {
+ .n_ref = 1,
+ };
return p;
}
int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) {
_cleanup_(socket_peer_unrefp) SocketPeer *remote = NULL;
- SocketPeer sa = {}, *i;
- socklen_t salen = sizeof(sa.peer);
+ SocketPeer sa = {
+ .peer_salen = sizeof(union sockaddr_union),
+ }, *i;
int r;
assert(fd >= 0);
assert(s);
- if (getpeername(fd, &sa.peer.sa, &salen) < 0)
+ if (getpeername(fd, &sa.peer.sa, &sa.peer_salen) < 0)
return log_unit_error_errno(UNIT(s), errno, "getpeername failed: %m");
if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)) {
return 0;
}
+ r = set_ensure_allocated(&s->peers_by_address, &peer_address_hash_ops);
+ if (r < 0)
+ return r;
+
i = set_get(s->peers_by_address, &sa);
if (i) {
*p = socket_peer_ref(i);
return log_oom();
remote->peer = sa.peer;
- remote->peer_salen = salen;
+ remote->peer_salen = sa.peer_salen;
r = set_put(s->peers_by_address, remote);
if (r < 0)
remote->socket = s;
*p = TAKE_PTR(remote);
-
return 1;
}
static void socket_dump(Unit *u, FILE *f, const char *prefix) {
Socket *s = SOCKET(u);
- SocketPort *p;
const char *prefix2, *str;
assert(s);
switch (p->type) {
case SOCKET_SOCKET: {
_cleanup_free_ char *k = NULL;
- const char *t;
int r;
r = socket_address_print(&p->address, &k);
- if (r < 0)
- t = strerror_safe(r);
- else
- t = k;
-
- fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t);
+ if (r < 0) {
+ errno = -r;
+ fprintf(f, "%s%s: %m\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type));
+ } else
+ fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), k);
break;
}
case SOCKET_SPECIAL:
fprintf(f, "%sSocketProtocol: %s\n", prefix, str);
if (!strv_isempty(s->symlinks)) {
- char **q;
-
fprintf(f, "%sSymlinks:", prefix);
STRV_FOREACH(q, s->symlinks)
fprintf(f, " %s", *q);
be16toh(remote.in6.sin6_port)) < 0)
return -ENOMEM;
} else {
- char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
-
if (asprintf(&r,
"%u-%s:%u-%s:%u",
nr,
- inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
+ IN6_ADDR_TO_STRING(&local.in6.sin6_addr),
be16toh(local.in6.sin6_port),
- inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
+ IN6_ADDR_TO_STRING(&remote.in6.sin6_addr),
be16toh(remote.in6.sin6_port)) < 0)
return -ENOMEM;
}
}
static void socket_close_fds(Socket *s) {
- SocketPort *p;
- char **i;
-
assert(s);
LIST_FOREACH(port, p, s->ports) {
mode_t directory_mode,
mode_t socket_mode) {
- _cleanup_close_ int fd = -1;
+ _cleanup_close_ int fd = -EBADF;
mode_t old_mask;
struct stat st;
int r;
}
static int special_address_create(const char *path, bool writable) {
- _cleanup_close_ int fd = -1;
+ _cleanup_close_ int fd = -EBADF;
struct stat st;
assert(path);
}
static int usbffs_address_create(const char *path) {
- _cleanup_close_ int fd = -1;
+ _cleanup_close_ int fd = -EBADF;
struct stat st;
assert(path);
long maxmsg,
long msgsize) {
- _cleanup_close_ int fd = -1;
+ _cleanup_close_ int fd = -EBADF;
struct stat st;
mode_t old_mask;
struct mq_attr _attr, *attr = NULL;
static int socket_symlink(Socket *s) {
const char *p;
- char **i;
int r;
assert(s);
}
if (r < 0)
- log_unit_warning_errno(UNIT(s), r, "Failed to create symlink %s → %s, ignoring: %m", p, *i);
+ log_unit_warning_errno(UNIT(s), r, "Failed to create symlink %s %s %s, ignoring: %m",
+ p, special_glyph(SPECIAL_GLYPH_ARROW_RIGHT), *i);
}
return 0;
assert(s);
assert(ret);
- if (s->selinux_context_from_net) {
- /* If this is requested, get the label from the network label */
+ Unit *service;
+ ExecCommand *c;
+ const char *exec_context;
+ _cleanup_free_ char *path = NULL;
- r = mac_selinux_get_our_label(ret);
- if (r == -EOPNOTSUPP)
- goto no_label;
+ r = socket_load_service_unit(s, -1, &service);
+ if (r == -ENODATA)
+ goto no_label;
+ if (r < 0)
+ return r;
- } else {
- /* Otherwise, get it from the executable we are about to start. */
+ exec_context = SERVICE(service)->exec_context.selinux_context;
+ if (exec_context) {
+ char *con;
- Unit *service;
- ExecCommand *c;
- _cleanup_free_ char *path = NULL;
-
- r = socket_load_service_unit(s, -1, &service);
- if (r == -ENODATA)
- goto no_label;
- if (r < 0)
- return r;
+ con = strdup(exec_context);
+ if (!con)
+ return -ENOMEM;
- c = SERVICE(service)->exec_command[SERVICE_EXEC_START];
- if (!c)
- goto no_label;
+ *ret = TAKE_PTR(con);
+ return 0;
+ }
- r = chase_symlinks(c->path, SERVICE(service)->exec_context.root_directory, CHASE_PREFIX_ROOT, &path, NULL);
- if (r < 0)
- goto no_label;
+ c = SERVICE(service)->exec_command[SERVICE_EXEC_START];
+ if (!c)
+ goto no_label;
- r = mac_selinux_get_create_label_from_exe(path, ret);
- if (IN_SET(r, -EPERM, -EOPNOTSUPP))
- goto no_label;
- }
+ r = chase_symlinks(c->path, SERVICE(service)->exec_context.root_directory, CHASE_PREFIX_ROOT, &path, NULL);
+ if (r < 0)
+ goto no_label;
+ r = mac_selinux_get_create_label_from_exe(path, ret);
+ if (IN_SET(r, -EPERM, -EOPNOTSUPP))
+ goto no_label;
return r;
no_label:
const SocketAddress *address,
const char *label) {
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
int fd, r;
pid_t pid;
_cleanup_(socket_close_fdsp) Socket *s = orig_s;
_cleanup_(mac_selinux_freep) char *label = NULL;
bool know_label = false;
- SocketPort *p;
int r;
assert(s);
}
static void socket_unwatch_fds(Socket *s) {
- SocketPort *p;
int r;
assert(s);
}
static int socket_watch_fds(Socket *s) {
- SocketPort *p;
int r;
assert(s);
static int socket_check_open(Socket *s) {
bool have_open = false, have_closed = false;
- SocketPort *p;
assert(s);
_cleanup_(exec_params_clear) ExecParameters exec_params = {
.flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
- .stdin_fd = -1,
- .stdout_fd = -1,
- .stderr_fd = -1,
- .exec_fd = -1,
+ .stdin_fd = -EBADF,
+ .stdout_fd = -EBADF,
+ .stderr_fd = -EBADF,
+ .exec_fd = -EBADF,
};
pid_t pid;
int r;
if (r == 0) {
uid_t uid = UID_INVALID;
gid_t gid = GID_INVALID;
- SocketPort *p;
/* Child */
}
static void flush_ports(Socket *s) {
- SocketPort *p;
+ assert(s);
/* Flush all incoming traffic, regardless if actual bytes or new connections, so that this socket isn't busy
* anymore */
s->n_accepted++;
- r = service_set_socket_fd(SERVICE(service), cfd, s, s->selinux_context_from_net);
+ r = service_set_socket_fd(SERVICE(service), cfd, s, p, s->selinux_context_from_net);
if (ERRNO_IS_DISCONNECT(r))
return;
if (r < 0)
TAKE_FD(cfd); /* We passed ownership of the fd to the service now. Forget it here. */
s->n_connections++;
- SERVICE(service)->peer = TAKE_PTR(p); /* Pass ownership of the peer reference */
-
r = manager_add_job(UNIT(s)->manager, JOB_START, service, JOB_REPLACE, NULL, &error, NULL);
if (r < 0) {
/* We failed to activate the new service, but it still exists. Let's make sure the
static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
Socket *s = SOCKET(u);
- SocketPort *p;
int r;
assert(u);
}
} else if (streq(key, "fifo")) {
int fd, skip = 0;
- SocketPort *p;
if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
log_unit_debug(u, "Failed to parse fifo value: %s", value);
} else if (streq(key, "special")) {
int fd, skip = 0;
- SocketPort *p;
if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
log_unit_debug(u, "Failed to parse special value: %s", value);
} else if (streq(key, "mqueue")) {
int fd, skip = 0;
- SocketPort *p;
if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
log_unit_debug(u, "Failed to parse mqueue value: %s", value);
} else if (streq(key, "socket")) {
int fd, type, skip = 0;
- SocketPort *p;
if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd))
log_unit_debug(u, "Failed to parse socket value: %s", value);
} else if (streq(key, "netlink")) {
int fd, skip = 0;
- SocketPort *p;
if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
log_unit_debug(u, "Failed to parse socket value: %s", value);
} else if (streq(key, "ffs")) {
int fd, skip = 0;
- SocketPort *p;
if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
log_unit_debug(u, "Failed to parse ffs value: %s", value);
static void socket_distribute_fds(Unit *u, FDSet *fds) {
Socket *s = SOCKET(u);
- SocketPort *p;
assert(u);
}
static int socket_accept_in_cgroup(Socket *s, SocketPort *p, int fd) {
- _cleanup_close_pair_ int pair[2] = { -1, -1 };
+ _cleanup_close_pair_ int pair[2] = PIPE_EBADF;
int cfd, r;
pid_t pid;
}
static int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
- SocketPort *p = userdata;
- int cfd = -1;
+ SocketPort *p = ASSERT_PTR(userdata);
+ int cfd = -EBADF;
- assert(p);
assert(fd >= 0);
if (p->socket->state != SOCKET_LISTENING)
int socket_collect_fds(Socket *s, int **fds) {
size_t k = 0, n = 0;
- SocketPort *p;
int *rfds;
assert(s);
return exec_context_get_clean_mask(&s->exec_context, ret);
}
-static int socket_test_start_limit(Unit *u) {
+static int socket_can_start(Unit *u) {
Socket *s = SOCKET(u);
int r;
return r;
}
- return 0;
+ return 1;
}
static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
},
},
- .test_start_limit = socket_test_start_limit,
+ .can_start = socket_can_start,
};