Bug Summary

File:build-scan/../src/core/socket.c
Warning:line 2391, column 9
Potential leak of memory pointed to by 'p'

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)
;
124
125 while ((p = s->ports)) {
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)
;
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);
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)
;
142
143 socket_free_ports(s);
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)));
28
Memory is allocated
543 if (!p)
29
Assuming 'p' is non-null
30
Taking false branch
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)
;
16
Taking false branch
17
Loop condition is false. Exiting loop
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)
;
18
Taking false branch
19
Loop condition is false. Exiting loop
586
587 r = getpeername(fd, &sa.peer.sa, &salen);
588 if (r < 0)
20
Assuming 'r' is >= 0
21
Taking false branch
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; })
) {
22
Control jumps to 'case 40:' at line 591
23
Execution continues on line 591
24
Taking false branch
592 *p = NULL((void*)0);
593 return 0;
594 }
595
596 i = set_get(s->peers_by_address, &sa);
597 if (i) {
25
Assuming 'i' is null
26
Taking false branch
598 *p = socket_peer_ref(i);
599 return 1;
600 }
601
602 remote = socket_peer_new();
27
Calling 'socket_peer_new'
31
Returned allocated memory
603 if (!remote
31.1
'remote' is non-null
)
32
Taking false branch
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)
33
Assuming 'r' is >= 0
34
Taking false branch
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)
;
1
Assuming 's' is non-null
2
Taking false branch
3
Loop condition is false. Exiting loop
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_; })
)
) {
4
'?' condition is true
5
Assuming the condition is false
6
Taking false branch
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)) {
7
Assuming the condition is false
8
Taking false branch
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) {
9
Assuming 'cfd' is >= 0
10
Taking false branch
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) {
11
Assuming field 'n_connections' is < field 'max_connections'
12
Taking false branch
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) {
13
Assuming field 'max_connections_per_source' is > 0
14
Taking true branch
2314 r = socket_acquire_peer(s, cfd, &p);
15
Calling 'socket_acquire_peer'
35
Returned allocated memory via 3rd parameter
2315 if (r
35.1
'r' is >= 0
< 0) {
36
Taking false branch
2316 goto refuse;
2317 } else if (r
36.1
'r' is > 0
> 0 && p->n_ref
36.2
Field 'n_ref' is <= field 'max_connections_per_source'
> s->max_connections_per_source) {
37
Taking false branch
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)
38
Assuming 'r' is < 0
39
Taking true branch
2331 goto fail;
40
Control jumps to line 2391
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)); })
41
Potential leak of memory pointed to by 'p'
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};