Bug Summary

File:build-scan/../src/core/socket.c
Warning:line 126, column 17
Use of memory after it is freed

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name socket.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -fhalf-no-semantic-interposition -mframe-pointer=all -relaxed-aliasing -menable-no-infs -menable-no-nans -menable-unsafe-fp-math -fno-signed-zeros -mreassociate -freciprocal-math -fdenormal-fp-math=preserve-sign,preserve-sign -ffp-contract=fast -fno-rounding-math -ffast-math -ffinite-math-only -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/12.0.0 -include config.h -I src/core/libcore.a.p -I src/core -I ../src/core -I src/basic -I ../src/basic -I src/shared -I ../src/shared -I src/systemd -I ../src/systemd -I src/journal -I ../src/journal -I src/journal-remote -I ../src/journal-remote -I src/nspawn -I ../src/nspawn -I src/resolve -I ../src/resolve -I src/timesync -I ../src/timesync -I ../src/time-wait-sync -I src/login -I ../src/login -I src/udev -I ../src/udev -I src/libudev -I ../src/libudev -I ../src/libsystemd/sd-bus -I ../src/libsystemd/sd-device -I ../src/libsystemd/sd-hwdb -I ../src/libsystemd/sd-id128 -I ../src/libsystemd/sd-netlink -I ../src/libsystemd/sd-network -I src/libsystemd-network -I ../src/libsystemd-network -I . -I .. -I /usr/include/libmount -I /usr/include/blkid -D _FILE_OFFSET_BITS=64 -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/12.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -Wwrite-strings -Wno-unused-parameter -Wno-missing-field-initializers -Wno-unused-result -Wno-format-signedness -Wno-error=nonnull -std=gnu99 -fconst-strings -fdebug-compilation-dir /home/mrc0mmand/repos/@redhat-plumbers/systemd-rhel8/build-scan -ferror-limit 19 -fvisibility hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcolor-diagnostics -analyzer-output=html -faddrsig -o /tmp/scan-build-2021-07-16-221226-1465241-1 -x c ../src/core/socket.c
1/* SPDX-License-Identifier: LGPL-2.1+ */
2
3#include <arpa/inet.h>
4#include <errno(*__errno_location ()).h>
5#include <fcntl.h>
6#include <mqueue.h>
7#include <netinet/tcp.h>
8#include <signal.h>
9#include <sys/epoll.h>
10#include <sys/stat.h>
11#include <unistd.h>
12#include <linux1/sctp.h>
13
14#include "alloc-util.h"
15#include "bpf-firewall.h"
16#include "bus-error.h"
17#include "bus-util.h"
18#include "copy.h"
19#include "dbus-socket.h"
20#include "def.h"
21#include "exit-status.h"
22#include "fd-util.h"
23#include "format-util.h"
24#include "fs-util.h"
25#include "in-addr-util.h"
26#include "io-util.h"
27#include "label.h"
28#include "log.h"
29#include "missing.h"
30#include "mkdir.h"
31#include "parse-util.h"
32#include "path-util.h"
33#include "process-util.h"
34#include "selinux-util.h"
35#include "signal-util.h"
36#include "smack-util.h"
37#include "socket.h"
38#include "socket-protocol-list.h"
39#include "special.h"
40#include "string-table.h"
41#include "string-util.h"
42#include "strv.h"
43#include "unit-name.h"
44#include "unit.h"
45#include "user-util.h"
46
47struct SocketPeer {
48 unsigned n_ref;
49
50 Socket *socket;
51 union sockaddr_union peer;
52 socklen_t peer_salen;
53};
54
55static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
56 [SOCKET_DEAD] = UNIT_INACTIVE,
57 [SOCKET_START_PRE] = UNIT_ACTIVATING,
58 [SOCKET_START_CHOWN] = UNIT_ACTIVATING,
59 [SOCKET_START_POST] = UNIT_ACTIVATING,
60 [SOCKET_LISTENING] = UNIT_ACTIVE,
61 [SOCKET_RUNNING] = UNIT_ACTIVE,
62 [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
63 [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
64 [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
65 [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
66 [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING,
67 [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING,
68 [SOCKET_FAILED] = UNIT_FAILED
69};
70
71static int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata);
72static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata);
73static void flush_ports(Socket *s);
74
75static void socket_init(Unit *u) {
76 Socket *s = SOCKET(u);
77
78 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/socket.c", 78, __PRETTY_FUNCTION__
); } while (0)
;
79 assert(u->load_state == UNIT_STUB)do { if ((__builtin_expect(!!(!(u->load_state == UNIT_STUB
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("u->load_state == UNIT_STUB"
), "../src/core/socket.c", 79, __PRETTY_FUNCTION__); } while (
0)
;
80
81 s->backlog = SOMAXCONN4096;
82 s->timeout_usec = u->manager->default_timeout_start_usec;
83 s->directory_mode = 0755;
84 s->socket_mode = 0666;
85
86 s->max_connections = 64;
87
88 s->priority = -1;
89 s->ip_tos = -1;
90 s->ip_ttl = -1;
91 s->mark = -1;
92
93 s->exec_context.std_output = u->manager->default_std_output;
94 s->exec_context.std_error = u->manager->default_std_error;
95
96 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
97
98 s->trigger_limit.interval = USEC_INFINITY((usec_t) -1);
99 s->trigger_limit.burst = (unsigned) -1;
100}
101
102static void socket_unwatch_control_pid(Socket *s) {
103 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 103, __PRETTY_FUNCTION__
); } while (0)
;
104
105 if (s->control_pid <= 0)
106 return;
107
108 unit_unwatch_pid(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, s->control_pid);
109 s->control_pid = 0;
110}
111
112static void socket_cleanup_fd_list(SocketPort *p) {
113 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/core/socket.c", 113, __PRETTY_FUNCTION__
); } while (0)
;
114
115 close_many(p->auxiliary_fds, p->n_auxiliary_fds);
116 p->auxiliary_fds = mfree(p->auxiliary_fds);
117 p->n_auxiliary_fds = 0;
118}
119
120void socket_free_ports(Socket *s) {
121 SocketPort *p;
122
123 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 123, __PRETTY_FUNCTION__
); } while (0)
;
4
Taking false branch
5
Loop condition is false. Exiting loop
124
125 while ((p = s->ports)) {
6
Loop condition is true. Entering loop body
15
Loop condition is true. Entering loop body
126 LIST_REMOVE(port, s->ports, p)do { typeof(*(s->ports)) **_head = &(s->ports), *_item
= (p); do { if ((__builtin_expect(!!(!(_item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_item"), "../src/core/socket.c", 126, __PRETTY_FUNCTION__
); } while (0); if (_item->port_next) _item->port_next->
port_prev = _item->port_prev; if (_item->port_prev) _item
->port_prev->port_next = _item->port_next; else { do
{ if ((__builtin_expect(!!(!(*_head == _item)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("*_head == _item"), "../src/core/socket.c"
, 126, __PRETTY_FUNCTION__); } while (0); *_head = _item->
port_next; } _item->port_next = _item->port_prev = ((void
*)0); } while (0)
;
7
Taking false branch
8
Loop condition is false. Exiting loop
9
Assuming field 'port_next' is null
10
Taking false branch
11
Assuming field 'port_prev' is non-null
12
Taking true branch
13
Loop condition is false. Exiting loop
16
Taking false branch
17
Loop condition is false. Exiting loop
18
Use of memory after it is freed
127
128 sd_event_source_unref(p->event_source);
129
130 socket_cleanup_fd_list(p);
131 safe_close(p->fd);
132 free(p->path);
133 free(p);
14
Memory is released
134 }
135}
136
137static void socket_done(Unit *u) {
138 Socket *s = SOCKET(u);
139 SocketPeer *p;
140
141 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 141, __PRETTY_FUNCTION__
); } while (0)
;
1
Taking false branch
2
Loop condition is false. Exiting loop
142
143 socket_free_ports(s);
3
Calling 'socket_free_ports'
144
145 while ((p = set_steal_first(s->peers_by_address)))
146 p->socket = NULL((void*)0);
147
148 s->peers_by_address = set_free(s->peers_by_address);
149
150 s->exec_runtime = exec_runtime_unref(s->exec_runtime, false0);
151 exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
152 s->control_command = NULL((void*)0);
153
154 dynamic_creds_unref(&s->dynamic_creds);
155
156 socket_unwatch_control_pid(s);
157
158 unit_ref_unset(&s->service);
159
160 s->tcp_congestion = mfree(s->tcp_congestion);
161 s->bind_to_device = mfree(s->bind_to_device);
162
163 s->smack = mfree(s->smack);
164 s->smack_ip_in = mfree(s->smack_ip_in);
165 s->smack_ip_out = mfree(s->smack_ip_out);
166
167 strv_free(s->symlinks);
168
169 s->user = mfree(s->user);
170 s->group = mfree(s->group);
171
172 s->fdname = mfree(s->fdname);
173
174 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
175}
176
177static int socket_arm_timer(Socket *s, usec_t usec) {
178 int r;
179
180 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 180, __PRETTY_FUNCTION__
); } while (0)
;
181
182 if (s->timer_event_source) {
183 r = sd_event_source_set_time(s->timer_event_source, usec);
184 if (r < 0)
185 return r;
186
187 return sd_event_source_set_enabled(s->timer_event_source, SD_EVENT_ONESHOT);
188 }
189
190 if (usec == USEC_INFINITY((usec_t) -1))
191 return 0;
192
193 r = sd_event_add_time(
194 UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->manager->event,
195 &s->timer_event_source,
196 CLOCK_MONOTONIC1,
197 usec, 0,
198 socket_dispatch_timer, s);
199 if (r < 0)
200 return r;
201
202 (void) sd_event_source_set_description(s->timer_event_source, "socket-timer");
203
204 return 0;
205}
206
207int socket_instantiate_service(Socket *s) {
208 _cleanup_free___attribute__((cleanup(freep))) char *prefix = NULL((void*)0), *name = NULL((void*)0);
209 int r;
210 Unit *u;
211
212 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 212, __PRETTY_FUNCTION__
); } while (0)
;
213
214 /* This fills in s->service if it isn't filled in yet. For
215 * Accept=yes sockets we create the next connection service
216 * here. For Accept=no this is mostly a NOP since the service
217 * is figured out at load time anyway. */
218
219 if (UNIT_DEREF(s->service)((s->service).target))
220 return 0;
221
222 if (!s->accept)
223 return 0;
224
225 r = unit_name_to_prefix(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->id, &prefix);
226 if (r < 0)
227 return r;
228
229 if (asprintf(&name, "%s@%u.service", prefix, s->n_accepted) < 0)
230 return -ENOMEM12;
231
232 r = manager_load_unit(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->manager, name, NULL((void*)0), NULL((void*)0), &u);
233 if (r < 0)
234 return r;
235
236 unit_ref_set(&s->service, UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, u);
237
238 return unit_add_two_dependencies(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, UNIT_BEFORE, UNIT_TRIGGERS, u, false0, UNIT_DEPENDENCY_IMPLICIT);
239}
240
241static bool_Bool have_non_accept_socket(Socket *s) {
242 SocketPort *p;
243
244 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 244, __PRETTY_FUNCTION__
); } while (0)
;
245
246 if (!s->accept)
247 return true1;
248
249 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
250
251 if (p->type != SOCKET_SOCKET)
252 return true1;
253
254 if (!socket_address_can_accept(&p->address))
255 return true1;
256 }
257
258 return false0;
259}
260
261static int socket_add_mount_dependencies(Socket *s) {
262 SocketPort *p;
263 int r;
264
265 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 265, __PRETTY_FUNCTION__
); } while (0)
;
266
267 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
268 const char *path = NULL((void*)0);
269
270 if (p->type == SOCKET_SOCKET)
271 path = socket_address_get_path(&p->address);
272 else if (IN_SET(p->type, SOCKET_FIFO, SOCKET_SPECIAL, SOCKET_USB_FUNCTION)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_FIFO, SOCKET_SPECIAL, SOCKET_USB_FUNCTION
})/sizeof(int)]; switch(p->type) { case SOCKET_FIFO: case SOCKET_SPECIAL
: case SOCKET_USB_FUNCTION: _found = 1; break; default: break
; } _found; })
)
273 path = p->path;
274
275 if (!path)
276 continue;
277
278 r = unit_require_mounts_for(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, path, UNIT_DEPENDENCY_FILE);
279 if (r < 0)
280 return r;
281 }
282
283 return 0;
284}
285
286static int socket_add_device_dependencies(Socket *s) {
287 char *t;
288
289 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 289, __PRETTY_FUNCTION__
); } while (0)
;
290
291 if (!s->bind_to_device || streq(s->bind_to_device, "lo")(strcmp((s->bind_to_device),("lo")) == 0))
292 return 0;
293
294 t = strjoina("/sys/subsystem/net/devices/", s->bind_to_device)({ const char *_appendees_[] = { "/sys/subsystem/net/devices/"
, s->bind_to_device }; char *_d_, *_p_; size_t _len_ = 0; size_t
_i_; for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _len_ += strlen
(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca (_len_ + 1);
for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr(
!__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
295 return unit_add_node_dependency(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, t, false0, UNIT_BINDS_TO, UNIT_DEPENDENCY_FILE);
296}
297
298static int socket_add_default_dependencies(Socket *s) {
299 int r;
300 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 300, __PRETTY_FUNCTION__
); } while (0)
;
301
302 if (!UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->default_dependencies)
303 return 0;
304
305 r = unit_add_dependency_by_name(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, UNIT_BEFORE, SPECIAL_SOCKETS_TARGET"sockets.target", NULL((void*)0), true1, UNIT_DEPENDENCY_DEFAULT);
306 if (r < 0)
307 return r;
308
309 if (MANAGER_IS_SYSTEM(UNIT(s)->manager)((({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })->manager)->unit_file_scope == UNIT_FILE_SYSTEM
)
) {
310 r = unit_add_two_dependencies_by_name(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET"sysinit.target", NULL((void*)0), true1, UNIT_DEPENDENCY_DEFAULT);
311 if (r < 0)
312 return r;
313 }
314
315 return unit_add_two_dependencies_by_name(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET"shutdown.target", NULL((void*)0), true1, UNIT_DEPENDENCY_DEFAULT);
316}
317
318_pure___attribute__ ((pure)) static bool_Bool socket_has_exec(Socket *s) {
319 unsigned i;
320 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 320, __PRETTY_FUNCTION__
); } while (0)
;
321
322 for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
323 if (s->exec_command[i])
324 return true1;
325
326 return false0;
327}
328
329static int socket_add_extras(Socket *s) {
330 Unit *u = UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
;
331 int r;
332
333 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 333, __PRETTY_FUNCTION__
); } while (0)
;
334
335 /* Pick defaults for the trigger limit, if nothing was explicitly configured. We pick a relatively high limit
336 * in Accept=yes mode, and a lower limit for Accept=no. Reason: in Accept=yes mode we are invoking accept()
337 * ourselves before the trigger limit can hit, thus incoming connections are taken off the socket queue quickly
338 * and reliably. This is different for Accept=no, where the spawned service has to take the incoming traffic
339 * off the queues, which it might not necessarily do. Moreover, while Accept=no services are supposed to
340 * process whatever is queued in one go, and thus should normally never have to be started frequently. This is
341 * different for Accept=yes where each connection is processed by a new service instance, and thus frequent
342 * service starts are typical. */
343
344 if (s->trigger_limit.interval == USEC_INFINITY((usec_t) -1))
345 s->trigger_limit.interval = 2 * USEC_PER_SEC((usec_t) 1000000ULL);
346
347 if (s->trigger_limit.burst == (unsigned) -1) {
348 if (s->accept)
349 s->trigger_limit.burst = 200;
350 else
351 s->trigger_limit.burst = 20;
352 }
353
354 if (have_non_accept_socket(s)) {
355
356 if (!UNIT_DEREF(s->service)((s->service).target)) {
357 Unit *x;
358
359 r = unit_load_related_unit(u, ".service", &x);
360 if (r < 0)
361 return r;
362
363 unit_ref_set(&s->service, u, x);
364 }
365
366 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service)((s->service).target), true1, UNIT_DEPENDENCY_IMPLICIT);
367 if (r < 0)
368 return r;
369 }
370
371 r = socket_add_mount_dependencies(s);
372 if (r < 0)
373 return r;
374
375 r = socket_add_device_dependencies(s);
376 if (r < 0)
377 return r;
378
379 r = unit_patch_contexts(u);
380 if (r < 0)
381 return r;
382
383 if (socket_has_exec(s)) {
384 r = unit_add_exec_dependencies(u, &s->exec_context);
385 if (r < 0)
386 return r;
387 }
388
389 r = unit_set_default_slice(u);
390 if (r < 0)
391 return r;
392
393 r = socket_add_default_dependencies(s);
394 if (r < 0)
395 return r;
396
397 return 0;
398}
399
400static const char *socket_find_symlink_target(Socket *s) {
401 const char *found = NULL((void*)0);
402 SocketPort *p;
403
404 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
405 const char *f = NULL((void*)0);
406
407 switch (p->type) {
408
409 case SOCKET_FIFO:
410 f = p->path;
411 break;
412
413 case SOCKET_SOCKET:
414 f = socket_address_get_path(&p->address);
415 break;
416
417 default:
418 break;
419 }
420
421 if (f) {
422 if (found)
423 return NULL((void*)0);
424
425 found = f;
426 }
427 }
428
429 return found;
430}
431
432static int socket_verify(Socket *s) {
433 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 433, __PRETTY_FUNCTION__
); } while (0)
;
434
435 if (UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->load_state != UNIT_LOADED)
436 return 0;
437
438 if (!s->ports) {
439 log_unit_error(UNIT(s), "Unit has no Listen setting (ListenStream=, ListenDatagram=, ListenFIFO=, ...). Refusing.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, 0, "../src/core/socket.c", 439, __func__, _u->manager->
unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Unit has no Listen setting (ListenStream=, ListenDatagram=, ListenFIFO=, ...). Refusing."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/core/socket.c", 439, __func__, "Unit has no Listen setting (ListenStream=, ListenDatagram=, ListenFIFO=, ...). Refusing."
); })
;
440 return -ENOEXEC8;
441 }
442
443 if (s->accept && have_non_accept_socket(s)) {
444 log_unit_error(UNIT(s), "Unit configured for accepting sockets, but sockets are non-accepting. Refusing.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, 0, "../src/core/socket.c", 444, __func__, _u->manager->
unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Unit configured for accepting sockets, but sockets are non-accepting. Refusing."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/core/socket.c", 444, __func__, "Unit configured for accepting sockets, but sockets are non-accepting. Refusing."
); })
;
445 return -ENOEXEC8;
446 }
447
448 if (s->accept && s->max_connections <= 0) {
449 log_unit_error(UNIT(s), "MaxConnection= setting too small. Refusing.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, 0, "../src/core/socket.c", 449, __func__, _u->manager->
unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "MaxConnection= setting too small. Refusing."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/core/socket.c", 449, __func__, "MaxConnection= setting too small. Refusing."
); })
;
450 return -ENOEXEC8;
451 }
452
453 if (s->accept && UNIT_DEREF(s->service)((s->service).target)) {
454 log_unit_error(UNIT(s), "Explicit service configuration for accepting socket units not supported. Refusing.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, 0, "../src/core/socket.c", 454, __func__, _u->manager->
unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Explicit service configuration for accepting socket units not supported. Refusing."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/core/socket.c", 454, __func__, "Explicit service configuration for accepting socket units not supported. Refusing."
); })
;
455 return -ENOEXEC8;
456 }
457
458 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
459 log_unit_error(UNIT(s), "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, 0, "../src/core/socket.c", 459, __func__, _u->manager->
unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/core/socket.c", 459, __func__, "Unit has PAM enabled. Kill mode must be set to 'control-group'. Refusing."
); })
;
460 return -ENOEXEC8;
461 }
462
463 if (!strv_isempty(s->symlinks) && !socket_find_symlink_target(s)) {
464 log_unit_error(UNIT(s), "Unit has symlinks set but none or more than one node in the file system. Refusing.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, 0, "../src/core/socket.c", 464, __func__, _u->manager->
unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Unit has symlinks set but none or more than one node in the file system. Refusing."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/core/socket.c", 464, __func__, "Unit has symlinks set but none or more than one node in the file system. Refusing."
); })
;
465 return -ENOEXEC8;
466 }
467
468 return 0;
469}
470
471static void peer_address_hash_func(const void *p, struct siphash *state) {
472 const SocketPeer *s = p;
473
474 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 474, __PRETTY_FUNCTION__
); } while (0)
;
475
476 if (s->peer.sa.sa_family == AF_INET2)
477 siphash24_compress(&s->peer.in.sin_addr, sizeof(s->peer.in.sin_addr), state);
478 else if (s->peer.sa.sa_family == AF_INET610)
479 siphash24_compress(&s->peer.in6.sin6_addr, sizeof(s->peer.in6.sin6_addr), state);
480 else if (s->peer.sa.sa_family == AF_VSOCK40)
481 siphash24_compress(&s->peer.vm.svm_cid, sizeof(s->peer.vm.svm_cid), state);
482 else
483 assert_not_reached("Unknown address family.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unknown address family."), "../src/core/socket.c", 483, __PRETTY_FUNCTION__
); } while (0)
;
484}
485
486static int peer_address_compare_func(const void *a, const void *b) {
487 const SocketPeer *x = a, *y = b;
488
489 if (x->peer.sa.sa_family < y->peer.sa.sa_family)
490 return -1;
491 if (x->peer.sa.sa_family > y->peer.sa.sa_family)
492 return 1;
493
494 switch(x->peer.sa.sa_family) {
495 case AF_INET2:
496 return memcmp(&x->peer.in.sin_addr, &y->peer.in.sin_addr, sizeof(x->peer.in.sin_addr));
497 case AF_INET610:
498 return memcmp(&x->peer.in6.sin6_addr, &y->peer.in6.sin6_addr, sizeof(x->peer.in6.sin6_addr));
499 case AF_VSOCK40:
500 if (x->peer.vm.svm_cid < y->peer.vm.svm_cid)
501 return -1;
502 if (x->peer.vm.svm_cid > y->peer.vm.svm_cid)
503 return 1;
504 return 0;
505 }
506 assert_not_reached("Black sheep in the family!")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Black sheep in the family!"), "../src/core/socket.c", 506, __PRETTY_FUNCTION__
); } while (0)
;
507}
508
509const struct hash_ops peer_address_hash_ops = {
510 .hash = peer_address_hash_func,
511 .compare = peer_address_compare_func
512};
513
514static int socket_load(Unit *u) {
515 Socket *s = SOCKET(u);
516 int r;
517
518 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/socket.c", 518, __PRETTY_FUNCTION__
); } while (0)
;
519 assert(u->load_state == UNIT_STUB)do { if ((__builtin_expect(!!(!(u->load_state == UNIT_STUB
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("u->load_state == UNIT_STUB"
), "../src/core/socket.c", 519, __PRETTY_FUNCTION__); } while
(0)
;
520
521 r = set_ensure_allocated(&s->peers_by_address, &peer_address_hash_ops)internal_set_ensure_allocated(&s->peers_by_address, &
peer_address_hash_ops )
;
522 if (r < 0)
523 return r;
524
525 r = unit_load_fragment_and_dropin(u);
526 if (r < 0)
527 return r;
528
529 if (u->load_state == UNIT_LOADED) {
530 /* This is a new unit? Then let's add in some extras */
531 r = socket_add_extras(s);
532 if (r < 0)
533 return r;
534 }
535
536 return socket_verify(s);
537}
538
539static SocketPeer *socket_peer_new(void) {
540 SocketPeer *p;
541
542 p = new0(SocketPeer, 1)((SocketPeer*) calloc((1), sizeof(SocketPeer)));
543 if (!p)
544 return NULL((void*)0);
545
546 p->n_ref = 1;
547
548 return p;
549}
550
551SocketPeer *socket_peer_ref(SocketPeer *p) {
552 if (!p)
553 return NULL((void*)0);
554
555 assert(p->n_ref > 0)do { if ((__builtin_expect(!!(!(p->n_ref > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p->n_ref > 0"), "../src/core/socket.c"
, 555, __PRETTY_FUNCTION__); } while (0)
;
556 p->n_ref++;
557
558 return p;
559}
560
561SocketPeer *socket_peer_unref(SocketPeer *p) {
562 if (!p)
563 return NULL((void*)0);
564
565 assert(p->n_ref > 0)do { if ((__builtin_expect(!!(!(p->n_ref > 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p->n_ref > 0"), "../src/core/socket.c"
, 565, __PRETTY_FUNCTION__); } while (0)
;
566
567 p->n_ref--;
568
569 if (p->n_ref > 0)
570 return NULL((void*)0);
571
572 if (p->socket)
573 set_remove(p->socket->peers_by_address, p);
574
575 return mfree(p);
576}
577
578int socket_acquire_peer(Socket *s, int fd, SocketPeer **p) {
579 _cleanup_(socket_peer_unrefp)__attribute__((cleanup(socket_peer_unrefp))) SocketPeer *remote = NULL((void*)0);
580 SocketPeer sa = {}, *i;
581 socklen_t salen = sizeof(sa.peer);
582 int r;
583
584 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/core/socket.c", 584
, __PRETTY_FUNCTION__); } while (0)
;
585 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 585, __PRETTY_FUNCTION__
); } while (0)
;
586
587 r = getpeername(fd, &sa.peer.sa, &salen);
588 if (r < 0)
589 return log_error_errno(errno, "getpeername failed: %m")({ int _level = ((3)), _e = (((*__errno_location ()))), _realm
= (LOG_REALM_SYSTEMD); (log_get_max_level_realm(_realm) >=
((_level) & 0x07)) ? log_internal_realm(((_realm) <<
10 | (_level)), _e, "../src/core/socket.c", 589, __func__, "getpeername failed: %m"
) : -abs(_e); })
;
590
591 if (!IN_SET(sa.peer.sa.sa_family, AF_INET, AF_INET6, AF_VSOCK)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 10, 40})/sizeof(int)]; switch(sa.peer
.sa.sa_family) { case 2: case 10: case 40: _found = 1; break;
default: break; } _found; })
) {
592 *p = NULL((void*)0);
593 return 0;
594 }
595
596 i = set_get(s->peers_by_address, &sa);
597 if (i) {
598 *p = socket_peer_ref(i);
599 return 1;
600 }
601
602 remote = socket_peer_new();
603 if (!remote)
604 return log_oom()log_oom_internal(LOG_REALM_SYSTEMD, "../src/core/socket.c", 604
, __func__)
;
605
606 remote->peer = sa.peer;
607 remote->peer_salen = salen;
608
609 r = set_put(s->peers_by_address, remote);
610 if (r < 0)
611 return r;
612
613 remote->socket = s;
614
615 *p = TAKE_PTR(remote)({ typeof(remote) _ptr_ = (remote); (remote) = ((void*)0); _ptr_
; })
;
616
617 return 1;
618}
619
620_const___attribute__ ((const)) static const char* listen_lookup(int family, int type) {
621
622 if (family == AF_NETLINK16)
623 return "ListenNetlink";
624
625 if (type == SOCK_STREAMSOCK_STREAM)
626 return "ListenStream";
627 else if (type == SOCK_DGRAMSOCK_DGRAM)
628 return "ListenDatagram";
629 else if (type == SOCK_SEQPACKETSOCK_SEQPACKET)
630 return "ListenSequentialPacket";
631
632 assert_not_reached("Unknown socket type")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unknown socket type"), "../src/core/socket.c", 632, __PRETTY_FUNCTION__
); } while (0)
;
633 return NULL((void*)0);
634}
635
636static void socket_dump(Unit *u, FILE *f, const char *prefix) {
637 char time_string[FORMAT_TIMESPAN_MAX64];
638 SocketExecCommand c;
639 Socket *s = SOCKET(u);
640 SocketPort *p;
641 const char *prefix2, *str;
642
643 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 643, __PRETTY_FUNCTION__
); } while (0)
;
644 assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("f"), "../src/core/socket.c", 644, __PRETTY_FUNCTION__
); } while (0)
;
645
646 prefix = strempty(prefix);
647 prefix2 = strjoina(prefix, "\t")({ const char *_appendees_[] = { prefix, "\t" }; char *_d_, *
_p_; size_t _len_ = 0; size_t _i_; for (_i_ = 0; _i_ < __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(_appendees_), typeof(&*(_appendees_))), sizeof(_appendees_
)/sizeof((_appendees_)[0]), ((void)0))) && _appendees_
[_i_]; _i_++) _len_ += strlen(_appendees_[_i_]); _p_ = _d_ = __builtin_alloca
(_len_ + 1); for (_i_ = 0; _i_ < __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(_appendees_), typeof(&
*(_appendees_))), sizeof(_appendees_)/sizeof((_appendees_)[0]
), ((void)0))) && _appendees_[_i_]; _i_++) _p_ = stpcpy
(_p_, _appendees_[_i_]); *_p_ = 0; _d_; })
;
648
649 fprintf(f,
650 "%sSocket State: %s\n"
651 "%sResult: %s\n"
652 "%sBindIPv6Only: %s\n"
653 "%sBacklog: %u\n"
654 "%sSocketMode: %04o\n"
655 "%sDirectoryMode: %04o\n"
656 "%sKeepAlive: %s\n"
657 "%sNoDelay: %s\n"
658 "%sFreeBind: %s\n"
659 "%sTransparent: %s\n"
660 "%sBroadcast: %s\n"
661 "%sPassCredentials: %s\n"
662 "%sPassSecurity: %s\n"
663 "%sPassPacketInfo: %s\n"
664 "%sTCPCongestion: %s\n"
665 "%sRemoveOnStop: %s\n"
666 "%sWritable: %s\n"
667 "%sFileDescriptorName: %s\n"
668 "%sSELinuxContextFromNet: %s\n",
669 prefix, socket_state_to_string(s->state),
670 prefix, socket_result_to_string(s->result),
671 prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
672 prefix, s->backlog,
673 prefix, s->socket_mode,
674 prefix, s->directory_mode,
675 prefix, yes_no(s->keep_alive),
676 prefix, yes_no(s->no_delay),
677 prefix, yes_no(s->free_bind),
678 prefix, yes_no(s->transparent),
679 prefix, yes_no(s->broadcast),
680 prefix, yes_no(s->pass_cred),
681 prefix, yes_no(s->pass_sec),
682 prefix, yes_no(s->pass_pktinfo),
683 prefix, strna(s->tcp_congestion),
684 prefix, yes_no(s->remove_on_stop),
685 prefix, yes_no(s->writable),
686 prefix, socket_fdname(s),
687 prefix, yes_no(s->selinux_context_from_net));
688
689 if (s->control_pid > 0)
690 fprintf(f,
691 "%sControl PID: "PID_FMT"%" "i""\n",
692 prefix, s->control_pid);
693
694 if (s->bind_to_device)
695 fprintf(f,
696 "%sBindToDevice: %s\n",
697 prefix, s->bind_to_device);
698
699 if (s->accept)
700 fprintf(f,
701 "%sAccepted: %u\n"
702 "%sNConnections: %u\n"
703 "%sMaxConnections: %u\n"
704 "%sMaxConnectionsPerSource: %u\n",
705 prefix, s->n_accepted,
706 prefix, s->n_connections,
707 prefix, s->max_connections,
708 prefix, s->max_connections_per_source);
709 else
710 fprintf(f,
711 "%sFlushPending: %s\n",
712 prefix, yes_no(s->flush_pending));
713
714
715 if (s->priority >= 0)
716 fprintf(f,
717 "%sPriority: %i\n",
718 prefix, s->priority);
719
720 if (s->receive_buffer > 0)
721 fprintf(f,
722 "%sReceiveBuffer: %zu\n",
723 prefix, s->receive_buffer);
724
725 if (s->send_buffer > 0)
726 fprintf(f,
727 "%sSendBuffer: %zu\n",
728 prefix, s->send_buffer);
729
730 if (s->ip_tos >= 0)
731 fprintf(f,
732 "%sIPTOS: %i\n",
733 prefix, s->ip_tos);
734
735 if (s->ip_ttl >= 0)
736 fprintf(f,
737 "%sIPTTL: %i\n",
738 prefix, s->ip_ttl);
739
740 if (s->pipe_size > 0)
741 fprintf(f,
742 "%sPipeSize: %zu\n",
743 prefix, s->pipe_size);
744
745 if (s->mark >= 0)
746 fprintf(f,
747 "%sMark: %i\n",
748 prefix, s->mark);
749
750 if (s->mq_maxmsg > 0)
751 fprintf(f,
752 "%sMessageQueueMaxMessages: %li\n",
753 prefix, s->mq_maxmsg);
754
755 if (s->mq_msgsize > 0)
756 fprintf(f,
757 "%sMessageQueueMessageSize: %li\n",
758 prefix, s->mq_msgsize);
759
760 if (s->reuse_port)
761 fprintf(f,
762 "%sReusePort: %s\n",
763 prefix, yes_no(s->reuse_port));
764
765 if (s->smack)
766 fprintf(f,
767 "%sSmackLabel: %s\n",
768 prefix, s->smack);
769
770 if (s->smack_ip_in)
771 fprintf(f,
772 "%sSmackLabelIPIn: %s\n",
773 prefix, s->smack_ip_in);
774
775 if (s->smack_ip_out)
776 fprintf(f,
777 "%sSmackLabelIPOut: %s\n",
778 prefix, s->smack_ip_out);
779
780 if (!isempty(s->user) || !isempty(s->group))
781 fprintf(f,
782 "%sSocketUser: %s\n"
783 "%sSocketGroup: %s\n",
784 prefix, strna(s->user),
785 prefix, strna(s->group));
786
787 if (s->keep_alive_time > 0)
788 fprintf(f,
789 "%sKeepAliveTimeSec: %s\n",
790 prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX64, s->keep_alive_time, USEC_PER_SEC((usec_t) 1000000ULL)));
791
792 if (s->keep_alive_interval > 0)
793 fprintf(f,
794 "%sKeepAliveIntervalSec: %s\n",
795 prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX64, s->keep_alive_interval, USEC_PER_SEC((usec_t) 1000000ULL)));
796
797 if (s->keep_alive_cnt > 0)
798 fprintf(f,
799 "%sKeepAliveProbes: %u\n",
800 prefix, s->keep_alive_cnt);
801
802 if (s->defer_accept > 0)
803 fprintf(f,
804 "%sDeferAcceptSec: %s\n",
805 prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX64, s->defer_accept, USEC_PER_SEC((usec_t) 1000000ULL)));
806
807 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
808
809 switch (p->type) {
810 case SOCKET_SOCKET: {
811 _cleanup_free___attribute__((cleanup(freep))) char *k = NULL((void*)0);
812 const char *t;
813 int r;
814
815 r = socket_address_print(&p->address, &k);
816 if (r < 0)
817 t = strerror(-r);
818 else
819 t = k;
820
821 fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address)((&p->address)->sockaddr.sa.sa_family), p->address.type), t);
822 break;
823 }
824 case SOCKET_SPECIAL:
825 fprintf(f, "%sListenSpecial: %s\n", prefix, p->path);
826 break;
827 case SOCKET_USB_FUNCTION:
828 fprintf(f, "%sListenUSBFunction: %s\n", prefix, p->path);
829 break;
830 case SOCKET_MQUEUE:
831 fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path);
832 break;
833 default:
834 fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
835 }
836 }
837
838 fprintf(f,
839 "%sTriggerLimitIntervalSec: %s\n"
840 "%sTriggerLimitBurst: %u\n",
841 prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX64, s->trigger_limit.interval, USEC_PER_SEC((usec_t) 1000000ULL)),
842 prefix, s->trigger_limit.burst);
843
844 str = socket_protocol_to_name(s->socket_protocol);
845 if (str)
846 fprintf(f, "%sSocketProtocol: %s\n", prefix, str);
847
848 if (!strv_isempty(s->symlinks)) {
849 char **q;
850
851 fprintf(f, "%sSymlinks:", prefix);
852 STRV_FOREACH(q, s->symlinks)for ((q) = (s->symlinks); (q) && *(q); (q)++)
853 fprintf(f, " %s", *q);
854
855 fprintf(f, "\n");
856 }
857
858 fprintf(f,
859 "%sTimeoutSec: %s\n",
860 prefix, format_timespan(time_string, FORMAT_TIMESPAN_MAX64, s->timeout_usec, USEC_PER_SEC((usec_t) 1000000ULL)));
861
862 exec_context_dump(&s->exec_context, f, prefix);
863 kill_context_dump(&s->kill_context, f, prefix);
864
865 for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
866 if (!s->exec_command[c])
867 continue;
868
869 fprintf(f, "%s-> %s:\n",
870 prefix, socket_exec_command_to_string(c));
871
872 exec_command_dump_list(s->exec_command[c], f, prefix2);
873 }
874
875 cgroup_context_dump(&s->cgroup_context, f, prefix);
876}
877
878static int instance_from_socket(int fd, unsigned nr, char **instance) {
879 socklen_t l;
880 char *r;
881 union sockaddr_union local, remote;
882
883 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/core/socket.c", 883
, __PRETTY_FUNCTION__); } while (0)
;
884 assert(instance)do { if ((__builtin_expect(!!(!(instance)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("instance"), "../src/core/socket.c", 884
, __PRETTY_FUNCTION__); } while (0)
;
885
886 l = sizeof(local);
887 if (getsockname(fd, &local.sa, &l) < 0)
888 return -errno(*__errno_location ());
889
890 l = sizeof(remote);
891 if (getpeername(fd, &remote.sa, &l) < 0)
892 return -errno(*__errno_location ());
893
894 switch (local.sa.sa_family) {
895
896 case AF_INET2: {
897 uint32_t
898 a = be32toh(local.in.sin_addr.s_addr)__bswap_32 (local.in.sin_addr.s_addr),
899 b = be32toh(remote.in.sin_addr.s_addr)__bswap_32 (remote.in.sin_addr.s_addr);
900
901 if (asprintf(&r,
902 "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
903 nr,
904 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
905 be16toh(local.in.sin_port)__bswap_16 (local.in.sin_port),
906 b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
907 be16toh(remote.in.sin_port)__bswap_16 (remote.in.sin_port)) < 0)
908 return -ENOMEM12;
909
910 break;
911 }
912
913 case AF_INET610: {
914 static const unsigned char ipv4_prefix[] = {
915 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
916 };
917
918 if (memcmp(&local.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0 &&
919 memcmp(&remote.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
920 const uint8_t
921 *a = local.in6.sin6_addr.s6_addr__in6_u.__u6_addr8+12,
922 *b = remote.in6.sin6_addr.s6_addr__in6_u.__u6_addr8+12;
923
924 if (asprintf(&r,
925 "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
926 nr,
927 a[0], a[1], a[2], a[3],
928 be16toh(local.in6.sin6_port)__bswap_16 (local.in6.sin6_port),
929 b[0], b[1], b[2], b[3],
930 be16toh(remote.in6.sin6_port)__bswap_16 (remote.in6.sin6_port)) < 0)
931 return -ENOMEM12;
932 } else {
933 char a[INET6_ADDRSTRLEN46], b[INET6_ADDRSTRLEN46];
934
935 if (asprintf(&r,
936 "%u-%s:%u-%s:%u",
937 nr,
938 inet_ntop(AF_INET610, &local.in6.sin6_addr, a, sizeof(a)),
939 be16toh(local.in6.sin6_port)__bswap_16 (local.in6.sin6_port),
940 inet_ntop(AF_INET610, &remote.in6.sin6_addr, b, sizeof(b)),
941 be16toh(remote.in6.sin6_port)__bswap_16 (remote.in6.sin6_port)) < 0)
942 return -ENOMEM12;
943 }
944
945 break;
946 }
947
948 case AF_UNIX1: {
949 struct ucred ucred;
950 int k;
951
952 k = getpeercred(fd, &ucred);
953 if (k >= 0) {
954 if (asprintf(&r,
955 "%u-"PID_FMT"%" "i""-"UID_FMT"%" "u",
956 nr, ucred.pid, ucred.uid) < 0)
957 return -ENOMEM12;
958 } else if (k == -ENODATA61) {
959 /* This handles the case where somebody is
960 * connecting from another pid/uid namespace
961 * (e.g. from outside of our container). */
962 if (asprintf(&r,
963 "%u-unknown",
964 nr) < 0)
965 return -ENOMEM12;
966 } else
967 return k;
968
969 break;
970 }
971
972 case AF_VSOCK40:
973 if (asprintf(&r,
974 "%u-%u:%u-%u:%u",
975 nr,
976 local.vm.svm_cid, local.vm.svm_port,
977 remote.vm.svm_cid, remote.vm.svm_port) < 0)
978 return -ENOMEM12;
979
980 break;
981
982 default:
983 assert_not_reached("Unhandled socket type.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unhandled socket type."), "../src/core/socket.c", 983, __PRETTY_FUNCTION__
); } while (0)
;
984 }
985
986 *instance = r;
987 return 0;
988}
989
990static void socket_close_fds(Socket *s) {
991 SocketPort *p;
992 char **i;
993
994 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 994, __PRETTY_FUNCTION__
); } while (0)
;
995
996 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
997 bool_Bool was_open;
998
999 was_open = p->fd >= 0;
1000
1001 p->event_source = sd_event_source_unref(p->event_source);
1002 p->fd = safe_close(p->fd);
1003 socket_cleanup_fd_list(p);
1004
1005 /* One little note: we should normally not delete any sockets in the file system here! After all some
1006 * other process we spawned might still have a reference of this fd and wants to continue to use
1007 * it. Therefore we normally delete sockets in the file system before we create a new one, not after we
1008 * stopped using one! That all said, if the user explicitly requested this, we'll delete them here
1009 * anyway, but only then. */
1010
1011 if (!was_open || !s->remove_on_stop)
1012 continue;
1013
1014 switch (p->type) {
1015
1016 case SOCKET_FIFO:
1017 (void) unlink(p->path);
1018 break;
1019
1020 case SOCKET_MQUEUE:
1021 (void) mq_unlink(p->path);
1022 break;
1023
1024 case SOCKET_SOCKET:
1025 (void) socket_address_unlink(&p->address);
1026 break;
1027
1028 default:
1029 break;
1030 }
1031 }
1032
1033 if (s->remove_on_stop)
1034 STRV_FOREACH(i, s->symlinks)for ((i) = (s->symlinks); (i) && *(i); (i)++)
1035 (void) unlink(*i);
1036}
1037
1038static void socket_apply_socket_options(Socket *s, int fd) {
1039 int r;
1040
1041 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1041, __PRETTY_FUNCTION__
); } while (0)
;
1042 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/core/socket.c", 1042
, __PRETTY_FUNCTION__); } while (0)
;
1043
1044 if (s->keep_alive) {
1045 int one = 1;
1046 if (setsockopt(fd, SOL_SOCKET1, SO_KEEPALIVE9, &one, sizeof(one)) < 0)
1047 log_unit_warning_errno(UNIT(s), errno, "SO_KEEPALIVE failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1047, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "SO_KEEPALIVE failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1047, __func__
, "SO_KEEPALIVE failed: %m"); })
;
1048 }
1049
1050 if (s->keep_alive_time > 0) {
1051 int value = s->keep_alive_time / USEC_PER_SEC((usec_t) 1000000ULL);
1052 if (setsockopt(fd, SOL_TCP6, TCP_KEEPIDLE4, &value, sizeof(value)) < 0)
1053 log_unit_warning_errno(UNIT(s), errno, "TCP_KEEPIDLE failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1053, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "TCP_KEEPIDLE failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1053, __func__
, "TCP_KEEPIDLE failed: %m"); })
;
1054 }
1055
1056 if (s->keep_alive_interval > 0) {
1057 int value = s->keep_alive_interval / USEC_PER_SEC((usec_t) 1000000ULL);
1058 if (setsockopt(fd, SOL_TCP6, TCP_KEEPINTVL5, &value, sizeof(value)) < 0)
1059 log_unit_warning_errno(UNIT(s), errno, "TCP_KEEPINTVL failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1059, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "TCP_KEEPINTVL failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1059, __func__
, "TCP_KEEPINTVL failed: %m"); })
;
1060 }
1061
1062 if (s->keep_alive_cnt > 0) {
1063 int value = s->keep_alive_cnt;
1064 if (setsockopt(fd, SOL_TCP6, TCP_KEEPCNT6, &value, sizeof(value)) < 0)
1065 log_unit_warning_errno(UNIT(s), errno, "TCP_KEEPCNT failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1065, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "TCP_KEEPCNT failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1065, __func__
, "TCP_KEEPCNT failed: %m"); })
;
1066 }
1067
1068 if (s->defer_accept > 0) {
1069 int value = s->defer_accept / USEC_PER_SEC((usec_t) 1000000ULL);
1070 if (setsockopt(fd, SOL_TCP6, TCP_DEFER_ACCEPT9, &value, sizeof(value)) < 0)
1071 log_unit_warning_errno(UNIT(s), errno, "TCP_DEFER_ACCEPT failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1071, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "TCP_DEFER_ACCEPT failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1071, __func__
, "TCP_DEFER_ACCEPT failed: %m"); })
;
1072 }
1073
1074 if (s->no_delay) {
1075 int one = 1;
1076
1077 if (s->socket_protocol == IPPROTO_SCTPIPPROTO_SCTP) {
1078 if (setsockopt(fd, SOL_SCTP132, SCTP_NODELAY3, &one, sizeof(one)) < 0)
1079 log_unit_warning_errno(UNIT(s), errno, "SCTP_NODELAY failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1079, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "SCTP_NODELAY failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1079, __func__
, "SCTP_NODELAY failed: %m"); })
;
1080 } else {
1081 if (setsockopt(fd, SOL_TCP6, TCP_NODELAY1, &one, sizeof(one)) < 0)
1082 log_unit_warning_errno(UNIT(s), errno, "TCP_NODELAY failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1082, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "TCP_NODELAY failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1082, __func__
, "TCP_NODELAY failed: %m"); })
;
1083 }
1084 }
1085
1086 if (s->broadcast) {
1087 int one = 1;
1088 if (setsockopt(fd, SOL_SOCKET1, SO_BROADCAST6, &one, sizeof(one)) < 0)
1089 log_unit_warning_errno(UNIT(s), errno, "SO_BROADCAST failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1089, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "SO_BROADCAST failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1089, __func__
, "SO_BROADCAST failed: %m"); })
;
1090 }
1091
1092 if (s->pass_cred) {
1093 int one = 1;
1094 if (setsockopt(fd, SOL_SOCKET1, SO_PASSCRED16, &one, sizeof(one)) < 0)
1095 log_unit_warning_errno(UNIT(s), errno, "SO_PASSCRED failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1095, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "SO_PASSCRED failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1095, __func__
, "SO_PASSCRED failed: %m"); })
;
1096 }
1097
1098 if (s->pass_sec) {
1099 int one = 1;
1100 if (setsockopt(fd, SOL_SOCKET1, SO_PASSSEC34, &one, sizeof(one)) < 0)
1101 log_unit_warning_errno(UNIT(s), errno, "SO_PASSSEC failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1101, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "SO_PASSSEC failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1101, __func__
, "SO_PASSSEC failed: %m"); })
;
1102 }
1103
1104 if (s->pass_pktinfo) {
1105 r = socket_pass_pktinfo(fd, true1);
1106 if (r < 0)
1107 log_unit_warning_errno(UNIT(s), r, "Failed to enable packet info socket option: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 1107, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to enable packet info socket option: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/core/socket.c", 1107, __func__, "Failed to enable packet info socket option: %m"
); })
;
1108 }
1109
1110 if (s->priority >= 0)
1111 if (setsockopt(fd, SOL_SOCKET1, SO_PRIORITY12, &s->priority, sizeof(s->priority)) < 0)
1112 log_unit_warning_errno(UNIT(s), errno, "SO_PRIORITY failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1112, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "SO_PRIORITY failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1112, __func__
, "SO_PRIORITY failed: %m"); })
;
1113
1114 if (s->receive_buffer > 0) {
1115 int value = (int) s->receive_buffer;
1116
1117 /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */
1118 if (setsockopt(fd, SOL_SOCKET1, SO_RCVBUFFORCE33, &value, sizeof(value)) < 0)
1119 if (setsockopt(fd, SOL_SOCKET1, SO_RCVBUF8, &value, sizeof(value)) < 0)
1120 log_unit_warning_errno(UNIT(s), errno, "SO_RCVBUF failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1120, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "SO_RCVBUF failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1120, __func__
, "SO_RCVBUF failed: %m"); })
;
1121 }
1122
1123 if (s->send_buffer > 0) {
1124 int value = (int) s->send_buffer;
1125 if (setsockopt(fd, SOL_SOCKET1, SO_SNDBUFFORCE32, &value, sizeof(value)) < 0)
1126 if (setsockopt(fd, SOL_SOCKET1, SO_SNDBUF7, &value, sizeof(value)) < 0)
1127 log_unit_warning_errno(UNIT(s), errno, "SO_SNDBUF failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1127, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "SO_SNDBUF failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1127, __func__
, "SO_SNDBUF failed: %m"); })
;
1128 }
1129
1130 if (s->mark >= 0)
1131 if (setsockopt(fd, SOL_SOCKET1, SO_MARK36, &s->mark, sizeof(s->mark)) < 0)
1132 log_unit_warning_errno(UNIT(s), errno, "SO_MARK failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1132, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "SO_MARK failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1132, __func__
, "SO_MARK failed: %m"); })
;
1133
1134 if (s->ip_tos >= 0)
1135 if (setsockopt(fd, IPPROTO_IPIPPROTO_IP, IP_TOS1, &s->ip_tos, sizeof(s->ip_tos)) < 0)
1136 log_unit_warning_errno(UNIT(s), errno, "IP_TOS failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1136, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "IP_TOS failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1136, __func__
, "IP_TOS failed: %m"); })
;
1137
1138 if (s->ip_ttl >= 0) {
1139 int x;
1140
1141 r = setsockopt(fd, IPPROTO_IPIPPROTO_IP, IP_TTL2, &s->ip_ttl, sizeof(s->ip_ttl));
1142
1143 if (socket_ipv6_is_supported())
1144 x = setsockopt(fd, IPPROTO_IPV6IPPROTO_IPV6, IPV6_UNICAST_HOPS16, &s->ip_ttl, sizeof(s->ip_ttl));
1145 else {
1146 x = -1;
1147 errno(*__errno_location ()) = EAFNOSUPPORT97;
1148 }
1149
1150 if (r < 0 && x < 0)
1151 log_unit_warning_errno(UNIT(s), errno, "IP_TTL/IPV6_UNICAST_HOPS failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1151, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "IP_TTL/IPV6_UNICAST_HOPS failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1151, __func__
, "IP_TTL/IPV6_UNICAST_HOPS failed: %m"); })
;
1152 }
1153
1154 if (s->tcp_congestion)
1155 if (setsockopt(fd, SOL_TCP6, TCP_CONGESTION13, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0)
1156 log_unit_warning_errno(UNIT(s), errno, "TCP_CONGESTION failed: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1156, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "TCP_CONGESTION failed: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1156, __func__
, "TCP_CONGESTION failed: %m"); })
;
1157
1158 if (s->smack_ip_in) {
1159 r = mac_smack_apply_fd(fd, SMACK_ATTR_IPIN, s->smack_ip_in);
1160 if (r < 0)
1161 log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_in_fd: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, r, "../src/core/socket.c", 1161, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "mac_smack_apply_ip_in_fd: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/core/socket.c", 1161, __func__, "mac_smack_apply_ip_in_fd: %m"
); })
;
1162 }
1163
1164 if (s->smack_ip_out) {
1165 r = mac_smack_apply_fd(fd, SMACK_ATTR_IPOUT, s->smack_ip_out);
1166 if (r < 0)
1167 log_unit_error_errno(UNIT(s), r, "mac_smack_apply_ip_out_fd: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, r, "../src/core/socket.c", 1167, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "mac_smack_apply_ip_out_fd: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/core/socket.c", 1167, __func__, "mac_smack_apply_ip_out_fd: %m"
); })
;
1168 }
1169}
1170
1171static void socket_apply_fifo_options(Socket *s, int fd) {
1172 int r;
1173
1174 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1174, __PRETTY_FUNCTION__
); } while (0)
;
1175 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/core/socket.c", 1175
, __PRETTY_FUNCTION__); } while (0)
;
1176
1177 if (s->pipe_size > 0)
1178 if (fcntl(fd, F_SETPIPE_SZ1031, s->pipe_size) < 0)
1179 log_unit_warning_errno(UNIT(s), errno, "Setting pipe size failed, ignoring: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, (*__errno_location ()), "../src/core/socket.c", 1179, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "Setting pipe size failed, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), (*__errno_location ()), "../src/core/socket.c", 1179, __func__
, "Setting pipe size failed, ignoring: %m"); })
;
1180
1181 if (s->smack) {
1182 r = mac_smack_apply_fd(fd, SMACK_ATTR_ACCESS, s->smack);
1183 if (r < 0)
1184 log_unit_error_errno(UNIT(s), r, "SMACK relabelling failed, ignoring: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, r, "../src/core/socket.c", 1184, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "SMACK relabelling failed, ignoring: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/core/socket.c", 1184, __func__, "SMACK relabelling failed, ignoring: %m"
); })
;
1185 }
1186}
1187
1188static int fifo_address_create(
1189 const char *path,
1190 mode_t directory_mode,
1191 mode_t socket_mode) {
1192
1193 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
1194 mode_t old_mask;
1195 struct stat st;
1196 int r;
1197
1198 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/socket.c", 1198, __PRETTY_FUNCTION__
); } while (0)
;
1199
1200 (void) mkdir_parents_label(path, directory_mode);
1201
1202 r = mac_selinux_create_file_prepare(path, S_IFIFO0010000);
1203 if (r < 0)
1204 return r;
1205
1206 /* Enforce the right access mode for the fifo */
1207 old_mask = umask(~socket_mode);
1208
1209 /* Include the original umask in our mask */
1210 (void) umask(~socket_mode | old_mask);
1211
1212 r = mkfifo(path, socket_mode);
1213 (void) umask(old_mask);
1214
1215 if (r < 0 && errno(*__errno_location ()) != EEXIST17) {
1216 r = -errno(*__errno_location ());
1217 goto fail;
1218 }
1219
1220 fd = open(path, O_RDWR02 | O_CLOEXEC02000000 | O_NOCTTY0400 | O_NONBLOCK04000 | O_NOFOLLOW0400000);
1221 if (fd < 0) {
1222 r = -errno(*__errno_location ());
1223 goto fail;
1224 }
1225
1226 mac_selinux_create_file_clear();
1227
1228 if (fstat(fd, &st) < 0) {
1229 r = -errno(*__errno_location ());
1230 goto fail;
1231 }
1232
1233 if (!S_ISFIFO(st.st_mode)((((st.st_mode)) & 0170000) == (0010000)) ||
1234 (st.st_mode & 0777) != (socket_mode & ~old_mask) ||
1235 st.st_uid != getuid() ||
1236 st.st_gid != getgid()) {
1237 r = -EEXIST17;
1238 goto fail;
1239 }
1240
1241 return TAKE_FD(fd)({ int _fd_ = (fd); (fd) = -1; _fd_; });
1242
1243fail:
1244 mac_selinux_create_file_clear();
1245 return r;
1246}
1247
1248static int special_address_create(const char *path, bool_Bool writable) {
1249 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
1250 struct stat st;
1251
1252 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/socket.c", 1252, __PRETTY_FUNCTION__
); } while (0)
;
1253
1254 fd = open(path, (writable ? O_RDWR02 : O_RDONLY00)|O_CLOEXEC02000000|O_NOCTTY0400|O_NONBLOCK04000|O_NOFOLLOW0400000);
1255 if (fd < 0)
1256 return -errno(*__errno_location ());
1257
1258 if (fstat(fd, &st) < 0)
1259 return -errno(*__errno_location ());
1260
1261 /* Check whether this is a /proc, /sys or /dev file or char device */
1262 if (!S_ISREG(st.st_mode)((((st.st_mode)) & 0170000) == (0100000)) && !S_ISCHR(st.st_mode)((((st.st_mode)) & 0170000) == (0020000)))
1263 return -EEXIST17;
1264
1265 return TAKE_FD(fd)({ int _fd_ = (fd); (fd) = -1; _fd_; });
1266}
1267
1268static int usbffs_address_create(const char *path) {
1269 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
1270 struct stat st;
1271
1272 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/socket.c", 1272, __PRETTY_FUNCTION__
); } while (0)
;
1273
1274 fd = open(path, O_RDWR02|O_CLOEXEC02000000|O_NOCTTY0400|O_NONBLOCK04000|O_NOFOLLOW0400000);
1275 if (fd < 0)
1276 return -errno(*__errno_location ());
1277
1278 if (fstat(fd, &st) < 0)
1279 return -errno(*__errno_location ());
1280
1281 /* Check whether this is a regular file (ffs endpoint) */
1282 if (!S_ISREG(st.st_mode)((((st.st_mode)) & 0170000) == (0100000)))
1283 return -EEXIST17;
1284
1285 return TAKE_FD(fd)({ int _fd_ = (fd); (fd) = -1; _fd_; });
1286}
1287
1288static int mq_address_create(
1289 const char *path,
1290 mode_t mq_mode,
1291 long maxmsg,
1292 long msgsize) {
1293
1294 _cleanup_close___attribute__((cleanup(closep))) int fd = -1;
1295 struct stat st;
1296 mode_t old_mask;
1297 struct mq_attr _attr, *attr = NULL((void*)0);
1298
1299 assert(path)do { if ((__builtin_expect(!!(!(path)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("path"), "../src/core/socket.c", 1299, __PRETTY_FUNCTION__
); } while (0)
;
1300
1301 if (maxmsg > 0 && msgsize > 0) {
1302 _attr = (struct mq_attr) {
1303 .mq_flags = O_NONBLOCK04000,
1304 .mq_maxmsg = maxmsg,
1305 .mq_msgsize = msgsize,
1306 };
1307 attr = &_attr;
1308 }
1309
1310 /* Enforce the right access mode for the mq */
1311 old_mask = umask(~mq_mode);
1312
1313 /* Include the original umask in our mask */
1314 (void) umask(~mq_mode | old_mask);
1315 fd = mq_open(path, O_RDONLY00|O_CLOEXEC02000000|O_NONBLOCK04000|O_CREAT0100, mq_mode, attr);
1316 (void) umask(old_mask);
1317
1318 if (fd < 0)
1319 return -errno(*__errno_location ());
1320
1321 if (fstat(fd, &st) < 0)
1322 return -errno(*__errno_location ());
1323
1324 if ((st.st_mode & 0777) != (mq_mode & ~old_mask) ||
1325 st.st_uid != getuid() ||
1326 st.st_gid != getgid())
1327 return -EEXIST17;
1328
1329 return TAKE_FD(fd)({ int _fd_ = (fd); (fd) = -1; _fd_; });
1330}
1331
1332static int socket_symlink(Socket *s) {
1333 const char *p;
1334 char **i;
1335 int r;
1336
1337 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1337, __PRETTY_FUNCTION__
); } while (0)
;
1338
1339 p = socket_find_symlink_target(s);
1340 if (!p)
1341 return 0;
1342
1343 STRV_FOREACH(i, s->symlinks)for ((i) = (s->symlinks); (i) && *(i); (i)++) {
1344 (void) mkdir_parents_label(*i, s->directory_mode);
1345
1346 r = symlink_idempotent(p, *i);
1347
1348 if (r == -EEXIST17 && s->remove_on_stop) {
1349 /* If there's already something where we want to create the symlink, and the destructive
1350 * RemoveOnStop= mode is set, then we might as well try to remove what already exists and try
1351 * again. */
1352
1353 if (unlink(*i) >= 0)
1354 r = symlink_idempotent(p, *i);
1355 }
1356
1357 if (r < 0)
1358 log_unit_warning_errno(UNIT(s), r, "Failed to create symlink %s → %s, ignoring: %m", p, *i)({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 1358, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to create symlink %s → %s, ignoring: %m"
, p, *i) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10
| ((4))), r, "../src/core/socket.c", 1358, __func__, "Failed to create symlink %s → %s, ignoring: %m"
, p, *i); })
;
1359 }
1360
1361 return 0;
1362}
1363
1364static int usbffs_write_descs(int fd, Service *s) {
1365 int r;
1366
1367 if (!s->usb_function_descriptors || !s->usb_function_strings)
1368 return -EINVAL22;
1369
1370 r = copy_file_fd(s->usb_function_descriptors, fd, 0);
1371 if (r < 0)
1372 return r;
1373
1374 return copy_file_fd(s->usb_function_strings, fd, 0);
1375}
1376
1377static int usbffs_select_ep(const struct dirent *d) {
1378 return d->d_name[0] != '.' && !streq(d->d_name, "ep0")(strcmp((d->d_name),("ep0")) == 0);
1379}
1380
1381static int usbffs_dispatch_eps(SocketPort *p) {
1382 _cleanup_free___attribute__((cleanup(freep))) struct dirent **ent = NULL((void*)0);
1383 size_t n, k, i;
1384 int r;
1385
1386 r = scandir(p->path, &ent, usbffs_select_ep, alphasort);
1387 if (r < 0)
1388 return -errno(*__errno_location ());
1389
1390 n = (size_t) r;
1391 p->auxiliary_fds = new(int, n)((int*) malloc_multiply(sizeof(int), (n)));
1392 if (!p->auxiliary_fds)
1393 return -ENOMEM12;
1394
1395 p->n_auxiliary_fds = n;
1396
1397 k = 0;
1398 for (i = 0; i < n; ++i) {
1399 _cleanup_free___attribute__((cleanup(freep))) char *ep = NULL((void*)0);
1400
1401 ep = path_make_absolute(ent[i]->d_name, p->path);
1402 if (!ep)
1403 return -ENOMEM12;
1404
1405 path_simplify(ep, false0);
1406
1407 r = usbffs_address_create(ep);
1408 if (r < 0)
1409 goto fail;
1410
1411 p->auxiliary_fds[k++] = r;
1412 free(ent[i]);
1413 }
1414
1415 return r;
1416
1417fail:
1418 close_many(p->auxiliary_fds, k);
1419 p->auxiliary_fds = mfree(p->auxiliary_fds);
1420 p->n_auxiliary_fds = 0;
1421
1422 return r;
1423}
1424
1425static int socket_determine_selinux_label(Socket *s, char **ret) {
1426 Service *service;
1427 ExecCommand *c;
1428 _cleanup_free___attribute__((cleanup(freep))) char *path = NULL((void*)0);
1429 int r;
1430
1431 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1431, __PRETTY_FUNCTION__
); } while (0)
;
1432 assert(ret)do { if ((__builtin_expect(!!(!(ret)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("ret"), "../src/core/socket.c", 1432, __PRETTY_FUNCTION__
); } while (0)
;
1433
1434 if (s->selinux_context_from_net) {
1435 /* If this is requested, get label from the network label */
1436
1437 r = mac_selinux_get_our_label(ret);
1438 if (r == -EOPNOTSUPP95)
1439 goto no_label;
1440
1441 } else {
1442 /* Otherwise, get it from the executable we are about to start */
1443 r = socket_instantiate_service(s);
1444 if (r < 0)
1445 return r;
1446
1447 if (!UNIT_ISSET(s->service)(!!(s->service).target))
1448 goto no_label;
1449
1450 service = SERVICE(UNIT_DEREF(s->service)((s->service).target));
1451 c = service->exec_command[SERVICE_EXEC_START];
1452 if (!c)
1453 goto no_label;
1454
1455 r = chase_symlinks(c->path, service->exec_context.root_directory, CHASE_PREFIX_ROOT, &path);
1456 if (r < 0)
1457 goto no_label;
1458
1459 r = mac_selinux_get_create_label_from_exe(path, ret);
1460 if (IN_SET(r, -EPERM, -EOPNOTSUPP)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){-1, -95})/sizeof(int)]; switch(r) { case
-1: case -95: _found = 1; break; default: break; } _found; }
)
)
1461 goto no_label;
1462 }
1463
1464 return r;
1465
1466no_label:
1467 *ret = NULL((void*)0);
1468 return 0;
1469}
1470
1471static int socket_address_listen_do(
1472 Socket *s,
1473 const SocketAddress *address,
1474 const char *label) {
1475
1476 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1476, __PRETTY_FUNCTION__
); } while (0)
;
1477 assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("address"), "../src/core/socket.c", 1477
, __PRETTY_FUNCTION__); } while (0)
;
1478
1479 return socket_address_listen(
1480 address,
1481 SOCK_CLOEXECSOCK_CLOEXEC|SOCK_NONBLOCKSOCK_NONBLOCK,
1482 s->backlog,
1483 s->bind_ipv6_only,
1484 s->bind_to_device,
1485 s->reuse_port,
1486 s->free_bind,
1487 s->transparent,
1488 s->directory_mode,
1489 s->socket_mode,
1490 label);
1491}
1492
1493static int socket_address_listen_in_cgroup(
1494 Socket *s,
1495 const SocketAddress *address,
1496 const char *label) {
1497
1498 _cleanup_close_pair___attribute__((cleanup(close_pairp))) int pair[2] = { -1, -1 };
1499 int fd, r;
1500 pid_t pid;
1501
1502 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1502, __PRETTY_FUNCTION__
); } while (0)
;
1503 assert(address)do { if ((__builtin_expect(!!(!(address)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("address"), "../src/core/socket.c", 1503
, __PRETTY_FUNCTION__); } while (0)
;
1504
1505 /* This is a wrapper around socket_address_listen(), that forks off a helper process inside the socket's cgroup
1506 * in which the socket is actually created. This way we ensure the socket is actually properly attached to the
1507 * unit's cgroup for the purpose of BPF filtering and such. */
1508
1509 if (!IN_SET(address->sockaddr.sa.sa_family, AF_INET, AF_INET6)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(address->
sockaddr.sa.sa_family) { case 2: case 10: _found = 1; break; default
: break; } _found; })
)
1510 goto shortcut; /* BPF filtering only applies to IPv4 + IPv6, shortcut things for other protocols */
1511
1512 r = bpf_firewall_supported();
1513 if (r < 0)
1514 return r;
1515 if (r == BPF_FIREWALL_UNSUPPORTED) /* If BPF firewalling isn't supported anyway — there's no point in this forking complexity */
1516 goto shortcut;
1517
1518 if (socketpair(AF_UNIX1, SOCK_SEQPACKETSOCK_SEQPACKET|SOCK_CLOEXECSOCK_CLOEXEC, 0, pair) < 0)
1519 return log_unit_error_errno(UNIT(s), errno, "Failed to create communication channel: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, (*__errno_location ()), "../src/core/socket.c", 1519, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "Failed to create communication channel: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), (*__errno_location ()), "../src/core/socket.c", 1519, __func__
, "Failed to create communication channel: %m"); })
;
1520
1521 r = unit_fork_helper_process(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, "(sd-listen)", &pid);
1522 if (r < 0)
1523 return log_unit_error_errno(UNIT(s), r, "Failed to fork off listener stub process: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, r, "../src/core/socket.c", 1523, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to fork off listener stub process: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/core/socket.c", 1523, __func__, "Failed to fork off listener stub process: %m"
); })
;
1524 if (r == 0) {
1525 /* Child */
1526
1527 pair[0] = safe_close(pair[0]);
1528
1529 fd = socket_address_listen_do(s, address, label);
1530 if (fd < 0) {
1531 log_unit_error_errno(UNIT(s), fd, "Failed to create listening socket: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, fd, "../src/core/socket.c", 1531, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to create listening socket: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), fd, "../src/core/socket.c", 1531, __func__, "Failed to create listening socket: %m"
); })
;
1532 _exit(EXIT_FAILURE1);
1533 }
1534
1535 r = send_one_fd(pair[1], fd, 0)send_one_fd_iov_sa(pair[1], fd, ((void*)0), 0, ((void*)0), 0,
0)
;
1536 if (r < 0) {
1537 log_unit_error_errno(UNIT(s), r, "Failed to send listening socket to parent: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, r, "../src/core/socket.c", 1537, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to send listening socket to parent: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/core/socket.c", 1537, __func__, "Failed to send listening socket to parent: %m"
); })
;
1538 _exit(EXIT_FAILURE1);
1539 }
1540
1541 _exit(EXIT_SUCCESS0);
1542 }
1543
1544 pair[1] = safe_close(pair[1]);
1545 fd = receive_one_fd(pair[0], 0);
1546
1547 /* We synchronously wait for the helper, as it shouldn't be slow */
1548 r = wait_for_terminate_and_check("(sd-listen)", pid, WAIT_LOG_ABNORMAL);
1549 if (r < 0) {
1550 safe_close(fd);
1551 return r;
1552 }
1553
1554 if (fd < 0)
1555 return log_unit_error_errno(UNIT(s), fd, "Failed to receive listening socket: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, fd, "../src/core/socket.c", 1555, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to receive listening socket: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), fd, "../src/core/socket.c", 1555, __func__, "Failed to receive listening socket: %m"
); })
;
1556
1557 return fd;
1558
1559shortcut:
1560 fd = socket_address_listen_do(s, address, label);
1561 if (fd < 0)
1562 return log_error_errno(fd, "Failed to create listening socket: %m")({ int _level = ((3)), _e = ((fd)), _realm = (LOG_REALM_SYSTEMD
); (log_get_max_level_realm(_realm) >= ((_level) & 0x07
)) ? log_internal_realm(((_realm) << 10 | (_level)), _e
, "../src/core/socket.c", 1562, __func__, "Failed to create listening socket: %m"
) : -abs(_e); })
;
1563
1564 return fd;
1565}
1566
1567static int socket_open_fds(Socket *s) {
1568 _cleanup_(mac_selinux_freep)__attribute__((cleanup(mac_selinux_freep))) char *label = NULL((void*)0);
1569 bool_Bool know_label = false0;
1570 SocketPort *p;
1571 int r;
1572
1573 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1573, __PRETTY_FUNCTION__
); } while (0)
;
1574
1575 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
1576
1577 if (p->fd >= 0)
1578 continue;
1579
1580 switch (p->type) {
1581
1582 case SOCKET_SOCKET:
1583
1584 if (!know_label) {
1585 /* Figure out label, if we don't it know yet. We do it once, for the first socket where
1586 * we need this and remember it for the rest. */
1587
1588 r = socket_determine_selinux_label(s, &label);
1589 if (r < 0)
1590 goto rollback;
1591
1592 know_label = true1;
1593 }
1594
1595 /* Apply the socket protocol */
1596 switch (p->address.type) {
1597
1598 case SOCK_STREAMSOCK_STREAM:
1599 case SOCK_SEQPACKETSOCK_SEQPACKET:
1600 if (s->socket_protocol == IPPROTO_SCTPIPPROTO_SCTP)
1601 p->address.protocol = s->socket_protocol;
1602 break;
1603
1604 case SOCK_DGRAMSOCK_DGRAM:
1605 if (s->socket_protocol == IPPROTO_UDPLITEIPPROTO_UDPLITE)
1606 p->address.protocol = s->socket_protocol;
1607 break;
1608 }
1609
1610 r = socket_address_listen_in_cgroup(s, &p->address, label);
1611 if (r < 0)
1612 goto rollback;
1613
1614 p->fd = r;
1615 socket_apply_socket_options(s, p->fd);
1616 socket_symlink(s);
1617 break;
1618
1619 case SOCKET_SPECIAL:
1620
1621 p->fd = special_address_create(p->path, s->writable);
1622 if (p->fd < 0) {
1623 r = p->fd;
1624 goto rollback;
1625 }
1626 break;
1627
1628 case SOCKET_FIFO:
1629
1630 p->fd = fifo_address_create(
1631 p->path,
1632 s->directory_mode,
1633 s->socket_mode);
1634 if (p->fd < 0) {
1635 r = p->fd;
1636 goto rollback;
1637 }
1638
1639 socket_apply_fifo_options(s, p->fd);
1640 socket_symlink(s);
1641 break;
1642
1643 case SOCKET_MQUEUE:
1644
1645 p->fd = mq_address_create(
1646 p->path,
1647 s->socket_mode,
1648 s->mq_maxmsg,
1649 s->mq_msgsize);
1650 if (p->fd < 0) {
1651 r = p->fd;
1652 goto rollback;
1653 }
1654 break;
1655
1656 case SOCKET_USB_FUNCTION: {
1657 _cleanup_free___attribute__((cleanup(freep))) char *ep = NULL((void*)0);
1658
1659 ep = path_make_absolute("ep0", p->path);
1660
1661 p->fd = usbffs_address_create(ep);
1662 if (p->fd < 0) {
1663 r = p->fd;
1664 goto rollback;
1665 }
1666
1667 r = usbffs_write_descs(p->fd, SERVICE(UNIT_DEREF(s->service)((s->service).target)));
1668 if (r < 0)
1669 goto rollback;
1670
1671 r = usbffs_dispatch_eps(p);
1672 if (r < 0)
1673 goto rollback;
1674
1675 break;
1676 }
1677 default:
1678 assert_not_reached("Unknown port type")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unknown port type"), "../src/core/socket.c", 1678, __PRETTY_FUNCTION__
); } while (0)
;
1679 }
1680 }
1681
1682 return 0;
1683
1684rollback:
1685 socket_close_fds(s);
1686 return r;
1687}
1688
1689static void socket_unwatch_fds(Socket *s) {
1690 SocketPort *p;
1691 int r;
1692
1693 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1693, __PRETTY_FUNCTION__
); } while (0)
;
1694
1695 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
1696 if (p->fd < 0)
1697 continue;
1698
1699 if (!p->event_source)
1700 continue;
1701
1702 r = sd_event_source_set_enabled(p->event_source, SD_EVENT_OFF);
1703 if (r < 0)
1704 log_unit_debug_errno(UNIT(s), r, "Failed to disable event source: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(7, r, "../src/core/socket.c", 1704, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to disable event source: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7
))), r, "../src/core/socket.c", 1704, __func__, "Failed to disable event source: %m"
); })
;
1705 }
1706}
1707
1708static int socket_watch_fds(Socket *s) {
1709 SocketPort *p;
1710 int r;
1711
1712 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1712, __PRETTY_FUNCTION__
); } while (0)
;
1713
1714 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
1715 if (p->fd < 0)
1716 continue;
1717
1718 if (p->event_source) {
1719 r = sd_event_source_set_enabled(p->event_source, SD_EVENT_ON);
1720 if (r < 0)
1721 goto fail;
1722 } else {
1723 r = sd_event_add_io(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->manager->event, &p->event_source, p->fd, EPOLLINEPOLLIN, socket_dispatch_io, p);
1724 if (r < 0)
1725 goto fail;
1726
1727 (void) sd_event_source_set_description(p->event_source, "socket-port-io");
1728 }
1729 }
1730
1731 return 0;
1732
1733fail:
1734 log_unit_warning_errno(UNIT(s), r, "Failed to watch listening fds: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 1734, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to watch listening fds: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/core/socket.c", 1734, __func__, "Failed to watch listening fds: %m"
); })
;
1735 socket_unwatch_fds(s);
1736 return r;
1737}
1738
1739enum {
1740 SOCKET_OPEN_NONE,
1741 SOCKET_OPEN_SOME,
1742 SOCKET_OPEN_ALL,
1743};
1744
1745static int socket_check_open(Socket *s) {
1746 bool_Bool have_open = false0, have_closed = false0;
1747 SocketPort *p;
1748
1749 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1749, __PRETTY_FUNCTION__
); } while (0)
;
1750
1751 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
1752 if (p->fd < 0)
1753 have_closed = true1;
1754 else
1755 have_open = true1;
1756
1757 if (have_open && have_closed)
1758 return SOCKET_OPEN_SOME;
1759 }
1760
1761 if (have_open)
1762 return SOCKET_OPEN_ALL;
1763
1764 return SOCKET_OPEN_NONE;
1765}
1766
1767static void socket_set_state(Socket *s, SocketState state) {
1768 SocketState old_state;
1769 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1769, __PRETTY_FUNCTION__
); } while (0)
;
1770
1771 old_state = s->state;
1772 s->state = state;
1773
1774 if (!IN_SET(state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
1775 SOCKET_START_PRE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
1776 SOCKET_START_CHOWN,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
1777 SOCKET_START_POST,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
1778 SOCKET_STOP_PRE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
1779 SOCKET_STOP_PRE_SIGTERM,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
1780 SOCKET_STOP_PRE_SIGKILL,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
1781 SOCKET_STOP_POST,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
1782 SOCKET_FINAL_SIGTERM,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
1783 SOCKET_FINAL_SIGKILL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_PRE: case SOCKET_START_CHOWN
: case SOCKET_START_POST: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM
: case SOCKET_FINAL_SIGKILL: _found = 1; break; default: break
; } _found; })
) {
1784
1785 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
1786 socket_unwatch_control_pid(s);
1787 s->control_command = NULL((void*)0);
1788 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
1789 }
1790
1791 if (state != SOCKET_LISTENING)
1792 socket_unwatch_fds(s);
1793
1794 if (!IN_SET(state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_CHOWN: case
SOCKET_START_POST: case SOCKET_LISTENING: case SOCKET_RUNNING
: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: _found = 1; break; default: break; } _found; })
1795 SOCKET_START_CHOWN,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_CHOWN: case
SOCKET_START_POST: case SOCKET_LISTENING: case SOCKET_RUNNING
: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: _found = 1; break; default: break; } _found; })
1796 SOCKET_START_POST,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_CHOWN: case
SOCKET_START_POST: case SOCKET_LISTENING: case SOCKET_RUNNING
: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: _found = 1; break; default: break; } _found; })
1797 SOCKET_LISTENING,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_CHOWN: case
SOCKET_START_POST: case SOCKET_LISTENING: case SOCKET_RUNNING
: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: _found = 1; break; default: break; } _found; })
1798 SOCKET_RUNNING,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_CHOWN: case
SOCKET_START_POST: case SOCKET_LISTENING: case SOCKET_RUNNING
: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: _found = 1; break; default: break; } _found; })
1799 SOCKET_STOP_PRE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_CHOWN: case
SOCKET_START_POST: case SOCKET_LISTENING: case SOCKET_RUNNING
: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: _found = 1; break; default: break; } _found; })
1800 SOCKET_STOP_PRE_SIGTERM,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_CHOWN: case
SOCKET_START_POST: case SOCKET_LISTENING: case SOCKET_RUNNING
: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: _found = 1; break; default: break; } _found; })
1801 SOCKET_STOP_PRE_SIGKILL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_START_CHOWN: case
SOCKET_START_POST: case SOCKET_LISTENING: case SOCKET_RUNNING
: case SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: _found = 1; break; default: break; } _found; })
)
1802 socket_close_fds(s);
1803
1804 if (state != old_state)
1805 log_unit_debug(UNIT(s), "Changed %s -> %s", socket_state_to_string(old_state), socket_state_to_string(state))({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(7, 0, "../src/core/socket.c", 1805, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Changed %s -> %s", socket_state_to_string
(old_state), socket_state_to_string(state)) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 1805, __func__, "Changed %s -> %s", socket_state_to_string
(old_state), socket_state_to_string(state)); })
;
1806
1807 unit_notify(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, state_translation_table[old_state], state_translation_table[state], 0);
1808}
1809
1810static int socket_coldplug(Unit *u) {
1811 Socket *s = SOCKET(u);
1812 int r;
1813
1814 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1814, __PRETTY_FUNCTION__
); } while (0)
;
1815 assert(s->state == SOCKET_DEAD)do { if ((__builtin_expect(!!(!(s->state == SOCKET_DEAD)),
0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->state == SOCKET_DEAD"
), "../src/core/socket.c", 1815, __PRETTY_FUNCTION__); } while
(0)
;
1816
1817 if (s->deserialized_state == s->state)
1818 return 0;
1819
1820 if (s->control_pid > 0 &&
1821 pid_is_unwaited(s->control_pid) &&
1822 IN_SET(s->deserialized_state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
1823 SOCKET_START_PRE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
1824 SOCKET_START_CHOWN,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
1825 SOCKET_START_POST,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
1826 SOCKET_STOP_PRE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
1827 SOCKET_STOP_PRE_SIGTERM,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
1828 SOCKET_STOP_PRE_SIGKILL,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
1829 SOCKET_STOP_POST,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
1830 SOCKET_FINAL_SIGTERM,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
1831 SOCKET_FINAL_SIGKILL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
, SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM, SOCKET_FINAL_SIGKILL
})/sizeof(int)]; switch(s->deserialized_state) { case SOCKET_START_PRE
: case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_STOP_PRE
: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL:
case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
) {
1832
1833 r = unit_watch_pid(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, s->control_pid, false0);
1834 if (r < 0)
1835 return r;
1836
1837 r = socket_arm_timer(s, usec_add(u->state_change_timestamp.monotonic, s->timeout_usec));
1838 if (r < 0)
1839 return r;
1840 }
1841
1842 if (IN_SET(s->deserialized_state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING})/sizeof(int)]; switch(s->deserialized_state
) { case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_LISTENING
: case SOCKET_RUNNING: _found = 1; break; default: break; } _found
; })
1843 SOCKET_START_CHOWN,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING})/sizeof(int)]; switch(s->deserialized_state
) { case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_LISTENING
: case SOCKET_RUNNING: _found = 1; break; default: break; } _found
; })
1844 SOCKET_START_POST,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING})/sizeof(int)]; switch(s->deserialized_state
) { case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_LISTENING
: case SOCKET_RUNNING: _found = 1; break; default: break; } _found
; })
1845 SOCKET_LISTENING,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING})/sizeof(int)]; switch(s->deserialized_state
) { case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_LISTENING
: case SOCKET_RUNNING: _found = 1; break; default: break; } _found
; })
1846 SOCKET_RUNNING)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_CHOWN, SOCKET_START_POST, SOCKET_LISTENING
, SOCKET_RUNNING})/sizeof(int)]; switch(s->deserialized_state
) { case SOCKET_START_CHOWN: case SOCKET_START_POST: case SOCKET_LISTENING
: case SOCKET_RUNNING: _found = 1; break; default: break; } _found
; })
) {
1847
1848 /* Originally, we used to simply reopen all sockets here that we didn't have file descriptors
1849 * for. However, this is problematic, as we won't traverse throught the SOCKET_START_CHOWN state for
1850 * them, and thus the UID/GID wouldn't be right. Hence, instead simply check if we have all fds open,
1851 * and if there's a mismatch, warn loudly. */
1852
1853 r = socket_check_open(s);
1854 if (r == SOCKET_OPEN_NONE)
1855 log_unit_warning(UNIT(s),({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 1858, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Socket unit configuration has changed while unit has been running, "
"no open socket file descriptor left. " "The socket unit is not functional until restarted."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 1858, __func__, "Socket unit configuration has changed while unit has been running, "
"no open socket file descriptor left. " "The socket unit is not functional until restarted."
); })
1856 "Socket unit configuration has changed while unit has been running, "({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 1858, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Socket unit configuration has changed while unit has been running, "
"no open socket file descriptor left. " "The socket unit is not functional until restarted."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 1858, __func__, "Socket unit configuration has changed while unit has been running, "
"no open socket file descriptor left. " "The socket unit is not functional until restarted."
); })
1857 "no open socket file descriptor left. "({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 1858, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Socket unit configuration has changed while unit has been running, "
"no open socket file descriptor left. " "The socket unit is not functional until restarted."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 1858, __func__, "Socket unit configuration has changed while unit has been running, "
"no open socket file descriptor left. " "The socket unit is not functional until restarted."
); })
1858 "The socket unit is not functional until restarted.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 1858, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Socket unit configuration has changed while unit has been running, "
"no open socket file descriptor left. " "The socket unit is not functional until restarted."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 1858, __func__, "Socket unit configuration has changed while unit has been running, "
"no open socket file descriptor left. " "The socket unit is not functional until restarted."
); })
;
1859 else if (r == SOCKET_OPEN_SOME)
1860 log_unit_warning(UNIT(s),({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 1863, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Socket unit configuration has changed while unit has been running, "
"and some socket file descriptors have not been opened yet. "
"The socket unit is not fully functional until restarted.") :
log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)))
, 0, "../src/core/socket.c", 1863, __func__, "Socket unit configuration has changed while unit has been running, "
"and some socket file descriptors have not been opened yet. "
"The socket unit is not fully functional until restarted.");
})
1861 "Socket unit configuration has changed while unit has been running, "({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 1863, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Socket unit configuration has changed while unit has been running, "
"and some socket file descriptors have not been opened yet. "
"The socket unit is not fully functional until restarted.") :
log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)))
, 0, "../src/core/socket.c", 1863, __func__, "Socket unit configuration has changed while unit has been running, "
"and some socket file descriptors have not been opened yet. "
"The socket unit is not fully functional until restarted.");
})
1862 "and some socket file descriptors have not been opened yet. "({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 1863, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Socket unit configuration has changed while unit has been running, "
"and some socket file descriptors have not been opened yet. "
"The socket unit is not fully functional until restarted.") :
log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)))
, 0, "../src/core/socket.c", 1863, __func__, "Socket unit configuration has changed while unit has been running, "
"and some socket file descriptors have not been opened yet. "
"The socket unit is not fully functional until restarted.");
})
1863 "The socket unit is not fully functional until restarted.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 1863, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Socket unit configuration has changed while unit has been running, "
"and some socket file descriptors have not been opened yet. "
"The socket unit is not fully functional until restarted.") :
log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)))
, 0, "../src/core/socket.c", 1863, __func__, "Socket unit configuration has changed while unit has been running, "
"and some socket file descriptors have not been opened yet. "
"The socket unit is not fully functional until restarted.");
})
;
1864 }
1865
1866 if (s->deserialized_state == SOCKET_LISTENING) {
1867 r = socket_watch_fds(s);
1868 if (r < 0)
1869 return r;
1870 }
1871
1872 if (!IN_SET(s->deserialized_state, SOCKET_DEAD, SOCKET_FAILED)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_DEAD, SOCKET_FAILED})/sizeof(int)
]; switch(s->deserialized_state) { case SOCKET_DEAD: case SOCKET_FAILED
: _found = 1; break; default: break; } _found; })
) {
1873 (void) unit_setup_dynamic_creds(u);
1874 (void) unit_setup_exec_runtime(u);
1875 }
1876
1877 socket_set_state(s, s->deserialized_state);
1878 return 0;
1879}
1880
1881static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
1882
1883 ExecParameters exec_params = {
1884 .flags = EXEC_APPLY_SANDBOXING|EXEC_APPLY_CHROOT|EXEC_APPLY_TTY_STDIN,
1885 .stdin_fd = -1,
1886 .stdout_fd = -1,
1887 .stderr_fd = -1,
1888 .exec_fd = -1,
1889 };
1890 pid_t pid;
1891 int r;
1892
1893 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 1893, __PRETTY_FUNCTION__
); } while (0)
;
1894 assert(c)do { if ((__builtin_expect(!!(!(c)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("c"), "../src/core/socket.c", 1894, __PRETTY_FUNCTION__
); } while (0)
;
1895 assert(_pid)do { if ((__builtin_expect(!!(!(_pid)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("_pid"), "../src/core/socket.c", 1895, __PRETTY_FUNCTION__
); } while (0)
;
1896
1897 r = unit_prepare_exec(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
);
1898 if (r < 0)
1899 return r;
1900
1901 r = socket_arm_timer(s, usec_add(now(CLOCK_MONOTONIC1), s->timeout_usec));
1902 if (r < 0)
1903 return r;
1904
1905 unit_set_exec_params(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, &exec_params);
1906
1907 exec_params.argv = c->argv;
1908
1909 r = exec_spawn(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
,
1910 c,
1911 &s->exec_context,
1912 &exec_params,
1913 s->exec_runtime,
1914 &s->dynamic_creds,
1915 &pid);
1916 if (r < 0)
1917 return r;
1918
1919 r = unit_watch_pid(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, pid, true1);
1920 if (r < 0)
1921 return r;
1922
1923 *_pid = pid;
1924
1925 return 0;
1926}
1927
1928static int socket_chown(Socket *s, pid_t *_pid) {
1929 pid_t pid;
1930 int r;
1931
1932 r = socket_arm_timer(s, usec_add(now(CLOCK_MONOTONIC1), s->timeout_usec));
1933 if (r < 0)
1934 goto fail;
1935
1936 /* We have to resolve the user names out-of-process, hence
1937 * let's fork here. It's messy, but well, what can we do? */
1938
1939 r = unit_fork_helper_process(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, "(sd-chown)", &pid);
1940 if (r < 0)
1941 return r;
1942 if (r == 0) {
1943 uid_t uid = UID_INVALID((uid_t) -1);
1944 gid_t gid = GID_INVALID((gid_t) -1);
1945 SocketPort *p;
1946
1947 /* Child */
1948
1949 if (!isempty(s->user)) {
1950 const char *user = s->user;
1951
1952 r = get_user_creds(&user, &uid, &gid, NULL((void*)0), NULL((void*)0));
1953 if (r < 0) {
1954 log_unit_error_errno(UNIT(s), r, "Failed to resolve user %s: %m", user)({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, r, "../src/core/socket.c", 1954, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to resolve user %s: %m"
, user) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10
| ((3))), r, "../src/core/socket.c", 1954, __func__, "Failed to resolve user %s: %m"
, user); })
;
1955 _exit(EXIT_USER);
1956 }
1957 }
1958
1959 if (!isempty(s->group)) {
1960 const char *group = s->group;
1961
1962 r = get_group_creds(&group, &gid);
1963 if (r < 0) {
1964 log_unit_error_errno(UNIT(s), r, "Failed to resolve group %s: %m", group)({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, r, "../src/core/socket.c", 1964, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to resolve group %s: %m"
, group) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10
| ((3))), r, "../src/core/socket.c", 1964, __func__, "Failed to resolve group %s: %m"
, group); })
;
1965 _exit(EXIT_GROUP);
1966 }
1967 }
1968
1969 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
1970 const char *path = NULL((void*)0);
1971
1972 if (p->type == SOCKET_SOCKET)
1973 path = socket_address_get_path(&p->address);
1974 else if (p->type == SOCKET_FIFO)
1975 path = p->path;
1976
1977 if (!path)
1978 continue;
1979
1980 if (chown(path, uid, gid) < 0) {
1981 log_unit_error_errno(UNIT(s), errno, "Failed to chown(): %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, (*__errno_location ()), "../src/core/socket.c", 1981, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "Failed to chown(): %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), (*__errno_location ()), "../src/core/socket.c", 1981, __func__
, "Failed to chown(): %m"); })
;
1982 _exit(EXIT_CHOWN);
1983 }
1984 }
1985
1986 _exit(EXIT_SUCCESS0);
1987 }
1988
1989 r = unit_watch_pid(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, pid, true1);
1990 if (r < 0)
1991 goto fail;
1992
1993 *_pid = pid;
1994 return 0;
1995
1996fail:
1997 s->timer_event_source = sd_event_source_unref(s->timer_event_source);
1998 return r;
1999}
2000
2001static void socket_enter_dead(Socket *s, SocketResult f) {
2002 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2002, __PRETTY_FUNCTION__
); } while (0)
;
2003
2004 if (s->result == SOCKET_SUCCESS)
2005 s->result = f;
2006
2007 if (s->result == SOCKET_SUCCESS)
2008 unit_log_success(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
);
2009 else
2010 unit_log_failure(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, socket_result_to_string(s->result));
2011
2012 socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD);
2013
2014 s->exec_runtime = exec_runtime_unref(s->exec_runtime, true1);
2015
2016 exec_context_destroy_runtime_directory(&s->exec_context, UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
2017
2018 unit_unref_uid_gid(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, true1);
2019
2020 dynamic_creds_destroy(&s->dynamic_creds);
2021}
2022
2023static void socket_enter_signal(Socket *s, SocketState state, SocketResult f);
2024
2025static void socket_enter_stop_post(Socket *s, SocketResult f) {
2026 int r;
2027 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2027, __PRETTY_FUNCTION__
); } while (0)
;
2028
2029 if (s->result == SOCKET_SUCCESS)
2030 s->result = f;
2031
2032 socket_unwatch_control_pid(s);
2033 s->control_command_id = SOCKET_EXEC_STOP_POST;
2034 s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST];
2035
2036 if (s->control_command) {
2037 r = socket_spawn(s, s->control_command, &s->control_pid);
2038 if (r < 0)
2039 goto fail;
2040
2041 socket_set_state(s, SOCKET_STOP_POST);
2042 } else
2043 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS);
2044
2045 return;
2046
2047fail:
2048 log_unit_warning_errno(UNIT(s), r, "Failed to run 'stop-post' task: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 2048, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to run 'stop-post' task: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/core/socket.c", 2048, __func__, "Failed to run 'stop-post' task: %m"
); })
;
2049 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
2050}
2051
2052static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) {
2053 int r;
2054
2055 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2055, __PRETTY_FUNCTION__
); } while (0)
;
2056
2057 if (s->result == SOCKET_SUCCESS)
2058 s->result = f;
2059
2060 r = unit_kill_context(
2061 UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
,
2062 &s->kill_context,
2063 !IN_SET(state, SOCKET_STOP_PRE_SIGTERM, SOCKET_FINAL_SIGTERM)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE_SIGTERM, SOCKET_FINAL_SIGTERM
})/sizeof(int)]; switch(state) { case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_FINAL_SIGTERM: _found = 1; break; default: break
; } _found; })
?
2064 KILL_KILL : KILL_TERMINATE,
2065 -1,
2066 s->control_pid,
2067 false0);
2068 if (r < 0)
2069 goto fail;
2070
2071 if (r > 0) {
2072 r = socket_arm_timer(s, usec_add(now(CLOCK_MONOTONIC1), s->timeout_usec));
2073 if (r < 0)
2074 goto fail;
2075
2076 socket_set_state(s, state);
2077 } else if (state == SOCKET_STOP_PRE_SIGTERM)
2078 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_SUCCESS);
2079 else if (state == SOCKET_STOP_PRE_SIGKILL)
2080 socket_enter_stop_post(s, SOCKET_SUCCESS);
2081 else if (state == SOCKET_FINAL_SIGTERM)
2082 socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_SUCCESS);
2083 else
2084 socket_enter_dead(s, SOCKET_SUCCESS);
2085
2086 return;
2087
2088fail:
2089 log_unit_warning_errno(UNIT(s), r, "Failed to kill processes: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 2089, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to kill processes: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/core/socket.c", 2089, __func__, "Failed to kill processes: %m"
); })
;
2090
2091 if (IN_SET(state, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_PRE_SIGKILL
})/sizeof(int)]; switch(state) { case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_PRE_SIGKILL: _found = 1; break; default: break
; } _found; })
)
2092 socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
2093 else
2094 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
2095}
2096
2097static void socket_enter_stop_pre(Socket *s, SocketResult f) {
2098 int r;
2099 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2099, __PRETTY_FUNCTION__
); } while (0)
;
2100
2101 if (s->result == SOCKET_SUCCESS)
2102 s->result = f;
2103
2104 socket_unwatch_control_pid(s);
2105 s->control_command_id = SOCKET_EXEC_STOP_PRE;
2106 s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE];
2107
2108 if (s->control_command) {
2109 r = socket_spawn(s, s->control_command, &s->control_pid);
2110 if (r < 0)
2111 goto fail;
2112
2113 socket_set_state(s, SOCKET_STOP_PRE);
2114 } else
2115 socket_enter_stop_post(s, SOCKET_SUCCESS);
2116
2117 return;
2118
2119fail:
2120 log_unit_warning_errno(UNIT(s), r, "Failed to run 'stop-pre' task: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 2120, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to run 'stop-pre' task: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/core/socket.c", 2120, __func__, "Failed to run 'stop-pre' task: %m"
); })
;
2121 socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
2122}
2123
2124static void socket_enter_listening(Socket *s) {
2125 int r;
2126 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2126, __PRETTY_FUNCTION__
); } while (0)
;
2127
2128 if (!s->accept && s->flush_pending) {
2129 log_unit_debug(UNIT(s), "Flushing socket before listening.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(7, 0, "../src/core/socket.c", 2129, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Flushing socket before listening."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7
))), 0, "../src/core/socket.c", 2129, __func__, "Flushing socket before listening."
); })
;
2130 flush_ports(s);
2131 }
2132
2133 r = socket_watch_fds(s);
2134 if (r < 0) {
2135 log_unit_warning_errno(UNIT(s), r, "Failed to watch sockets: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 2135, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to watch sockets: %m")
: log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)
)), r, "../src/core/socket.c", 2135, __func__, "Failed to watch sockets: %m"
); })
;
2136 goto fail;
2137 }
2138
2139 socket_set_state(s, SOCKET_LISTENING);
2140 return;
2141
2142fail:
2143 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
2144}
2145
2146static void socket_enter_start_post(Socket *s) {
2147 int r;
2148 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2148, __PRETTY_FUNCTION__
); } while (0)
;
2149
2150 socket_unwatch_control_pid(s);
2151 s->control_command_id = SOCKET_EXEC_START_POST;
2152 s->control_command = s->exec_command[SOCKET_EXEC_START_POST];
2153
2154 if (s->control_command) {
2155 r = socket_spawn(s, s->control_command, &s->control_pid);
2156 if (r < 0) {
2157 log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-post' task: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 2157, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to run 'start-post' task: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/core/socket.c", 2157, __func__, "Failed to run 'start-post' task: %m"
); })
;
2158 goto fail;
2159 }
2160
2161 socket_set_state(s, SOCKET_START_POST);
2162 } else
2163 socket_enter_listening(s);
2164
2165 return;
2166
2167fail:
2168 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
2169}
2170
2171static void socket_enter_start_chown(Socket *s) {
2172 int r;
2173
2174 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2174, __PRETTY_FUNCTION__
); } while (0)
;
2175
2176 r = socket_open_fds(s);
2177 if (r < 0) {
2178 log_unit_warning_errno(UNIT(s), r, "Failed to listen on sockets: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 2178, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to listen on sockets: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/core/socket.c", 2178, __func__, "Failed to listen on sockets: %m"
); })
;
2179 goto fail;
2180 }
2181
2182 if (!isempty(s->user) || !isempty(s->group)) {
2183
2184 socket_unwatch_control_pid(s);
2185 s->control_command_id = SOCKET_EXEC_START_CHOWN;
2186 s->control_command = NULL((void*)0);
2187
2188 r = socket_chown(s, &s->control_pid);
2189 if (r < 0) {
2190 log_unit_warning_errno(UNIT(s), r, "Failed to fork 'start-chown' task: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 2190, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to fork 'start-chown' task: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/core/socket.c", 2190, __func__, "Failed to fork 'start-chown' task: %m"
); })
;
2191 goto fail;
2192 }
2193
2194 socket_set_state(s, SOCKET_START_CHOWN);
2195 } else
2196 socket_enter_start_post(s);
2197
2198 return;
2199
2200fail:
2201 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
2202}
2203
2204static void socket_enter_start_pre(Socket *s) {
2205 int r;
2206 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2206, __PRETTY_FUNCTION__
); } while (0)
;
2207
2208 socket_unwatch_control_pid(s);
2209
2210 unit_warn_leftover_processes(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
);
2211
2212 s->control_command_id = SOCKET_EXEC_START_PRE;
2213 s->control_command = s->exec_command[SOCKET_EXEC_START_PRE];
2214
2215 if (s->control_command) {
2216 r = socket_spawn(s, s->control_command, &s->control_pid);
2217 if (r < 0) {
2218 log_unit_warning_errno(UNIT(s), r, "Failed to run 'start-pre' task: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 2218, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to run 'start-pre' task: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), r, "../src/core/socket.c", 2218, __func__, "Failed to run 'start-pre' task: %m"
); })
;
2219 goto fail;
2220 }
2221
2222 socket_set_state(s, SOCKET_START_PRE);
2223 } else
2224 socket_enter_start_chown(s);
2225
2226 return;
2227
2228fail:
2229 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
2230}
2231
2232static void flush_ports(Socket *s) {
2233 SocketPort *p;
2234
2235 /* Flush all incoming traffic, regardless if actual bytes or new connections, so that this socket isn't busy
2236 * anymore */
2237
2238 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
2239 if (p->fd < 0)
2240 continue;
2241
2242 (void) flush_accept(p->fd);
2243 (void) flush_fd(p->fd);
2244 }
2245}
2246
2247static void socket_enter_running(Socket *s, int cfd) {
2248 _cleanup_(sd_bus_error_free)__attribute__((cleanup(sd_bus_error_free))) sd_bus_error error = SD_BUS_ERROR_NULL((const sd_bus_error) {(((void*)0)), (((void*)0)), 0});
2249 int r;
2250
2251 /* Note that this call takes possession of the connection fd passed. It either has to assign it somewhere or
2252 * close it. */
2253
2254 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2254, __PRETTY_FUNCTION__
); } while (0)
;
2255
2256 /* We don't take connections anymore if we are supposed to shut down anyway */
2257 if (unit_stop_pending(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
)) {
2258
2259 log_unit_debug(UNIT(s), "Suppressing connection request since unit stop is scheduled.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(7, 0, "../src/core/socket.c", 2259, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Suppressing connection request since unit stop is scheduled."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7
))), 0, "../src/core/socket.c", 2259, __func__, "Suppressing connection request since unit stop is scheduled."
); })
;
2260
2261 if (cfd >= 0)
2262 goto refuse;
2263 else
2264 flush_ports(s);
2265
2266 return;
2267 }
2268
2269 if (!ratelimit_below(&s->trigger_limit)) {
2270 log_unit_warning(UNIT(s), "Trigger limit hit, refusing further activation.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 2270, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Trigger limit hit, refusing further activation."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 2270, __func__, "Trigger limit hit, refusing further activation."
); })
;
2271 socket_enter_stop_pre(s, SOCKET_FAILURE_TRIGGER_LIMIT_HIT);
2272 goto refuse;
2273 }
2274
2275 if (cfd < 0) {
2276 bool_Bool pending = false0;
2277 Unit *other;
2278 Iterator i;
2279 void *v;
2280
2281 /* If there's already a start pending don't bother to
2282 * do anything */
2283 HASHMAP_FOREACH_KEY(v, other, UNIT(s)->dependencies[UNIT_TRIGGERS], i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }); hashmap_iterate((({ typeof(s) _u_ =
(s); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_
; })->dependencies[UNIT_TRIGGERS]), &(i), (void**)&
(v), (const void**) &(other)); )
2284 if (unit_active_or_pending(other)) {
2285 pending = true1;
2286 break;
2287 }
2288
2289 if (!pending) {
2290 if (!UNIT_ISSET(s->service)(!!(s->service).target)) {
2291 log_unit_error(UNIT(s), "Service to activate vanished, refusing activation.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, 0, "../src/core/socket.c", 2291, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Service to activate vanished, refusing activation."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/core/socket.c", 2291, __func__, "Service to activate vanished, refusing activation."
); })
;
2292 r = -ENOENT2;
2293 goto fail;
2294 }
2295
2296 r = manager_add_job(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->manager, JOB_START, UNIT_DEREF(s->service)((s->service).target), JOB_REPLACE, NULL((void*)0), &error, NULL((void*)0));
2297 if (r < 0)
2298 goto fail;
2299 }
2300
2301 socket_set_state(s, SOCKET_RUNNING);
2302 } else {
2303 _cleanup_free___attribute__((cleanup(freep))) char *prefix = NULL((void*)0), *instance = NULL((void*)0), *name = NULL((void*)0);
2304 _cleanup_(socket_peer_unrefp)__attribute__((cleanup(socket_peer_unrefp))) SocketPeer *p = NULL((void*)0);
2305 Service *service;
2306
2307 if (s->n_connections >= s->max_connections) {
2308 log_unit_warning(UNIT(s), "Too many incoming connections (%u), dropping connection.",({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 2309, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Too many incoming connections (%u), dropping connection."
, s->n_connections) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((4))), 0, "../src/core/socket.c", 2309, __func__
, "Too many incoming connections (%u), dropping connection.",
s->n_connections); })
2309 s->n_connections)({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 2309, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Too many incoming connections (%u), dropping connection."
, s->n_connections) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((4))), 0, "../src/core/socket.c", 2309, __func__
, "Too many incoming connections (%u), dropping connection.",
s->n_connections); })
;
2310 goto refuse;
2311 }
2312
2313 if (s->max_connections_per_source > 0) {
2314 r = socket_acquire_peer(s, cfd, &p);
2315 if (r < 0) {
2316 goto refuse;
2317 } else if (r > 0 && p->n_ref > s->max_connections_per_source) {
2318 _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0);
2319
2320 (void) sockaddr_pretty(&p->peer.sa, p->peer_salen, true1, false0, &t);
2321
2322 log_unit_warning(UNIT(s),({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 2324, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Too many incoming connections (%u) from source %s, dropping connection."
, p->n_ref, strnull(t)) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((4))), 0, "../src/core/socket.c", 2324, __func__
, "Too many incoming connections (%u) from source %s, dropping connection."
, p->n_ref, strnull(t)); })
2323 "Too many incoming connections (%u) from source %s, dropping connection.",({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 2324, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Too many incoming connections (%u) from source %s, dropping connection."
, p->n_ref, strnull(t)) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((4))), 0, "../src/core/socket.c", 2324, __func__
, "Too many incoming connections (%u) from source %s, dropping connection."
, p->n_ref, strnull(t)); })
2324 p->n_ref, strnull(t))({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 2324, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Too many incoming connections (%u) from source %s, dropping connection."
, p->n_ref, strnull(t)) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((4))), 0, "../src/core/socket.c", 2324, __func__
, "Too many incoming connections (%u) from source %s, dropping connection."
, p->n_ref, strnull(t)); })
;
2325 goto refuse;
2326 }
2327 }
2328
2329 r = socket_instantiate_service(s);
2330 if (r < 0)
2331 goto fail;
2332
2333 r = instance_from_socket(cfd, s->n_accepted, &instance);
2334 if (r < 0) {
2335 if (r != -ENOTCONN107)
2336 goto fail;
2337
2338 /* ENOTCONN is legitimate if TCP RST was received.
2339 * This connection is over, but the socket unit lives on. */
2340 log_unit_debug(UNIT(s), "Got ENOTCONN on incoming socket, assuming aborted connection attempt, ignoring.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(7, 0, "../src/core/socket.c", 2340, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Got ENOTCONN on incoming socket, assuming aborted connection attempt, ignoring."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((7
))), 0, "../src/core/socket.c", 2340, __func__, "Got ENOTCONN on incoming socket, assuming aborted connection attempt, ignoring."
); })
;
2341 goto refuse;
2342 }
2343
2344 r = unit_name_to_prefix(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->id, &prefix);
2345 if (r < 0)
2346 goto fail;
2347
2348 r = unit_name_build(prefix, instance, ".service", &name);
2349 if (r < 0)
2350 goto fail;
2351
2352 r = unit_add_name(UNIT_DEREF(s->service)((s->service).target), name);
2353 if (r < 0)
2354 goto fail;
2355
2356 service = SERVICE(UNIT_DEREF(s->service)((s->service).target));
2357 unit_ref_unset(&s->service);
2358
2359 s->n_accepted++;
2360 unit_choose_id(UNIT(service)({ typeof(service) _u_ = (service); Unit *_w_ = _u_ ? &(_u_
)->meta : ((void*)0); _w_; })
, name);
2361
2362 r = service_set_socket_fd(service, cfd, s, s->selinux_context_from_net);
2363 if (r < 0)
2364 goto fail;
2365
2366 cfd = -1; /* We passed ownership of the fd to the service now. Forget it here. */
2367 s->n_connections++;
2368
2369 service->peer = TAKE_PTR(p)({ typeof(p) _ptr_ = (p); (p) = ((void*)0); _ptr_; }); /* Pass ownership of the peer reference */
2370
2371 r = manager_add_job(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->manager, JOB_START, UNIT(service)({ typeof(service) _u_ = (service); Unit *_w_ = _u_ ? &(_u_
)->meta : ((void*)0); _w_; })
, JOB_REPLACE, NULL((void*)0), &error, NULL((void*)0));
2372 if (r < 0) {
2373 /* We failed to activate the new service, but it still exists. Let's make sure the service
2374 * closes and forgets the connection fd again, immediately. */
2375 service_close_socket_fd(service);
2376 goto fail;
2377 }
2378
2379 /* Notify clients about changed counters */
2380 unit_add_to_dbus_queue(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
);
2381 }
2382
2383 return;
2384
2385refuse:
2386 s->n_refused++;
2387 safe_close(cfd);
2388 return;
2389
2390fail:
2391 log_unit_warning(UNIT(s), "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 2393, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s"
, cfd >= 0 ? "template" : "non-template", bus_error_message
(&error, r)) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((4))), 0, "../src/core/socket.c", 2393, __func__, "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s"
, cfd >= 0 ? "template" : "non-template", bus_error_message
(&error, r)); })
2392 cfd >= 0 ? "template" : "non-template",({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 2393, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s"
, cfd >= 0 ? "template" : "non-template", bus_error_message
(&error, r)) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((4))), 0, "../src/core/socket.c", 2393, __func__, "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s"
, cfd >= 0 ? "template" : "non-template", bus_error_message
(&error, r)); })
2393 bus_error_message(&error, r))({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 2393, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s"
, cfd >= 0 ? "template" : "non-template", bus_error_message
(&error, r)) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((4))), 0, "../src/core/socket.c", 2393, __func__, "Failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s"
, cfd >= 0 ? "template" : "non-template", bus_error_message
(&error, r)); })
;
2394
2395 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
2396 safe_close(cfd);
2397}
2398
2399static void socket_run_next(Socket *s) {
2400 int r;
2401
2402 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2402, __PRETTY_FUNCTION__
); } while (0)
;
2403 assert(s->control_command)do { if ((__builtin_expect(!!(!(s->control_command)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s->control_command"), "../src/core/socket.c"
, 2403, __PRETTY_FUNCTION__); } while (0)
;
2404 assert(s->control_command->command_next)do { if ((__builtin_expect(!!(!(s->control_command->command_next
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->control_command->command_next"
), "../src/core/socket.c", 2404, __PRETTY_FUNCTION__); } while
(0)
;
2405
2406 socket_unwatch_control_pid(s);
2407
2408 s->control_command = s->control_command->command_next;
2409
2410 r = socket_spawn(s, s->control_command, &s->control_pid);
2411 if (r < 0)
2412 goto fail;
2413
2414 return;
2415
2416fail:
2417 log_unit_warning_errno(UNIT(s), r, "Failed to run next task: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, r, "../src/core/socket.c", 2417, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to run next task: %m")
: log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4)
)), r, "../src/core/socket.c", 2417, __func__, "Failed to run next task: %m"
); })
;
2418
2419 if (s->state == SOCKET_START_POST)
2420 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
2421 else if (s->state == SOCKET_STOP_POST)
2422 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
2423 else
2424 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
2425}
2426
2427static int socket_start(Unit *u) {
2428 Socket *s = SOCKET(u);
2429 int r;
2430
2431 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2431, __PRETTY_FUNCTION__
); } while (0)
;
2432
2433 /* We cannot fulfill this request right now, try again later
2434 * please! */
2435 if (IN_SET(s->state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2436 SOCKET_STOP_PRE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2437 SOCKET_STOP_PRE_SIGKILL,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2438 SOCKET_STOP_PRE_SIGTERM,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2439 SOCKET_STOP_POST,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2440 SOCKET_FINAL_SIGTERM,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2441 SOCKET_FINAL_SIGKILL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGKILL
, SOCKET_STOP_PRE_SIGTERM, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGKILL: case SOCKET_STOP_PRE_SIGTERM
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
)
2442 return -EAGAIN11;
2443
2444 /* Already on it! */
2445 if (IN_SET(s->state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
})/sizeof(int)]; switch(s->state) { case SOCKET_START_PRE:
case SOCKET_START_CHOWN: case SOCKET_START_POST: _found = 1;
break; default: break; } _found; })
2446 SOCKET_START_PRE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
})/sizeof(int)]; switch(s->state) { case SOCKET_START_PRE:
case SOCKET_START_CHOWN: case SOCKET_START_POST: _found = 1;
break; default: break; } _found; })
2447 SOCKET_START_CHOWN,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
})/sizeof(int)]; switch(s->state) { case SOCKET_START_PRE:
case SOCKET_START_CHOWN: case SOCKET_START_POST: _found = 1;
break; default: break; } _found; })
2448 SOCKET_START_POST)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
})/sizeof(int)]; switch(s->state) { case SOCKET_START_PRE:
case SOCKET_START_CHOWN: case SOCKET_START_POST: _found = 1;
break; default: break; } _found; })
)
2449 return 0;
2450
2451 /* Cannot run this without the service being around */
2452 if (UNIT_ISSET(s->service)(!!(s->service).target)) {
2453 Service *service;
2454
2455 service = SERVICE(UNIT_DEREF(s->service)((s->service).target));
2456
2457 if (UNIT(service)({ typeof(service) _u_ = (service); Unit *_w_ = _u_ ? &(_u_
)->meta : ((void*)0); _w_; })
->load_state != UNIT_LOADED) {
2458 log_unit_error(u, "Socket service %s not loaded, refusing.", UNIT(service)->id)({ const Unit *_u = (u); _u ? log_object_internal(3, 0, "../src/core/socket.c"
, 2458, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Socket service %s not loaded, refusing.", ({ typeof(service
) _u_ = (service); Unit *_w_ = _u_ ? &(_u_)->meta : ((
void*)0); _w_; })->id) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((3))), 0, "../src/core/socket.c", 2458, __func__
, "Socket service %s not loaded, refusing.", ({ typeof(service
) _u_ = (service); Unit *_w_ = _u_ ? &(_u_)->meta : ((
void*)0); _w_; })->id); })
;
2459 return -ENOENT2;
2460 }
2461
2462 /* If the service is already active we cannot start the
2463 * socket */
2464 if (!IN_SET(service->state, SERVICE_DEAD, SERVICE_FAILED, SERVICE_AUTO_RESTART)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SERVICE_DEAD, SERVICE_FAILED, SERVICE_AUTO_RESTART
})/sizeof(int)]; switch(service->state) { case SERVICE_DEAD
: case SERVICE_FAILED: case SERVICE_AUTO_RESTART: _found = 1;
break; default: break; } _found; })
) {
2465 log_unit_error(u, "Socket service %s already active, refusing.", UNIT(service)->id)({ const Unit *_u = (u); _u ? log_object_internal(3, 0, "../src/core/socket.c"
, 2465, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Socket service %s already active, refusing.", ({ typeof(service
) _u_ = (service); Unit *_w_ = _u_ ? &(_u_)->meta : ((
void*)0); _w_; })->id) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((3))), 0, "../src/core/socket.c", 2465, __func__
, "Socket service %s already active, refusing.", ({ typeof(service
) _u_ = (service); Unit *_w_ = _u_ ? &(_u_)->meta : ((
void*)0); _w_; })->id); })
;
2466 return -EBUSY16;
2467 }
2468 }
2469
2470 assert(IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SOCKET_DEAD, SOCKET_FAILED})/sizeof(int)]; switch
(s->state) { case SOCKET_DEAD: case SOCKET_FAILED: _found =
1; break; default: break; } _found; }))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("IN_SET(s->state, SOCKET_DEAD, SOCKET_FAILED)"
), "../src/core/socket.c", 2470, __PRETTY_FUNCTION__); } while
(0)
;
2471
2472 r = unit_start_limit_test(u);
2473 if (r < 0) {
2474 socket_enter_dead(s, SOCKET_FAILURE_START_LIMIT_HIT);
2475 return r;
2476 }
2477
2478 r = unit_acquire_invocation_id(u);
2479 if (r < 0)
2480 return r;
2481
2482 s->result = SOCKET_SUCCESS;
2483
2484 u->reset_accounting = true1;
2485
2486 socket_enter_start_pre(s);
2487 return 1;
2488}
2489
2490static int socket_stop(Unit *u) {
2491 Socket *s = SOCKET(u);
2492
2493 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2493, __PRETTY_FUNCTION__
); } while (0)
;
2494
2495 /* Already on it */
2496 if (IN_SET(s->state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM
, SOCKET_STOP_PRE_SIGKILL, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2497 SOCKET_STOP_PRE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM
, SOCKET_STOP_PRE_SIGKILL, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2498 SOCKET_STOP_PRE_SIGTERM,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM
, SOCKET_STOP_PRE_SIGKILL, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2499 SOCKET_STOP_PRE_SIGKILL,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM
, SOCKET_STOP_PRE_SIGKILL, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2500 SOCKET_STOP_POST,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM
, SOCKET_STOP_PRE_SIGKILL, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2501 SOCKET_FINAL_SIGTERM,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM
, SOCKET_STOP_PRE_SIGKILL, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
2502 SOCKET_FINAL_SIGKILL)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_STOP_PRE, SOCKET_STOP_PRE_SIGTERM
, SOCKET_STOP_PRE_SIGKILL, SOCKET_STOP_POST, SOCKET_FINAL_SIGTERM
, SOCKET_FINAL_SIGKILL})/sizeof(int)]; switch(s->state) { case
SOCKET_STOP_PRE: case SOCKET_STOP_PRE_SIGTERM: case SOCKET_STOP_PRE_SIGKILL
: case SOCKET_STOP_POST: case SOCKET_FINAL_SIGTERM: case SOCKET_FINAL_SIGKILL
: _found = 1; break; default: break; } _found; })
)
2503 return 0;
2504
2505 /* If there's already something running we go directly into
2506 * kill mode. */
2507 if (IN_SET(s->state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
})/sizeof(int)]; switch(s->state) { case SOCKET_START_PRE:
case SOCKET_START_CHOWN: case SOCKET_START_POST: _found = 1;
break; default: break; } _found; })
2508 SOCKET_START_PRE,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
})/sizeof(int)]; switch(s->state) { case SOCKET_START_PRE:
case SOCKET_START_CHOWN: case SOCKET_START_POST: _found = 1;
break; default: break; } _found; })
2509 SOCKET_START_CHOWN,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
})/sizeof(int)]; switch(s->state) { case SOCKET_START_PRE:
case SOCKET_START_CHOWN: case SOCKET_START_POST: _found = 1;
break; default: break; } _found; })
2510 SOCKET_START_POST)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_START_PRE, SOCKET_START_CHOWN, SOCKET_START_POST
})/sizeof(int)]; switch(s->state) { case SOCKET_START_PRE:
case SOCKET_START_CHOWN: case SOCKET_START_POST: _found = 1;
break; default: break; } _found; })
) {
2511 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS);
2512 return -EAGAIN11;
2513 }
2514
2515 assert(IN_SET(s->state, SOCKET_LISTENING, SOCKET_RUNNING))do { if ((__builtin_expect(!!(!(({ _Bool _found = 0; static __attribute__
((unused)) char _static_assert__macros_need_to_be_extended[20
- sizeof((int[]){SOCKET_LISTENING, SOCKET_RUNNING})/sizeof(int
)]; switch(s->state) { case SOCKET_LISTENING: case SOCKET_RUNNING
: _found = 1; break; default: break; } _found; }))),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("IN_SET(s->state, SOCKET_LISTENING, SOCKET_RUNNING)"
), "../src/core/socket.c", 2515, __PRETTY_FUNCTION__); } while
(0)
;
2516
2517 socket_enter_stop_pre(s, SOCKET_SUCCESS);
2518 return 1;
2519}
2520
2521static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
2522 Socket *s = SOCKET(u);
2523 SocketPort *p;
2524 int r;
2525
2526 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/socket.c", 2526, __PRETTY_FUNCTION__
); } while (0)
;
2527 assert(f)do { if ((__builtin_expect(!!(!(f)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("f"), "../src/core/socket.c", 2527, __PRETTY_FUNCTION__
); } while (0)
;
2528 assert(fds)do { if ((__builtin_expect(!!(!(fds)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fds"), "../src/core/socket.c", 2528, __PRETTY_FUNCTION__
); } while (0)
;
2529
2530 unit_serialize_item(u, f, "state", socket_state_to_string(s->state));
2531 unit_serialize_item(u, f, "result", socket_result_to_string(s->result));
2532 unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted);
2533 unit_serialize_item_format(u, f, "n-refused", "%u", s->n_refused);
2534
2535 if (s->control_pid > 0)
2536 unit_serialize_item_format(u, f, "control-pid", PID_FMT"%" "i", s->control_pid);
2537
2538 if (s->control_command_id >= 0)
2539 unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id));
2540
2541 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
2542 int copy;
2543
2544 if (p->fd < 0)
2545 continue;
2546
2547 copy = fdset_put_dup(fds, p->fd);
2548 if (copy < 0)
2549 return copy;
2550
2551 if (p->type == SOCKET_SOCKET) {
2552 _cleanup_free___attribute__((cleanup(freep))) char *t = NULL((void*)0);
2553
2554 r = socket_address_print(&p->address, &t);
2555 if (r < 0)
2556 return r;
2557
2558 if (socket_address_family(&p->address)((&p->address)->sockaddr.sa.sa_family) == AF_NETLINK16)
2559 unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t);
2560 else
2561 unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t);
2562
2563 } else if (p->type == SOCKET_SPECIAL)
2564 unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path);
2565 else if (p->type == SOCKET_MQUEUE)
2566 unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path);
2567 else if (p->type == SOCKET_USB_FUNCTION)
2568 unit_serialize_item_format(u, f, "ffs", "%i %s", copy, p->path);
2569 else {
2570 assert(p->type == SOCKET_FIFO)do { if ((__builtin_expect(!!(!(p->type == SOCKET_FIFO)),0
))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("p->type == SOCKET_FIFO"
), "../src/core/socket.c", 2570, __PRETTY_FUNCTION__); } while
(0)
;
2571 unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path);
2572 }
2573 }
2574
2575 return 0;
2576}
2577
2578static void socket_port_take_fd(SocketPort *p, FDSet *fds, int fd) {
2579 safe_close(p->fd);
2580 p->fd = fdset_remove(fds, fd);
2581}
2582
2583static int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
2584 Socket *s = SOCKET(u);
2585
2586 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/socket.c", 2586, __PRETTY_FUNCTION__
); } while (0)
;
2587 assert(key)do { if ((__builtin_expect(!!(!(key)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("key"), "../src/core/socket.c", 2587, __PRETTY_FUNCTION__
); } while (0)
;
2588 assert(value)do { if ((__builtin_expect(!!(!(value)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("value"), "../src/core/socket.c", 2588, __PRETTY_FUNCTION__
); } while (0)
;
2589
2590 if (streq(key, "state")(strcmp((key),("state")) == 0)) {
2591 SocketState state;
2592
2593 state = socket_state_from_string(value);
2594 if (state < 0)
2595 log_unit_debug(u, "Failed to parse state value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2595, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse state value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2595, __func__, "Failed to parse state value: %s", value); }
)
;
2596 else
2597 s->deserialized_state = state;
2598 } else if (streq(key, "result")(strcmp((key),("result")) == 0)) {
2599 SocketResult f;
2600
2601 f = socket_result_from_string(value);
2602 if (f < 0)
2603 log_unit_debug(u, "Failed to parse result value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2603, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse result value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2603, __func__, "Failed to parse result value: %s", value);
})
;
2604 else if (f != SOCKET_SUCCESS)
2605 s->result = f;
2606
2607 } else if (streq(key, "n-accepted")(strcmp((key),("n-accepted")) == 0)) {
2608 unsigned k;
2609
2610 if (safe_atou(value, &k) < 0)
2611 log_unit_debug(u, "Failed to parse n-accepted value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2611, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse n-accepted value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2611, __func__, "Failed to parse n-accepted value: %s", value
); })
;
2612 else
2613 s->n_accepted += k;
2614 } else if (streq(key, "n-refused")(strcmp((key),("n-refused")) == 0)) {
2615 unsigned k;
2616
2617 if (safe_atou(value, &k) < 0)
2618 log_unit_debug(u, "Failed to parse n-refused value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2618, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse n-refused value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2618, __func__, "Failed to parse n-refused value: %s", value
); })
;
2619 else
2620 s->n_refused += k;
2621 } else if (streq(key, "control-pid")(strcmp((key),("control-pid")) == 0)) {
2622 pid_t pid;
2623
2624 if (parse_pid(value, &pid) < 0)
2625 log_unit_debug(u, "Failed to parse control-pid value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2625, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse control-pid value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2625, __func__, "Failed to parse control-pid value: %s", value
); })
;
2626 else
2627 s->control_pid = pid;
2628 } else if (streq(key, "control-command")(strcmp((key),("control-command")) == 0)) {
2629 SocketExecCommand id;
2630
2631 id = socket_exec_command_from_string(value);
2632 if (id < 0)
2633 log_unit_debug(u, "Failed to parse exec-command value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2633, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse exec-command value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2633, __func__, "Failed to parse exec-command value: %s", value
); })
;
2634 else {
2635 s->control_command_id = id;
2636 s->control_command = s->exec_command[id];
2637 }
2638 } else if (streq(key, "fifo")(strcmp((key),("fifo")) == 0)) {
2639 int fd, skip = 0;
2640 SocketPort *p;
2641
2642 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
2643 log_unit_debug(u, "Failed to parse fifo value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2643, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse fifo value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2643, __func__, "Failed to parse fifo value: %s", value); }
)
;
2644 else
2645 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next)
2646 if (p->type == SOCKET_FIFO &&
2647 path_equal_or_files_same(p->path, value+skip, 0)) {
2648 socket_port_take_fd(p, fds, fd);
2649 break;
2650 }
2651
2652 } else if (streq(key, "special")(strcmp((key),("special")) == 0)) {
2653 int fd, skip = 0;
2654 SocketPort *p;
2655
2656 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
2657 log_unit_debug(u, "Failed to parse special value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2657, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse special value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2657, __func__, "Failed to parse special value: %s", value)
; })
;
2658 else
2659 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next)
2660 if (p->type == SOCKET_SPECIAL &&
2661 path_equal_or_files_same(p->path, value+skip, 0)) {
2662 socket_port_take_fd(p, fds, fd);
2663 break;
2664 }
2665
2666 } else if (streq(key, "mqueue")(strcmp((key),("mqueue")) == 0)) {
2667 int fd, skip = 0;
2668 SocketPort *p;
2669
2670 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
2671 log_unit_debug(u, "Failed to parse mqueue value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2671, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse mqueue value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2671, __func__, "Failed to parse mqueue value: %s", value);
})
;
2672 else
2673 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next)
2674 if (p->type == SOCKET_MQUEUE &&
2675 streq(p->path, value+skip)(strcmp((p->path),(value+skip)) == 0)) {
2676 socket_port_take_fd(p, fds, fd);
2677 break;
2678 }
2679
2680 } else if (streq(key, "socket")(strcmp((key),("socket")) == 0)) {
2681 int fd, type, skip = 0;
2682 SocketPort *p;
2683
2684 if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd))
2685 log_unit_debug(u, "Failed to parse socket value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2685, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse socket value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2685, __func__, "Failed to parse socket value: %s", value);
})
;
2686 else
2687 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next)
2688 if (socket_address_is(&p->address, value+skip, type)) {
2689 socket_port_take_fd(p, fds, fd);
2690 break;
2691 }
2692
2693 } else if (streq(key, "netlink")(strcmp((key),("netlink")) == 0)) {
2694 int fd, skip = 0;
2695 SocketPort *p;
2696
2697 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
2698 log_unit_debug(u, "Failed to parse socket value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2698, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse socket value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2698, __func__, "Failed to parse socket value: %s", value);
})
;
2699 else
2700 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next)
2701 if (socket_address_is_netlink(&p->address, value+skip)) {
2702 socket_port_take_fd(p, fds, fd);
2703 break;
2704 }
2705
2706 } else if (streq(key, "ffs")(strcmp((key),("ffs")) == 0)) {
2707 int fd, skip = 0;
2708 SocketPort *p;
2709
2710 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
2711 log_unit_debug(u, "Failed to parse ffs value: %s", value)({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 2711, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Failed to parse ffs value: %s", value) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((7))), 0, "../src/core/socket.c"
, 2711, __func__, "Failed to parse ffs value: %s", value); })
;
2712 else
2713 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next)
2714 if (p->type == SOCKET_USB_FUNCTION &&
2715 path_equal_or_files_same(p->path, value+skip, 0)) {
2716 socket_port_take_fd(p, fds, fd);
2717 break;
2718 }
2719
2720 } else
2721 log_unit_debug(UNIT(s), "Unknown serialization key: %s", key)({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(7, 0, "../src/core/socket.c", 2721, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Unknown serialization key: %s"
, key) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 |
((7))), 0, "../src/core/socket.c", 2721, __func__, "Unknown serialization key: %s"
, key); })
;
2722
2723 return 0;
2724}
2725
2726static void socket_distribute_fds(Unit *u, FDSet *fds) {
2727 Socket *s = SOCKET(u);
2728 SocketPort *p;
2729
2730 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/socket.c", 2730, __PRETTY_FUNCTION__
); } while (0)
;
2731
2732 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
2733 Iterator i;
2734 int fd;
2735
2736 if (p->type != SOCKET_SOCKET)
2737 continue;
2738
2739 if (p->fd >= 0)
2740 continue;
2741
2742 FDSET_FOREACH(fd, fds, i)for ((i) = ((Iterator) { .idx = ((2147483647 *2U +1U) - 1), .
next_key = ((void*)0) }), (fd) = fdset_iterate((fds), &(i
)); (fd) >= 0; (fd) = fdset_iterate((fds), &(i)))
{
2743 if (socket_address_matches_fd(&p->address, fd)) {
2744 p->fd = fdset_remove(fds, fd);
2745 s->deserialized_state = SOCKET_LISTENING;
2746 break;
2747 }
2748 }
2749 }
2750}
2751
2752_pure___attribute__ ((pure)) static UnitActiveState socket_active_state(Unit *u) {
2753 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/socket.c", 2753, __PRETTY_FUNCTION__
); } while (0)
;
2754
2755 return state_translation_table[SOCKET(u)->state];
2756}
2757
2758_pure___attribute__ ((pure)) static const char *socket_sub_state_to_string(Unit *u) {
2759 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/socket.c", 2759, __PRETTY_FUNCTION__
); } while (0)
;
2760
2761 return socket_state_to_string(SOCKET(u)->state);
2762}
2763
2764const char* socket_port_type_to_string(SocketPort *p) {
2765
2766 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/core/socket.c", 2766, __PRETTY_FUNCTION__
); } while (0)
;
2767
2768 switch (p->type) {
2769
2770 case SOCKET_SOCKET:
2771
2772 switch (p->address.type) {
2773
2774 case SOCK_STREAMSOCK_STREAM:
2775 return "Stream";
2776
2777 case SOCK_DGRAMSOCK_DGRAM:
2778 return "Datagram";
2779
2780 case SOCK_SEQPACKETSOCK_SEQPACKET:
2781 return "SequentialPacket";
2782
2783 case SOCK_RAWSOCK_RAW:
2784 if (socket_address_family(&p->address)((&p->address)->sockaddr.sa.sa_family) == AF_NETLINK16)
2785 return "Netlink";
2786
2787 _fallthrough_;
2788 default:
2789 return NULL((void*)0);
2790 }
2791
2792 case SOCKET_SPECIAL:
2793 return "Special";
2794
2795 case SOCKET_MQUEUE:
2796 return "MessageQueue";
2797
2798 case SOCKET_FIFO:
2799 return "FIFO";
2800
2801 case SOCKET_USB_FUNCTION:
2802 return "USBFunction";
2803
2804 default:
2805 return NULL((void*)0);
2806 }
2807}
2808
2809SocketType socket_port_type_from_string(const char *s) {
2810 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2810, __PRETTY_FUNCTION__
); } while (0)
;
2811
2812 if (STR_IN_SET(s, "Stream", "Datagram", "SequentialPacket", "Netlink")(!!strv_find((((char**) ((const char*[]) { "Stream", "Datagram"
, "SequentialPacket", "Netlink", ((void*)0) }))), (s)))
)
2813 return SOCKET_SOCKET;
2814 else if (streq(s, "Special")(strcmp((s),("Special")) == 0))
2815 return SOCKET_SPECIAL;
2816 else if (streq(s, "MessageQueue")(strcmp((s),("MessageQueue")) == 0))
2817 return SOCKET_MQUEUE;
2818 else if (streq(s, "FIFO")(strcmp((s),("FIFO")) == 0))
2819 return SOCKET_FIFO;
2820 else if (streq(s, "USBFunction")(strcmp((s),("USBFunction")) == 0))
2821 return SOCKET_USB_FUNCTION;
2822 else
2823 return _SOCKET_TYPE_INVALID;
2824}
2825
2826_pure___attribute__ ((pure)) static bool_Bool socket_may_gc(Unit *u) {
2827 Socket *s = SOCKET(u);
2828
2829 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/socket.c", 2829, __PRETTY_FUNCTION__
); } while (0)
;
2830
2831 return s->n_connections == 0;
2832}
2833
2834static int socket_accept_do(Socket *s, int fd) {
2835 int cfd;
2836
2837 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2837, __PRETTY_FUNCTION__
); } while (0)
;
2838 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/core/socket.c", 2838
, __PRETTY_FUNCTION__); } while (0)
;
2839
2840 for (;;) {
2841 cfd = accept4(fd, NULL((void*)0), NULL((void*)0), SOCK_NONBLOCKSOCK_NONBLOCK);
2842 if (cfd < 0) {
2843 if (errno(*__errno_location ()) == EINTR4)
2844 continue;
2845
2846 return -errno(*__errno_location ());
2847 }
2848
2849 break;
2850 }
2851
2852 return cfd;
2853}
2854
2855static int socket_accept_in_cgroup(Socket *s, SocketPort *p, int fd) {
2856 _cleanup_close_pair___attribute__((cleanup(close_pairp))) int pair[2] = { -1, -1 };
2857 int cfd, r;
2858 pid_t pid;
2859
2860 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2860, __PRETTY_FUNCTION__
); } while (0)
;
2861 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/core/socket.c", 2861, __PRETTY_FUNCTION__
); } while (0)
;
2862 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/core/socket.c", 2862
, __PRETTY_FUNCTION__); } while (0)
;
2863
2864 /* Similar to socket_address_listen_in_cgroup(), but for accept() rathern than socket(): make sure that any
2865 * connection socket is also properly associated with the cgroup. */
2866
2867 if (!IN_SET(p->address.sockaddr.sa.sa_family, AF_INET, AF_INET6)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){2, 10})/sizeof(int)]; switch(p->address
.sockaddr.sa.sa_family) { case 2: case 10: _found = 1; break;
default: break; } _found; })
)
2868 goto shortcut;
2869
2870 r = bpf_firewall_supported();
2871 if (r < 0)
2872 return r;
2873 if (r == BPF_FIREWALL_UNSUPPORTED)
2874 goto shortcut;
2875
2876 if (socketpair(AF_UNIX1, SOCK_SEQPACKETSOCK_SEQPACKET|SOCK_CLOEXECSOCK_CLOEXEC, 0, pair) < 0)
2877 return log_unit_error_errno(UNIT(s), errno, "Failed to create communication channel: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, (*__errno_location ()), "../src/core/socket.c", 2877, __func__
, _u->manager->unit_log_field, _u->id, _u->manager
->invocation_log_field, _u->invocation_id_string, "Failed to create communication channel: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), (*__errno_location ()), "../src/core/socket.c", 2877, __func__
, "Failed to create communication channel: %m"); })
;
2878
2879 r = unit_fork_helper_process(UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
, "(sd-accept)", &pid);
2880 if (r < 0)
2881 return log_unit_error_errno(UNIT(s), r, "Failed to fork off accept stub process: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, r, "../src/core/socket.c", 2881, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to fork off accept stub process: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/core/socket.c", 2881, __func__, "Failed to fork off accept stub process: %m"
); })
;
2882 if (r == 0) {
2883 /* Child */
2884
2885 pair[0] = safe_close(pair[0]);
2886
2887 cfd = socket_accept_do(s, fd);
2888 if (cfd < 0) {
2889 log_unit_error_errno(UNIT(s), cfd, "Failed to accept connection socket: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, cfd, "../src/core/socket.c", 2889, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to accept connection socket: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), cfd, "../src/core/socket.c", 2889, __func__, "Failed to accept connection socket: %m"
); })
;
2890 _exit(EXIT_FAILURE1);
2891 }
2892
2893 r = send_one_fd(pair[1], cfd, 0)send_one_fd_iov_sa(pair[1], cfd, ((void*)0), 0, ((void*)0), 0
, 0)
;
2894 if (r < 0) {
2895 log_unit_error_errno(UNIT(s), r, "Failed to send connection socket to parent: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, r, "../src/core/socket.c", 2895, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to send connection socket to parent: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), r, "../src/core/socket.c", 2895, __func__, "Failed to send connection socket to parent: %m"
); })
;
2896 _exit(EXIT_FAILURE1);
2897 }
2898
2899 _exit(EXIT_SUCCESS0);
2900 }
2901
2902 pair[1] = safe_close(pair[1]);
2903 cfd = receive_one_fd(pair[0], 0);
2904
2905 /* We synchronously wait for the helper, as it shouldn't be slow */
2906 r = wait_for_terminate_and_check("(sd-accept)", pid, WAIT_LOG_ABNORMAL);
2907 if (r < 0) {
2908 safe_close(cfd);
2909 return r;
2910 }
2911
2912 if (cfd < 0)
2913 return log_unit_error_errno(UNIT(s), cfd, "Failed to receive connection socket: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, cfd, "../src/core/socket.c", 2913, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to receive connection socket: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), cfd, "../src/core/socket.c", 2913, __func__, "Failed to receive connection socket: %m"
); })
;
2914
2915 return cfd;
2916
2917shortcut:
2918 cfd = socket_accept_do(s, fd);
2919 if (cfd < 0)
2920 return log_unit_error_errno(UNIT(s), cfd, "Failed to accept connection socket: %m")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(3, cfd, "../src/core/socket.c", 2920, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Failed to accept connection socket: %m"
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), cfd, "../src/core/socket.c", 2920, __func__, "Failed to accept connection socket: %m"
); })
;
2921
2922 return cfd;
2923}
2924
2925static int socket_dispatch_io(sd_event_source *source, int fd, uint32_t revents, void *userdata) {
2926 SocketPort *p = userdata;
2927 int cfd = -1;
2928
2929 assert(p)do { if ((__builtin_expect(!!(!(p)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("p"), "../src/core/socket.c", 2929, __PRETTY_FUNCTION__
); } while (0)
;
2930 assert(fd >= 0)do { if ((__builtin_expect(!!(!(fd >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fd >= 0"), "../src/core/socket.c", 2930
, __PRETTY_FUNCTION__); } while (0)
;
2931
2932 if (p->socket->state != SOCKET_LISTENING)
2933 return 0;
2934
2935 log_unit_debug(UNIT(p->socket), "Incoming traffic")({ const Unit *_u = (({ typeof(p->socket) _u_ = (p->socket
); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }
)); _u ? log_object_internal(7, 0, "../src/core/socket.c", 2935
, __func__, _u->manager->unit_log_field, _u->id, _u->
manager->invocation_log_field, _u->invocation_id_string
, "Incoming traffic") : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((7))), 0, "../src/core/socket.c", 2935, __func__
, "Incoming traffic"); })
;
2936
2937 if (revents != EPOLLINEPOLLIN) {
2938
2939 if (revents & EPOLLHUPEPOLLHUP)
2940 log_unit_error(UNIT(p->socket), "Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that.")({ const Unit *_u = (({ typeof(p->socket) _u_ = (p->socket
); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }
)); _u ? log_object_internal(3, 0, "../src/core/socket.c", 2940
, __func__, _u->manager->unit_log_field, _u->id, _u->
manager->invocation_log_field, _u->invocation_id_string
, "Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((3
))), 0, "../src/core/socket.c", 2940, __func__, "Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that."
); })
;
2941 else
2942 log_unit_error(UNIT(p->socket), "Got unexpected poll event (0x%x) on socket.", revents)({ const Unit *_u = (({ typeof(p->socket) _u_ = (p->socket
); Unit *_w_ = _u_ ? &(_u_)->meta : ((void*)0); _w_; }
)); _u ? log_object_internal(3, 0, "../src/core/socket.c", 2942
, __func__, _u->manager->unit_log_field, _u->id, _u->
manager->invocation_log_field, _u->invocation_id_string
, "Got unexpected poll event (0x%x) on socket.", revents) : log_internal_realm
(((LOG_REALM_SYSTEMD) << 10 | ((3))), 0, "../src/core/socket.c"
, 2942, __func__, "Got unexpected poll event (0x%x) on socket."
, revents); })
;
2943 goto fail;
2944 }
2945
2946 if (p->socket->accept &&
2947 p->type == SOCKET_SOCKET &&
2948 socket_address_can_accept(&p->address)) {
2949
2950 cfd = socket_accept_in_cgroup(p->socket, p, fd);
2951 if (cfd < 0)
2952 goto fail;
2953
2954 socket_apply_socket_options(p->socket, cfd);
2955 }
2956
2957 socket_enter_running(p->socket, cfd);
2958 return 0;
2959
2960fail:
2961 socket_enter_stop_pre(p->socket, SOCKET_FAILURE_RESOURCES);
2962 return 0;
2963}
2964
2965static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
2966 Socket *s = SOCKET(u);
2967 SocketResult f;
2968
2969 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 2969, __PRETTY_FUNCTION__
); } while (0)
;
2970 assert(pid >= 0)do { if ((__builtin_expect(!!(!(pid >= 0)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("pid >= 0"), "../src/core/socket.c", 2970
, __PRETTY_FUNCTION__); } while (0)
;
2971
2972 if (pid != s->control_pid)
2973 return;
2974
2975 s->control_pid = 0;
2976
2977 if (is_clean_exit(code, status, EXIT_CLEAN_COMMAND, NULL((void*)0)))
2978 f = SOCKET_SUCCESS;
2979 else if (code == CLD_EXITEDCLD_EXITED)
2980 f = SOCKET_FAILURE_EXIT_CODE;
2981 else if (code == CLD_KILLEDCLD_KILLED)
2982 f = SOCKET_FAILURE_SIGNAL;
2983 else if (code == CLD_DUMPEDCLD_DUMPED)
2984 f = SOCKET_FAILURE_CORE_DUMP;
2985 else
2986 assert_not_reached("Unknown sigchld code")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Unknown sigchld code"), "../src/core/socket.c", 2986, __PRETTY_FUNCTION__
); } while (0)
;
2987
2988 if (s->control_command) {
2989 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
2990
2991 if (s->control_command->flags & EXEC_COMMAND_IGNORE_FAILURE)
2992 f = SOCKET_SUCCESS;
2993 }
2994
2995 log_unit_full(u, f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE, 0,({ const Unit *_u = (u); _u ? log_object_internal(f == SOCKET_SUCCESS
? 7 : 5, 0, "../src/core/socket.c", 2997, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Control process exited, code=%s status=%i"
, sigchld_code_to_string(code), status) : log_internal_realm(
((LOG_REALM_SYSTEMD) << 10 | ((f == SOCKET_SUCCESS ? 7 :
5))), 0, "../src/core/socket.c", 2997, __func__, "Control process exited, code=%s status=%i"
, sigchld_code_to_string(code), status); })
2996 "Control process exited, code=%s status=%i",({ const Unit *_u = (u); _u ? log_object_internal(f == SOCKET_SUCCESS
? 7 : 5, 0, "../src/core/socket.c", 2997, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Control process exited, code=%s status=%i"
, sigchld_code_to_string(code), status) : log_internal_realm(
((LOG_REALM_SYSTEMD) << 10 | ((f == SOCKET_SUCCESS ? 7 :
5))), 0, "../src/core/socket.c", 2997, __func__, "Control process exited, code=%s status=%i"
, sigchld_code_to_string(code), status); })
2997 sigchld_code_to_string(code), status)({ const Unit *_u = (u); _u ? log_object_internal(f == SOCKET_SUCCESS
? 7 : 5, 0, "../src/core/socket.c", 2997, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Control process exited, code=%s status=%i"
, sigchld_code_to_string(code), status) : log_internal_realm(
((LOG_REALM_SYSTEMD) << 10 | ((f == SOCKET_SUCCESS ? 7 :
5))), 0, "../src/core/socket.c", 2997, __func__, "Control process exited, code=%s status=%i"
, sigchld_code_to_string(code), status); })
;
2998
2999 if (s->result == SOCKET_SUCCESS)
3000 s->result = f;
3001
3002 if (s->control_command &&
3003 s->control_command->command_next &&
3004 f == SOCKET_SUCCESS) {
3005
3006 log_unit_debug(u, "Running next command for state %s", socket_state_to_string(s->state))({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 3006, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Running next command for state %s", socket_state_to_string
(s->state)) : log_internal_realm(((LOG_REALM_SYSTEMD) <<
10 | ((7))), 0, "../src/core/socket.c", 3006, __func__, "Running next command for state %s"
, socket_state_to_string(s->state)); })
;
3007 socket_run_next(s);
3008 } else {
3009 s->control_command = NULL((void*)0);
3010 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
3011
3012 /* No further commands for this step, so let's figure
3013 * out what to do next */
3014
3015 log_unit_debug(u, "Got final SIGCHLD for state %s", socket_state_to_string(s->state))({ const Unit *_u = (u); _u ? log_object_internal(7, 0, "../src/core/socket.c"
, 3015, __func__, _u->manager->unit_log_field, _u->id
, _u->manager->invocation_log_field, _u->invocation_id_string
, "Got final SIGCHLD for state %s", socket_state_to_string(s->
state)) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10
| ((7))), 0, "../src/core/socket.c", 3015, __func__, "Got final SIGCHLD for state %s"
, socket_state_to_string(s->state)); })
;
3016
3017 switch (s->state) {
3018
3019 case SOCKET_START_PRE:
3020 if (f == SOCKET_SUCCESS)
3021 socket_enter_start_chown(s);
3022 else
3023 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f);
3024 break;
3025
3026 case SOCKET_START_CHOWN:
3027 if (f == SOCKET_SUCCESS)
3028 socket_enter_start_post(s);
3029 else
3030 socket_enter_stop_pre(s, f);
3031 break;
3032
3033 case SOCKET_START_POST:
3034 if (f == SOCKET_SUCCESS)
3035 socket_enter_listening(s);
3036 else
3037 socket_enter_stop_pre(s, f);
3038 break;
3039
3040 case SOCKET_STOP_PRE:
3041 case SOCKET_STOP_PRE_SIGTERM:
3042 case SOCKET_STOP_PRE_SIGKILL:
3043 socket_enter_stop_post(s, f);
3044 break;
3045
3046 case SOCKET_STOP_POST:
3047 case SOCKET_FINAL_SIGTERM:
3048 case SOCKET_FINAL_SIGKILL:
3049 socket_enter_dead(s, f);
3050 break;
3051
3052 default:
3053 assert_not_reached("Uh, control process died at wrong time.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Uh, control process died at wrong time."), "../src/core/socket.c"
, 3053, __PRETTY_FUNCTION__); } while (0)
;
3054 }
3055 }
3056
3057 /* Notify clients about changed exit status */
3058 unit_add_to_dbus_queue(u);
3059}
3060
3061static int socket_dispatch_timer(sd_event_source *source, usec_t usec, void *userdata) {
3062 Socket *s = SOCKET(userdata);
3063
3064 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 3064, __PRETTY_FUNCTION__
); } while (0)
;
3065 assert(s->timer_event_source == source)do { if ((__builtin_expect(!!(!(s->timer_event_source == source
)),0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->timer_event_source == source"
), "../src/core/socket.c", 3065, __PRETTY_FUNCTION__); } while
(0)
;
3066
3067 switch (s->state) {
3068
3069 case SOCKET_START_PRE:
3070 log_unit_warning(UNIT(s), "Starting timed out. Terminating.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3070, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Starting timed out. Terminating."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3070, __func__, "Starting timed out. Terminating."
); })
;
3071 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
3072 break;
3073
3074 case SOCKET_START_CHOWN:
3075 case SOCKET_START_POST:
3076 log_unit_warning(UNIT(s), "Starting timed out. Stopping.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3076, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Starting timed out. Stopping."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3076, __func__, "Starting timed out. Stopping."
); })
;
3077 socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT);
3078 break;
3079
3080 case SOCKET_STOP_PRE:
3081 log_unit_warning(UNIT(s), "Stopping timed out. Terminating.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3081, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Stopping timed out. Terminating."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3081, __func__, "Stopping timed out. Terminating."
); })
;
3082 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT);
3083 break;
3084
3085 case SOCKET_STOP_PRE_SIGTERM:
3086 if (s->kill_context.send_sigkill) {
3087 log_unit_warning(UNIT(s), "Stopping timed out. Killing.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3087, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Stopping timed out. Killing."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3087, __func__, "Stopping timed out. Killing."
); })
;
3088 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT);
3089 } else {
3090 log_unit_warning(UNIT(s), "Stopping timed out. Skipping SIGKILL. Ignoring.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3090, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Stopping timed out. Skipping SIGKILL. Ignoring."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3090, __func__, "Stopping timed out. Skipping SIGKILL. Ignoring."
); })
;
3091 socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
3092 }
3093 break;
3094
3095 case SOCKET_STOP_PRE_SIGKILL:
3096 log_unit_warning(UNIT(s), "Processes still around after SIGKILL. Ignoring.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3096, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Processes still around after SIGKILL. Ignoring."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3096, __func__, "Processes still around after SIGKILL. Ignoring."
); })
;
3097 socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
3098 break;
3099
3100 case SOCKET_STOP_POST:
3101 log_unit_warning(UNIT(s), "Stopping timed out (2). Terminating.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3101, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Stopping timed out (2). Terminating."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3101, __func__, "Stopping timed out (2). Terminating."
); })
;
3102 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
3103 break;
3104
3105 case SOCKET_FINAL_SIGTERM:
3106 if (s->kill_context.send_sigkill) {
3107 log_unit_warning(UNIT(s), "Stopping timed out (2). Killing.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3107, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Stopping timed out (2). Killing."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3107, __func__, "Stopping timed out (2). Killing."
); })
;
3108 socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT);
3109 } else {
3110 log_unit_warning(UNIT(s), "Stopping timed out (2). Skipping SIGKILL. Ignoring.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3110, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Stopping timed out (2). Skipping SIGKILL. Ignoring."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3110, __func__, "Stopping timed out (2). Skipping SIGKILL. Ignoring."
); })
;
3111 socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
3112 }
3113 break;
3114
3115 case SOCKET_FINAL_SIGKILL:
3116 log_unit_warning(UNIT(s), "Still around after SIGKILL (2). Entering failed mode.")({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(4, 0, "../src/core/socket.c", 3116, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "Still around after SIGKILL (2). Entering failed mode."
) : log_internal_realm(((LOG_REALM_SYSTEMD) << 10 | ((4
))), 0, "../src/core/socket.c", 3116, __func__, "Still around after SIGKILL (2). Entering failed mode."
); })
;
3117 socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
3118 break;
3119
3120 default:
3121 assert_not_reached("Timeout at wrong time.")do { log_assert_failed_unreachable_realm(LOG_REALM_SYSTEMD, (
"Timeout at wrong time."), "../src/core/socket.c", 3121, __PRETTY_FUNCTION__
); } while (0)
;
3122 }
3123
3124 return 0;
3125}
3126
3127int socket_collect_fds(Socket *s, int **fds) {
3128 size_t k = 0, n = 0;
3129 SocketPort *p;
3130 int *rfds;
3131
3132 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 3132, __PRETTY_FUNCTION__
); } while (0)
;
3133 assert(fds)do { if ((__builtin_expect(!!(!(fds)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("fds"), "../src/core/socket.c", 3133, __PRETTY_FUNCTION__
); } while (0)
;
3134
3135 /* Called from the service code for requesting our fds */
3136
3137 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
3138 if (p->fd >= 0)
3139 n++;
3140 n += p->n_auxiliary_fds;
3141 }
3142
3143 if (n <= 0) {
3144 *fds = NULL((void*)0);
3145 return 0;
3146 }
3147
3148 rfds = new(int, n)((int*) malloc_multiply(sizeof(int), (n)));
3149 if (!rfds)
3150 return -ENOMEM12;
3151
3152 LIST_FOREACH(port, p, s->ports)for ((p) = (s->ports); (p); (p) = (p)->port_next) {
3153 size_t i;
3154
3155 if (p->fd >= 0)
3156 rfds[k++] = p->fd;
3157 for (i = 0; i < p->n_auxiliary_fds; ++i)
3158 rfds[k++] = p->auxiliary_fds[i];
3159 }
3160
3161 assert(k == n)do { if ((__builtin_expect(!!(!(k == n)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("k == n"), "../src/core/socket.c", 3161,
__PRETTY_FUNCTION__); } while (0)
;
3162
3163 *fds = rfds;
3164 return (int) n;
3165}
3166
3167static void socket_reset_failed(Unit *u) {
3168 Socket *s = SOCKET(u);
3169
3170 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 3170, __PRETTY_FUNCTION__
); } while (0)
;
3171
3172 if (s->state == SOCKET_FAILED)
3173 socket_set_state(s, SOCKET_DEAD);
3174
3175 s->result = SOCKET_SUCCESS;
3176}
3177
3178void socket_connection_unref(Socket *s) {
3179 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 3179, __PRETTY_FUNCTION__
); } while (0)
;
3180
3181 /* The service is dead. Yay!
3182 *
3183 * This is strictly for one-instance-per-connection
3184 * services. */
3185
3186 assert(s->n_connections > 0)do { if ((__builtin_expect(!!(!(s->n_connections > 0)),
0))) log_assert_failed_realm(LOG_REALM_SYSTEMD, ("s->n_connections > 0"
), "../src/core/socket.c", 3186, __PRETTY_FUNCTION__); } while
(0)
;
3187 s->n_connections--;
3188
3189 log_unit_debug(UNIT(s), "One connection closed, %u left.", s->n_connections)({ const Unit *_u = (({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ?
&(_u_)->meta : ((void*)0); _w_; })); _u ? log_object_internal
(7, 0, "../src/core/socket.c", 3189, __func__, _u->manager
->unit_log_field, _u->id, _u->manager->invocation_log_field
, _u->invocation_id_string, "One connection closed, %u left."
, s->n_connections) : log_internal_realm(((LOG_REALM_SYSTEMD
) << 10 | ((7))), 0, "../src/core/socket.c", 3189, __func__
, "One connection closed, %u left.", s->n_connections); })
;
3190}
3191
3192static void socket_trigger_notify(Unit *u, Unit *other) {
3193 Socket *s = SOCKET(u);
3194
3195 assert(u)do { if ((__builtin_expect(!!(!(u)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("u"), "../src/core/socket.c", 3195, __PRETTY_FUNCTION__
); } while (0)
;
3196 assert(other)do { if ((__builtin_expect(!!(!(other)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("other"), "../src/core/socket.c", 3196, __PRETTY_FUNCTION__
); } while (0)
;
3197
3198 /* Filter out invocations with bogus state */
3199 if (other->load_state != UNIT_LOADED || other->type != UNIT_SERVICE)
3200 return;
3201
3202 /* Don't propagate state changes from the service if we are already down */
3203 if (!IN_SET(s->state, SOCKET_RUNNING, SOCKET_LISTENING)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SOCKET_RUNNING, SOCKET_LISTENING})/sizeof
(int)]; switch(s->state) { case SOCKET_RUNNING: case SOCKET_LISTENING
: _found = 1; break; default: break; } _found; })
)
3204 return;
3205
3206 /* We don't care for the service state if we are in Accept=yes mode */
3207 if (s->accept)
3208 return;
3209
3210 /* Propagate start limit hit state */
3211 if (other->start_limit_hit) {
3212 socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_START_LIMIT_HIT);
3213 return;
3214 }
3215
3216 /* Don't propagate anything if there's still a job queued */
3217 if (other->job)
3218 return;
3219
3220 if (IN_SET(SERVICE(other)->state,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SERVICE_DEAD, SERVICE_FAILED, SERVICE_FINAL_SIGTERM
, SERVICE_FINAL_SIGKILL, SERVICE_AUTO_RESTART})/sizeof(int)];
switch(SERVICE(other)->state) { case SERVICE_DEAD: case SERVICE_FAILED
: case SERVICE_FINAL_SIGTERM: case SERVICE_FINAL_SIGKILL: case
SERVICE_AUTO_RESTART: _found = 1; break; default: break; } _found
; })
3221 SERVICE_DEAD, SERVICE_FAILED,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SERVICE_DEAD, SERVICE_FAILED, SERVICE_FINAL_SIGTERM
, SERVICE_FINAL_SIGKILL, SERVICE_AUTO_RESTART})/sizeof(int)];
switch(SERVICE(other)->state) { case SERVICE_DEAD: case SERVICE_FAILED
: case SERVICE_FINAL_SIGTERM: case SERVICE_FINAL_SIGKILL: case
SERVICE_AUTO_RESTART: _found = 1; break; default: break; } _found
; })
3222 SERVICE_FINAL_SIGTERM, SERVICE_FINAL_SIGKILL,({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SERVICE_DEAD, SERVICE_FAILED, SERVICE_FINAL_SIGTERM
, SERVICE_FINAL_SIGKILL, SERVICE_AUTO_RESTART})/sizeof(int)];
switch(SERVICE(other)->state) { case SERVICE_DEAD: case SERVICE_FAILED
: case SERVICE_FINAL_SIGTERM: case SERVICE_FINAL_SIGKILL: case
SERVICE_AUTO_RESTART: _found = 1; break; default: break; } _found
; })
3223 SERVICE_AUTO_RESTART)({ _Bool _found = 0; static __attribute__ ((unused)) char _static_assert__macros_need_to_be_extended
[20 - sizeof((int[]){SERVICE_DEAD, SERVICE_FAILED, SERVICE_FINAL_SIGTERM
, SERVICE_FINAL_SIGKILL, SERVICE_AUTO_RESTART})/sizeof(int)];
switch(SERVICE(other)->state) { case SERVICE_DEAD: case SERVICE_FAILED
: case SERVICE_FINAL_SIGTERM: case SERVICE_FINAL_SIGKILL: case
SERVICE_AUTO_RESTART: _found = 1; break; default: break; } _found
; })
)
3224 socket_enter_listening(s);
3225
3226 if (SERVICE(other)->state == SERVICE_RUNNING)
3227 socket_set_state(s, SOCKET_RUNNING);
3228}
3229
3230static int socket_kill(Unit *u, KillWho who, int signo, sd_bus_error *error) {
3231 return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
3232}
3233
3234static int socket_get_timeout(Unit *u, usec_t *timeout) {
3235 Socket *s = SOCKET(u);
3236 usec_t t;
3237 int r;
3238
3239 if (!s->timer_event_source)
3240 return 0;
3241
3242 r = sd_event_source_get_time(s->timer_event_source, &t);
3243 if (r < 0)
3244 return r;
3245 if (t == USEC_INFINITY((usec_t) -1))
3246 return 0;
3247
3248 *timeout = t;
3249 return 1;
3250}
3251
3252char *socket_fdname(Socket *s) {
3253 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 3253, __PRETTY_FUNCTION__
); } while (0)
;
3254
3255 /* Returns the name to use for $LISTEN_NAMES. If the user
3256 * didn't specify anything specifically, use the socket unit's
3257 * name as fallback. */
3258
3259 return s->fdname ?: UNIT(s)({ typeof(s) _u_ = (s); Unit *_w_ = _u_ ? &(_u_)->meta
: ((void*)0); _w_; })
->id;
3260}
3261
3262static int socket_control_pid(Unit *u) {
3263 Socket *s = SOCKET(u);
3264
3265 assert(s)do { if ((__builtin_expect(!!(!(s)),0))) log_assert_failed_realm
(LOG_REALM_SYSTEMD, ("s"), "../src/core/socket.c", 3265, __PRETTY_FUNCTION__
); } while (0)
;
3266
3267 return s->control_pid;
3268}
3269
3270static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
3271 [SOCKET_EXEC_START_PRE] = "ExecStartPre",
3272 [SOCKET_EXEC_START_CHOWN] = "ExecStartChown",
3273 [SOCKET_EXEC_START_POST] = "ExecStartPost",
3274 [SOCKET_EXEC_STOP_PRE] = "ExecStopPre",
3275 [SOCKET_EXEC_STOP_POST] = "ExecStopPost"
3276};
3277
3278DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand)const char *socket_exec_command_to_string(SocketExecCommand i
) { if (i < 0 || i >= (SocketExecCommand) __extension__
(__builtin_choose_expr( !__builtin_types_compatible_p(typeof
(socket_exec_command_table), typeof(&*(socket_exec_command_table
))), sizeof(socket_exec_command_table)/sizeof((socket_exec_command_table
)[0]), ((void)0)))) return ((void*)0); return socket_exec_command_table
[i]; } SocketExecCommand socket_exec_command_from_string(const
char *s) { return (SocketExecCommand) string_table_lookup(socket_exec_command_table
, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(socket_exec_command_table), typeof(&*(socket_exec_command_table
))), sizeof(socket_exec_command_table)/sizeof((socket_exec_command_table
)[0]), ((void)0))), s); }
;
3279
3280static const char* const socket_result_table[_SOCKET_RESULT_MAX] = {
3281 [SOCKET_SUCCESS] = "success",
3282 [SOCKET_FAILURE_RESOURCES] = "resources",
3283 [SOCKET_FAILURE_TIMEOUT] = "timeout",
3284 [SOCKET_FAILURE_EXIT_CODE] = "exit-code",
3285 [SOCKET_FAILURE_SIGNAL] = "signal",
3286 [SOCKET_FAILURE_CORE_DUMP] = "core-dump",
3287 [SOCKET_FAILURE_START_LIMIT_HIT] = "start-limit-hit",
3288 [SOCKET_FAILURE_TRIGGER_LIMIT_HIT] = "trigger-limit-hit",
3289 [SOCKET_FAILURE_SERVICE_START_LIMIT_HIT] = "service-start-limit-hit"
3290};
3291
3292DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult)const char *socket_result_to_string(SocketResult i) { if (i <
0 || i >= (SocketResult) __extension__ (__builtin_choose_expr
( !__builtin_types_compatible_p(typeof(socket_result_table), typeof
(&*(socket_result_table))), sizeof(socket_result_table)/sizeof
((socket_result_table)[0]), ((void)0)))) return ((void*)0); return
socket_result_table[i]; } SocketResult socket_result_from_string
(const char *s) { return (SocketResult) string_table_lookup(socket_result_table
, __extension__ (__builtin_choose_expr( !__builtin_types_compatible_p
(typeof(socket_result_table), typeof(&*(socket_result_table
))), sizeof(socket_result_table)/sizeof((socket_result_table)
[0]), ((void)0))), s); }
;
3293
3294const UnitVTable socket_vtable = {
3295 .object_size = sizeof(Socket),
3296 .exec_context_offset = offsetof(Socket, exec_context)__builtin_offsetof(Socket, exec_context),
3297 .cgroup_context_offset = offsetof(Socket, cgroup_context)__builtin_offsetof(Socket, cgroup_context),
3298 .kill_context_offset = offsetof(Socket, kill_context)__builtin_offsetof(Socket, kill_context),
3299 .exec_runtime_offset = offsetof(Socket, exec_runtime)__builtin_offsetof(Socket, exec_runtime),
3300 .dynamic_creds_offset = offsetof(Socket, dynamic_creds)__builtin_offsetof(Socket, dynamic_creds),
3301
3302 .sections =
3303 "Unit\0"
3304 "Socket\0"
3305 "Install\0",
3306 .private_section = "Socket",
3307
3308 .can_transient = true1,
3309
3310 .init = socket_init,
3311 .done = socket_done,
3312 .load = socket_load,
3313
3314 .coldplug = socket_coldplug,
3315
3316 .dump = socket_dump,
3317
3318 .start = socket_start,
3319 .stop = socket_stop,
3320
3321 .kill = socket_kill,
3322
3323 .get_timeout = socket_get_timeout,
3324
3325 .serialize = socket_serialize,
3326 .deserialize_item = socket_deserialize_item,
3327 .distribute_fds = socket_distribute_fds,
3328
3329 .active_state = socket_active_state,
3330 .sub_state_to_string = socket_sub_state_to_string,
3331
3332 .may_gc = socket_may_gc,
3333
3334 .sigchld_event = socket_sigchld_event,
3335
3336 .trigger_notify = socket_trigger_notify,
3337
3338 .reset_failed = socket_reset_failed,
3339
3340 .control_pid = socket_control_pid,
3341
3342 .bus_vtable = bus_socket_vtable,
3343 .bus_set_property = bus_socket_set_property,
3344 .bus_commit_properties = bus_socket_commit_properties,
3345
3346 .status_message_formats = {
3347 /*.starting_stopping = {
3348 [0] = "Starting socket %s...",
3349 [1] = "Stopping socket %s...",
3350 },*/
3351 .finished_start_job = {
3352 [JOB_DONE] = "Listening on %s.",
3353 [JOB_FAILED] = "Failed to listen on %s.",
3354 [JOB_TIMEOUT] = "Timed out starting %s.",
3355 },
3356 .finished_stop_job = {
3357 [JOB_DONE] = "Closed %s.",
3358 [JOB_FAILED] = "Failed stopping %s.",
3359 [JOB_TIMEOUT] = "Timed out stopping %s.",
3360 },
3361 },
3362};