]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/socket.c
unit-name: when escaping a path consider the empty path identical to the root dir
[thirdparty/systemd.git] / src / core / socket.c
CommitLineData
d6c9574f 1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
5cb5a6ff 2
a7334b09
LP
3/***
4 This file is part of systemd.
5
6 Copyright 2010 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
a7334b09
LP
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 16 Lesser General Public License for more details.
a7334b09 17
5430f7f2 18 You should have received a copy of the GNU Lesser General Public License
a7334b09
LP
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
83c60c9f
LP
22#include <sys/types.h>
23#include <sys/stat.h>
24#include <unistd.h>
25#include <errno.h>
26#include <fcntl.h>
f94ea366 27#include <sys/epoll.h>
034c6ed7 28#include <signal.h>
4f2d528d 29#include <arpa/inet.h>
916abb21 30#include <mqueue.h>
b00ad20f 31#ifdef HAVE_XATTR
0eb59ccf 32#include <attr/xattr.h>
cf37cd2f 33#endif
83c60c9f 34
87f0e418 35#include "unit.h"
5cb5a6ff 36#include "socket.h"
cebf8b20 37#include "netinet/tcp.h"
83c60c9f 38#include "log.h"
23a177ef
LP
39#include "load-dropin.h"
40#include "load-fragment.h"
9e2f7c11 41#include "strv.h"
49e942b2 42#include "mkdir.h"
9eb977db 43#include "path-util.h"
4f2d528d 44#include "unit-name.h"
41f9172f 45#include "unit-printf.h"
4139c1b2 46#include "dbus-socket.h"
4fd5948e 47#include "missing.h"
a40eb732 48#include "special.h"
449101fc 49#include "dbus-common.h"
e51bc1a2 50#include "label.h"
9a57c629 51#include "exit-status.h"
f6a6225e 52#include "def.h"
83c60c9f 53
acbb0225 54static const UnitActiveState state_translation_table[_SOCKET_STATE_MAX] = {
87f0e418
LP
55 [SOCKET_DEAD] = UNIT_INACTIVE,
56 [SOCKET_START_PRE] = UNIT_ACTIVATING,
57 [SOCKET_START_POST] = UNIT_ACTIVATING,
58 [SOCKET_LISTENING] = UNIT_ACTIVE,
59 [SOCKET_RUNNING] = UNIT_ACTIVE,
60 [SOCKET_STOP_PRE] = UNIT_DEACTIVATING,
61 [SOCKET_STOP_PRE_SIGTERM] = UNIT_DEACTIVATING,
62 [SOCKET_STOP_PRE_SIGKILL] = UNIT_DEACTIVATING,
63 [SOCKET_STOP_POST] = UNIT_DEACTIVATING,
80876c20
LP
64 [SOCKET_FINAL_SIGTERM] = UNIT_DEACTIVATING,
65 [SOCKET_FINAL_SIGKILL] = UNIT_DEACTIVATING,
fdf20a31 66 [SOCKET_FAILED] = UNIT_FAILED
83c60c9f 67};
5cb5a6ff 68
a16e1123
LP
69static void socket_init(Unit *u) {
70 Socket *s = SOCKET(u);
71
72 assert(u);
ac155bb8 73 assert(u->load_state == UNIT_STUB);
a16e1123 74
a16e1123
LP
75 s->backlog = SOMAXCONN;
76 s->timeout_usec = DEFAULT_TIMEOUT_USEC;
77 s->directory_mode = 0755;
9131f660 78 s->socket_mode = 0666;
a16e1123 79
6cf6bbc2
LP
80 s->max_connections = 64;
81
4fd5948e 82 s->priority = -1;
4fd5948e
LP
83 s->ip_tos = -1;
84 s->ip_ttl = -1;
4fd5948e 85 s->mark = -1;
4fd5948e 86
a16e1123 87 exec_context_init(&s->exec_context);
ac155bb8
MS
88 s->exec_context.std_output = u->manager->default_std_output;
89 s->exec_context.std_error = u->manager->default_std_error;
4819ff03 90 kill_context_init(&s->kill_context);
4ad49000 91 cgroup_context_init(&s->cgroup_context);
a16e1123
LP
92
93 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
94}
acbb0225 95
5e94833f
LP
96static void socket_unwatch_control_pid(Socket *s) {
97 assert(s);
98
99 if (s->control_pid <= 0)
100 return;
101
102 unit_unwatch_pid(UNIT(s), s->control_pid);
103 s->control_pid = 0;
104}
105
74051b9b 106void socket_free_ports(Socket *s) {
034c6ed7
LP
107 SocketPort *p;
108
109 assert(s);
110
111 while ((p = s->ports)) {
112 LIST_REMOVE(SocketPort, port, s->ports, p);
113
a16e1123
LP
114 if (p->fd >= 0) {
115 unit_unwatch_fd(UNIT(s), &p->fd_watch);
116 close_nointr_nofail(p->fd);
117 }
118
034c6ed7
LP
119 free(p->path);
120 free(p);
121 }
74051b9b
LP
122}
123
124static void socket_done(Unit *u) {
125 Socket *s = SOCKET(u);
126
127 assert(s);
128
129 socket_free_ports(s);
034c6ed7 130
c17ec25e 131 exec_context_done(&s->exec_context, manager_is_reloading_or_reexecuting(u->manager));
4ad49000
LP
132 cgroup_context_init(&s->cgroup_context);
133
e537352b 134 exec_command_free_array(s->exec_command, _SOCKET_EXEC_COMMAND_MAX);
034c6ed7
LP
135 s->control_command = NULL;
136
5e94833f 137 socket_unwatch_control_pid(s);
034c6ed7 138
57020a3a 139 unit_ref_unset(&s->service);
034c6ed7 140
cebf8b20
TT
141 free(s->tcp_congestion);
142 s->tcp_congestion = NULL;
143
acbb0225 144 free(s->bind_to_device);
e537352b 145 s->bind_to_device = NULL;
acbb0225 146
0eb59ccf
AK
147 free(s->smack);
148 free(s->smack_ip_in);
149 free(s->smack_ip_out);
150
acbb0225 151 unit_unwatch_timer(u, &s->timer_watch);
5cb5a6ff
LP
152}
153
b15bdda8
LP
154static int socket_instantiate_service(Socket *s) {
155 char *prefix, *name;
156 int r;
157 Unit *u;
158
159 assert(s);
160
161 /* This fills in s->service if it isn't filled in yet. For
162 * Accept=yes sockets we create the next connection service
163 * here. For Accept=no this is mostly a NOP since the service
164 * is figured out at load time anyway. */
165
57020a3a 166 if (UNIT_DEREF(s->service))
b15bdda8
LP
167 return 0;
168
169 assert(s->accept);
170
1124fe6f 171 if (!(prefix = unit_name_to_prefix(UNIT(s)->id)))
b15bdda8
LP
172 return -ENOMEM;
173
174 r = asprintf(&name, "%s@%u.service", prefix, s->n_accepted);
175 free(prefix);
176
177 if (r < 0)
178 return -ENOMEM;
179
1124fe6f 180 r = manager_load_unit(UNIT(s)->manager, name, NULL, NULL, &u);
b15bdda8
LP
181 free(name);
182
183 if (r < 0)
184 return r;
185
7b4bf06b 186#ifdef HAVE_SYSV_COMPAT
1b64d026 187 if (SERVICE(u)->is_sysv) {
7b4bf06b
LP
188 log_error("Using SysV services for socket activation is not supported. Refusing.");
189 return -ENOENT;
190 }
191#endif
192
ac155bb8 193 u->no_gc = true;
57020a3a
LP
194 unit_ref_set(&s->service, u);
195
196 return unit_add_two_dependencies(UNIT(s), UNIT_BEFORE, UNIT_TRIGGERS, u, false);
b15bdda8
LP
197}
198
4f2d528d
LP
199static bool have_non_accept_socket(Socket *s) {
200 SocketPort *p;
201
202 assert(s);
203
204 if (!s->accept)
205 return true;
206
dd5ad9d4
LP
207 LIST_FOREACH(port, p, s->ports) {
208
209 if (p->type != SOCKET_SOCKET)
210 return true;
211
4f2d528d
LP
212 if (!socket_address_can_accept(&p->address))
213 return true;
dd5ad9d4 214 }
4f2d528d
LP
215
216 return false;
217}
218
219static int socket_verify(Socket *s) {
220 assert(s);
221
1124fe6f 222 if (UNIT(s)->load_state != UNIT_LOADED)
4f2d528d
LP
223 return 0;
224
225 if (!s->ports) {
66870f90
ZJS
226 log_error_unit(UNIT(s)->id,
227 "%s lacks Listen setting. Refusing.", UNIT(s)->id);
4f2d528d
LP
228 return -EINVAL;
229 }
230
0009d2a6 231 if (s->accept && have_non_accept_socket(s)) {
66870f90
ZJS
232 log_error_unit(UNIT(s)->id,
233 "%s configured for accepting sockets, but sockets are non-accepting. Refusing.",
234 UNIT(s)->id);
0009d2a6
LP
235 return -EINVAL;
236 }
237
6cf6bbc2 238 if (s->accept && s->max_connections <= 0) {
66870f90
ZJS
239 log_error_unit(UNIT(s)->id,
240 "%s's MaxConnection setting too small. Refusing.", UNIT(s)->id);
4d0e5dbd
LP
241 return -EINVAL;
242 }
243
57020a3a 244 if (s->accept && UNIT_DEREF(s->service)) {
66870f90
ZJS
245 log_error_unit(UNIT(s)->id,
246 "Explicit service configuration for accepting sockets not supported on %s. Refusing.",
247 UNIT(s)->id);
d9ff321a
LP
248 return -EINVAL;
249 }
250
4819ff03 251 if (s->exec_context.pam_name && s->kill_context.kill_mode != KILL_CONTROL_GROUP) {
66870f90
ZJS
252 log_error_unit(UNIT(s)->id,
253 "%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.",
254 UNIT(s)->id);
6cf6bbc2
LP
255 return -EINVAL;
256 }
257
4f2d528d
LP
258 return 0;
259}
260
6e2ef85b
LP
261static bool socket_needs_mount(Socket *s, const char *prefix) {
262 SocketPort *p;
263
264 assert(s);
265
266 LIST_FOREACH(port, p, s->ports) {
267
268 if (p->type == SOCKET_SOCKET) {
269 if (socket_address_needs_mount(&p->address, prefix))
270 return true;
916abb21 271 } else if (p->type == SOCKET_FIFO || p->type == SOCKET_SPECIAL) {
6e2ef85b
LP
272 if (path_startswith(p->path, prefix))
273 return true;
274 }
275 }
276
277 return false;
278}
279
280int socket_add_one_mount_link(Socket *s, Mount *m) {
281 int r;
282
283 assert(s);
284 assert(m);
285
1124fe6f
MS
286 if (UNIT(s)->load_state != UNIT_LOADED ||
287 UNIT(m)->load_state != UNIT_LOADED)
6e2ef85b
LP
288 return 0;
289
290 if (!socket_needs_mount(s, m->where))
291 return 0;
292
b87705cd
LP
293 r = unit_add_two_dependencies(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, UNIT(m), true);
294 if (r < 0)
6e2ef85b
LP
295 return r;
296
297 return 0;
298}
299
300static int socket_add_mount_links(Socket *s) {
ac155bb8 301 Unit *other;
6e2ef85b
LP
302 int r;
303
304 assert(s);
305
b87705cd
LP
306 LIST_FOREACH(units_by_type, other, UNIT(s)->manager->units_by_type[UNIT_MOUNT]) {
307 r = socket_add_one_mount_link(s, MOUNT(other));
308 if (r < 0)
6e2ef85b 309 return r;
b87705cd 310 }
6e2ef85b
LP
311
312 return 0;
313}
314
315static int socket_add_device_link(Socket *s) {
316 char *t;
317 int r;
318
319 assert(s);
320
7d0c710d 321 if (!s->bind_to_device || streq(s->bind_to_device, "lo"))
6e2ef85b
LP
322 return 0;
323
324 if (asprintf(&t, "/sys/subsystem/net/devices/%s", s->bind_to_device) < 0)
325 return -ENOMEM;
326
327 r = unit_add_node_link(UNIT(s), t, false);
328 free(t);
329
330 return r;
331}
332
a40eb732
LP
333static int socket_add_default_dependencies(Socket *s) {
334 int r;
335 assert(s);
336
e3d84721
LP
337 r = unit_add_dependency_by_name(UNIT(s), UNIT_BEFORE, SPECIAL_SOCKETS_TARGET, NULL, true);
338 if (r < 0)
339 return r;
2a77d31d 340
e3d84721
LP
341 if (UNIT(s)->manager->running_as == SYSTEMD_SYSTEM) {
342 r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true);
343 if (r < 0)
a40eb732 344 return r;
2a77d31d 345 }
a40eb732 346
ead8e478 347 return unit_add_two_dependencies_by_name(UNIT(s), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true);
a40eb732
LP
348}
349
44a6b1b6 350_pure_ static bool socket_has_exec(Socket *s) {
4cfc6dbe
LP
351 unsigned i;
352 assert(s);
353
354 for (i = 0; i < _SOCKET_EXEC_COMMAND_MAX; i++)
355 if (s->exec_command[i])
356 return true;
357
358 return false;
359}
360
e537352b
LP
361static int socket_load(Unit *u) {
362 Socket *s = SOCKET(u);
363 int r;
44d8db9e 364
e537352b 365 assert(u);
ac155bb8 366 assert(u->load_state == UNIT_STUB);
44d8db9e 367
e537352b 368 if ((r = unit_load_fragment_and_dropin(u)) < 0)
23a177ef 369 return r;
44d8db9e 370
23a177ef 371 /* This is a new unit? Then let's add in some extras */
ac155bb8 372 if (u->load_state == UNIT_LOADED) {
44d8db9e 373
4f2d528d 374 if (have_non_accept_socket(s)) {
d9ff321a 375
57020a3a
LP
376 if (!UNIT_DEREF(s->service)) {
377 Unit *x;
378
379 r = unit_load_related_unit(u, ".service", &x);
380 if (r < 0)
d9ff321a 381 return r;
23a177ef 382
57020a3a
LP
383 unit_ref_set(&s->service, x);
384 }
385
386 r = unit_add_two_dependencies(u, UNIT_BEFORE, UNIT_TRIGGERS, UNIT_DEREF(s->service), true);
387 if (r < 0)
4f2d528d
LP
388 return r;
389 }
44d8db9e 390
6e2ef85b
LP
391 if ((r = socket_add_mount_links(s)) < 0)
392 return r;
393
394 if ((r = socket_add_device_link(s)) < 0)
395 return r;
396
4cfc6dbe
LP
397 if (socket_has_exec(s))
398 if ((r = unit_add_exec_dependencies(u, &s->exec_context)) < 0)
399 return r;
23a177ef 400
a016b922
LP
401 r = unit_add_default_slice(u);
402 if (r < 0)
403 return r;
404
1124fe6f 405 if (UNIT(s)->default_dependencies)
a40eb732
LP
406 if ((r = socket_add_default_dependencies(s)) < 0)
407 return r;
e06c73cc 408
cba6e062 409 r = unit_exec_context_defaults(u, &s->exec_context);
e06c73cc
LP
410 if (r < 0)
411 return r;
23a177ef
LP
412 }
413
4f2d528d 414 return socket_verify(s);
44d8db9e
LP
415}
416
44a6b1b6 417_const_ static const char* listen_lookup(int family, int type) {
7a22745a
LP
418
419 if (family == AF_NETLINK)
420 return "ListenNetlink";
542563ba
LP
421
422 if (type == SOCK_STREAM)
423 return "ListenStream";
424 else if (type == SOCK_DGRAM)
425 return "ListenDatagram";
426 else if (type == SOCK_SEQPACKET)
427 return "ListenSequentialPacket";
428
034c6ed7 429 assert_not_reached("Unknown socket type");
542563ba
LP
430 return NULL;
431}
432
87f0e418 433static void socket_dump(Unit *u, FILE *f, const char *prefix) {
5cb5a6ff 434
5cb5a6ff 435 SocketExecCommand c;
87f0e418 436 Socket *s = SOCKET(u);
542563ba 437 SocketPort *p;
82ba9f08
LP
438 const char *prefix2;
439 char *p2;
5cb5a6ff
LP
440
441 assert(s);
fa068367 442 assert(f);
5cb5a6ff 443
82ba9f08
LP
444 p2 = strappend(prefix, "\t");
445 prefix2 = p2 ? p2 : prefix;
c43d20a0 446
5cb5a6ff
LP
447 fprintf(f,
448 "%sSocket State: %s\n"
81a5c6d0 449 "%sResult: %s\n"
542563ba 450 "%sBindIPv6Only: %s\n"
b5a0699f
LP
451 "%sBacklog: %u\n"
452 "%sSocketMode: %04o\n"
4fd5948e
LP
453 "%sDirectoryMode: %04o\n"
454 "%sKeepAlive: %s\n"
cebf8b20 455 "%sFreeBind: %s\n"
6b6d2dee 456 "%sTransparent: %s\n"
ec6370a2 457 "%sBroadcast: %s\n"
ede3deb4 458 "%sPassCredentials: %s\n"
54ecda32 459 "%sPassSecurity: %s\n"
cebf8b20 460 "%sTCPCongestion: %s\n",
a16e1123 461 prefix, socket_state_to_string(s->state),
81a5c6d0 462 prefix, socket_result_to_string(s->result),
c0120d99 463 prefix, socket_address_bind_ipv6_only_to_string(s->bind_ipv6_only),
b5a0699f
LP
464 prefix, s->backlog,
465 prefix, s->socket_mode,
4fd5948e
LP
466 prefix, s->directory_mode,
467 prefix, yes_no(s->keep_alive),
cebf8b20 468 prefix, yes_no(s->free_bind),
6b6d2dee 469 prefix, yes_no(s->transparent),
ec6370a2 470 prefix, yes_no(s->broadcast),
d68af586 471 prefix, yes_no(s->pass_cred),
54ecda32 472 prefix, yes_no(s->pass_sec),
83a95334 473 prefix, strna(s->tcp_congestion));
542563ba 474
70123e68
LP
475 if (s->control_pid > 0)
476 fprintf(f,
bb00e604
LP
477 "%sControl PID: %lu\n",
478 prefix, (unsigned long) s->control_pid);
70123e68 479
acbb0225
LP
480 if (s->bind_to_device)
481 fprintf(f,
482 "%sBindToDevice: %s\n",
483 prefix, s->bind_to_device);
484
4f2d528d
LP
485 if (s->accept)
486 fprintf(f,
6cf6bbc2
LP
487 "%sAccepted: %u\n"
488 "%sNConnections: %u\n"
489 "%sMaxConnections: %u\n",
490 prefix, s->n_accepted,
491 prefix, s->n_connections,
492 prefix, s->max_connections);
4f2d528d 493
4fd5948e
LP
494 if (s->priority >= 0)
495 fprintf(f,
496 "%sPriority: %i\n",
497 prefix, s->priority);
498
499 if (s->receive_buffer > 0)
500 fprintf(f,
501 "%sReceiveBuffer: %zu\n",
502 prefix, s->receive_buffer);
503
504 if (s->send_buffer > 0)
505 fprintf(f,
506 "%sSendBuffer: %zu\n",
507 prefix, s->send_buffer);
508
509 if (s->ip_tos >= 0)
510 fprintf(f,
511 "%sIPTOS: %i\n",
512 prefix, s->ip_tos);
513
514 if (s->ip_ttl >= 0)
515 fprintf(f,
516 "%sIPTTL: %i\n",
517 prefix, s->ip_ttl);
518
519 if (s->pipe_size > 0)
520 fprintf(f,
521 "%sPipeSize: %zu\n",
522 prefix, s->pipe_size);
523
524 if (s->mark >= 0)
525 fprintf(f,
526 "%sMark: %i\n",
527 prefix, s->mark);
528
916abb21
LP
529 if (s->mq_maxmsg > 0)
530 fprintf(f,
531 "%sMessageQueueMaxMessages: %li\n",
532 prefix, s->mq_maxmsg);
533
534 if (s->mq_msgsize > 0)
535 fprintf(f,
536 "%sMessageQueueMessageSize: %li\n",
537 prefix, s->mq_msgsize);
538
f7db7a69
SL
539 if (s->reuseport)
540 fprintf(f,
541 "%sReusePort: %s\n",
542 prefix, yes_no(s->reuseport));
543
0eb59ccf
AK
544 if (s->smack)
545 fprintf(f,
546 "%sSmackLabel: %s\n",
547 prefix, s->smack);
548
549 if (s->smack_ip_in)
550 fprintf(f,
551 "%sSmackLabelIPIn: %s\n",
552 prefix, s->smack_ip_in);
553
554 if (s->smack_ip_out)
555 fprintf(f,
556 "%sSmackLabelIPOut: %s\n",
557 prefix, s->smack_ip_out);
558
034c6ed7 559 LIST_FOREACH(port, p, s->ports) {
5cb5a6ff 560
542563ba
LP
561 if (p->type == SOCKET_SOCKET) {
562 const char *t;
563 int r;
e364ad06 564 char *k = NULL;
542563ba
LP
565
566 if ((r = socket_address_print(&p->address, &k)) < 0)
567 t = strerror(-r);
568 else
569 t = k;
570
7a22745a 571 fprintf(f, "%s%s: %s\n", prefix, listen_lookup(socket_address_family(&p->address), p->address.type), t);
542563ba 572 free(k);
b0a3f2bc
LP
573 } else if (p->type == SOCKET_SPECIAL)
574 fprintf(f, "%sListenSpecial: %s\n", prefix, p->path);
916abb21
LP
575 else if (p->type == SOCKET_MQUEUE)
576 fprintf(f, "%sListenMessageQueue: %s\n", prefix, p->path);
b0a3f2bc 577 else
542563ba
LP
578 fprintf(f, "%sListenFIFO: %s\n", prefix, p->path);
579 }
5cb5a6ff
LP
580
581 exec_context_dump(&s->exec_context, f, prefix);
4819ff03 582 kill_context_dump(&s->kill_context, f, prefix);
5cb5a6ff 583
e537352b 584 for (c = 0; c < _SOCKET_EXEC_COMMAND_MAX; c++) {
c43d20a0
LP
585 if (!s->exec_command[c])
586 continue;
5cb5a6ff 587
40d50879 588 fprintf(f, "%s-> %s:\n",
a16e1123 589 prefix, socket_exec_command_to_string(c));
c43d20a0
LP
590
591 exec_command_dump_list(s->exec_command[c], f, prefix2);
5cb5a6ff 592 }
c43d20a0 593
82ba9f08 594 free(p2);
5cb5a6ff
LP
595}
596
4f2d528d
LP
597static int instance_from_socket(int fd, unsigned nr, char **instance) {
598 socklen_t l;
599 char *r;
600 union {
601 struct sockaddr sa;
602 struct sockaddr_un un;
603 struct sockaddr_in in;
604 struct sockaddr_in6 in6;
605 struct sockaddr_storage storage;
606 } local, remote;
607
608 assert(fd >= 0);
609 assert(instance);
610
611 l = sizeof(local);
612 if (getsockname(fd, &local.sa, &l) < 0)
613 return -errno;
614
615 l = sizeof(remote);
616 if (getpeername(fd, &remote.sa, &l) < 0)
617 return -errno;
618
619 switch (local.sa.sa_family) {
620
621 case AF_INET: {
622 uint32_t
623 a = ntohl(local.in.sin_addr.s_addr),
624 b = ntohl(remote.in.sin_addr.s_addr);
625
626 if (asprintf(&r,
77b088c2
LP
627 "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
628 nr,
4f2d528d
LP
629 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
630 ntohs(local.in.sin_port),
631 b >> 24, (b >> 16) & 0xFF, (b >> 8) & 0xFF, b & 0xFF,
632 ntohs(remote.in.sin_port)) < 0)
633 return -ENOMEM;
634
635 break;
636 }
637
638 case AF_INET6: {
c65a0b14 639 static const unsigned char ipv4_prefix[] = {
2b061f5a
LP
640 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
641 };
642
643 if (memcmp(&local.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0 &&
644 memcmp(&remote.in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
645 const uint8_t
646 *a = local.in6.sin6_addr.s6_addr+12,
647 *b = remote.in6.sin6_addr.s6_addr+12;
648
649 if (asprintf(&r,
77b088c2
LP
650 "%u-%u.%u.%u.%u:%u-%u.%u.%u.%u:%u",
651 nr,
2b061f5a
LP
652 a[0], a[1], a[2], a[3],
653 ntohs(local.in6.sin6_port),
654 b[0], b[1], b[2], b[3],
655 ntohs(remote.in6.sin6_port)) < 0)
656 return -ENOMEM;
657 } else {
658 char a[INET6_ADDRSTRLEN], b[INET6_ADDRSTRLEN];
659
660 if (asprintf(&r,
77b088c2
LP
661 "%u-%s:%u-%s:%u",
662 nr,
2b061f5a
LP
663 inet_ntop(AF_INET6, &local.in6.sin6_addr, a, sizeof(a)),
664 ntohs(local.in6.sin6_port),
665 inet_ntop(AF_INET6, &remote.in6.sin6_addr, b, sizeof(b)),
666 ntohs(remote.in6.sin6_port)) < 0)
667 return -ENOMEM;
668 }
4f2d528d
LP
669
670 break;
671 }
672
673 case AF_UNIX: {
674 struct ucred ucred;
675
676 l = sizeof(ucred);
677 if (getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &ucred, &l) < 0)
678 return -errno;
679
680 if (asprintf(&r,
bb00e604 681 "%u-%lu-%lu",
4f2d528d 682 nr,
bb00e604
LP
683 (unsigned long) ucred.pid,
684 (unsigned long) ucred.uid) < 0)
4f2d528d
LP
685 return -ENOMEM;
686
687 break;
688 }
689
690 default:
691 assert_not_reached("Unhandled socket type.");
692 }
693
694 *instance = r;
695 return 0;
696}
697
034c6ed7 698static void socket_close_fds(Socket *s) {
83c60c9f
LP
699 SocketPort *p;
700
701 assert(s);
702
034c6ed7 703 LIST_FOREACH(port, p, s->ports) {
83c60c9f
LP
704 if (p->fd < 0)
705 continue;
706
acbb0225 707 unit_unwatch_fd(UNIT(s), &p->fd_watch);
a16e1123
LP
708 close_nointr_nofail(p->fd);
709
710 /* One little note: we should never delete any sockets
711 * in the file system here! After all some other
712 * process we spawned might still have a reference of
713 * this fd and wants to continue to use it. Therefore
714 * we delete sockets in the file system before we
715 * create a new one, not after we stopped using
716 * one! */
9152c765 717
83c60c9f
LP
718 p->fd = -1;
719 }
720}
721
4fd5948e
LP
722static void socket_apply_socket_options(Socket *s, int fd) {
723 assert(s);
724 assert(fd >= 0);
725
726 if (s->keep_alive) {
727 int b = s->keep_alive;
728 if (setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &b, sizeof(b)) < 0)
66870f90 729 log_warning_unit(UNIT(s)->id, "SO_KEEPALIVE failed: %m");
4fd5948e
LP
730 }
731
ec6370a2
LP
732 if (s->broadcast) {
733 int one = 1;
734 if (setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &one, sizeof(one)) < 0)
66870f90 735 log_warning_unit(UNIT(s)->id, "SO_BROADCAST failed: %m");
ec6370a2
LP
736 }
737
d68af586
MS
738 if (s->pass_cred) {
739 int one = 1;
740 if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
66870f90 741 log_warning_unit(UNIT(s)->id, "SO_PASSCRED failed: %m");
d68af586
MS
742 }
743
54ecda32
LP
744 if (s->pass_sec) {
745 int one = 1;
746 if (setsockopt(fd, SOL_SOCKET, SO_PASSSEC, &one, sizeof(one)) < 0)
66870f90 747 log_warning_unit(UNIT(s)->id, "SO_PASSSEC failed: %m");
54ecda32
LP
748 }
749
4fd5948e
LP
750 if (s->priority >= 0)
751 if (setsockopt(fd, SOL_SOCKET, SO_PRIORITY, &s->priority, sizeof(s->priority)) < 0)
66870f90 752 log_warning_unit(UNIT(s)->id, "SO_PRIORITY failed: %m");
4fd5948e
LP
753
754 if (s->receive_buffer > 0) {
755 int value = (int) s->receive_buffer;
7d9eaa84
LP
756
757 /* We first try with SO_RCVBUFFORCE, in case we have the perms for that */
758
b8cef44e 759 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
7d9eaa84 760 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
66870f90 761 log_warning_unit(UNIT(s)->id, "SO_RCVBUF failed: %m");
4fd5948e
LP
762 }
763
764 if (s->send_buffer > 0) {
765 int value = (int) s->send_buffer;
b8cef44e 766 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
7d9eaa84 767 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
66870f90 768 log_warning_unit(UNIT(s)->id, "SO_SNDBUF failed: %m");
4fd5948e
LP
769 }
770
771 if (s->mark >= 0)
772 if (setsockopt(fd, SOL_SOCKET, SO_MARK, &s->mark, sizeof(s->mark)) < 0)
66870f90 773 log_warning_unit(UNIT(s)->id, "SO_MARK failed: %m");
4fd5948e
LP
774
775 if (s->ip_tos >= 0)
776 if (setsockopt(fd, IPPROTO_IP, IP_TOS, &s->ip_tos, sizeof(s->ip_tos)) < 0)
66870f90 777 log_warning_unit(UNIT(s)->id, "IP_TOS failed: %m");
4fd5948e 778
46925ac5
LP
779 if (s->ip_ttl >= 0) {
780 int r, x;
781
782 r = setsockopt(fd, IPPROTO_IP, IP_TTL, &s->ip_ttl, sizeof(s->ip_ttl));
5bfcc1c6
FF
783
784 if (socket_ipv6_is_supported())
785 x = setsockopt(fd, IPPROTO_IPV6, IPV6_UNICAST_HOPS, &s->ip_ttl, sizeof(s->ip_ttl));
786 else {
787 x = -1;
788 errno = EAFNOSUPPORT;
789 }
46925ac5
LP
790
791 if (r < 0 && x < 0)
66870f90
ZJS
792 log_warning_unit(UNIT(s)->id,
793 "IP_TTL/IPV6_UNICAST_HOPS failed: %m");
46925ac5 794 }
cebf8b20
TT
795
796 if (s->tcp_congestion)
797 if (setsockopt(fd, SOL_TCP, TCP_CONGESTION, s->tcp_congestion, strlen(s->tcp_congestion)+1) < 0)
66870f90 798 log_warning_unit(UNIT(s)->id, "TCP_CONGESTION failed: %m");
0eb59ccf 799
f7db7a69
SL
800 if (s->reuseport) {
801 int b = s->reuseport;
802 if (setsockopt(fd, SOL_SOCKET, SO_REUSEPORT, &b, sizeof(b)))
803 log_warning_unit(UNIT(s)->id, "SO_REUSEPORT failed: %m");
804 }
805
2b3e18de 806#ifdef HAVE_SMACK
0eb59ccf
AK
807 if (s->smack_ip_in)
808 if (fsetxattr(fd, "security.SMACK64IPIN", s->smack_ip_in, strlen(s->smack_ip_in), 0) < 0)
66870f90
ZJS
809 log_error_unit(UNIT(s)->id,
810 "fsetxattr(\"security.SMACK64IPIN\"): %m");
0eb59ccf
AK
811
812 if (s->smack_ip_out)
813 if (fsetxattr(fd, "security.SMACK64IPOUT", s->smack_ip_out, strlen(s->smack_ip_out), 0) < 0)
66870f90
ZJS
814 log_error_unit(UNIT(s)->id,
815 "fsetxattr(\"security.SMACK64IPOUT\"): %m");
cf37cd2f 816#endif
4fd5948e
LP
817}
818
b15bdda8 819static void socket_apply_fifo_options(Socket *s, int fd) {
4fd5948e
LP
820 assert(s);
821 assert(fd >= 0);
822
823 if (s->pipe_size > 0)
824 if (fcntl(fd, F_SETPIPE_SZ, s->pipe_size) < 0)
66870f90
ZJS
825 log_warning_unit(UNIT(s)->id,
826 "F_SETPIPE_SZ: %m");
0eb59ccf 827
2b3e18de 828#ifdef HAVE_SMACK
0eb59ccf
AK
829 if (s->smack)
830 if (fsetxattr(fd, "security.SMACK64", s->smack, strlen(s->smack), 0) < 0)
66870f90
ZJS
831 log_error_unit(UNIT(s)->id,
832 "fsetxattr(\"security.SMACK64\"): %m");
cf37cd2f 833#endif
4fd5948e
LP
834}
835
b15bdda8
LP
836static int fifo_address_create(
837 const char *path,
838 mode_t directory_mode,
839 mode_t socket_mode,
b15bdda8
LP
840 int *_fd) {
841
7a58bfa4 842 int fd = -1, r = 0;
b15bdda8
LP
843 struct stat st;
844 mode_t old_mask;
845
846 assert(path);
847 assert(_fd);
848
d2e54fae 849 mkdir_parents_label(path, directory_mode);
b15bdda8 850
e9a5ef7c
KS
851 r = label_context_set(path, S_IFIFO);
852 if (r < 0)
56cf987f 853 goto fail;
b15bdda8
LP
854
855 /* Enforce the right access mode for the fifo */
856 old_mask = umask(~ socket_mode);
857
858 /* Include the original umask in our mask */
859 umask(~socket_mode | old_mask);
860
861 r = mkfifo(path, socket_mode);
862 umask(old_mask);
863
94bc2731 864 if (r < 0 && errno != EEXIST) {
b15bdda8
LP
865 r = -errno;
866 goto fail;
867 }
868
e4f44e73 869 if ((fd = open(path, O_RDWR|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
b15bdda8
LP
870 r = -errno;
871 goto fail;
872 }
873
e9a5ef7c 874 label_context_clear();
7a58bfa4 875
b15bdda8
LP
876 if (fstat(fd, &st) < 0) {
877 r = -errno;
878 goto fail;
879 }
880
881 if (!S_ISFIFO(st.st_mode) ||
de0200fc 882 (st.st_mode & 0777) != (socket_mode & ~old_mask) ||
e4f44e73
DR
883 st.st_uid != getuid() ||
884 st.st_gid != getgid()) {
b15bdda8
LP
885
886 r = -EEXIST;
887 goto fail;
888 }
889
890 *_fd = fd;
891 return 0;
892
893fail:
e9a5ef7c 894 label_context_clear();
56cf987f 895
b15bdda8
LP
896 if (fd >= 0)
897 close_nointr_nofail(fd);
898
899 return r;
900}
901
b0a3f2bc
LP
902static int special_address_create(
903 const char *path,
904 int *_fd) {
905
906 int fd = -1, r = 0;
907 struct stat st;
908
909 assert(path);
910 assert(_fd);
911
912 if ((fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NONBLOCK|O_NOFOLLOW)) < 0) {
913 r = -errno;
914 goto fail;
915 }
916
917 if (fstat(fd, &st) < 0) {
918 r = -errno;
919 goto fail;
920 }
921
922 /* Check whether this is a /proc, /sys or /dev file or char device */
923 if (!S_ISREG(st.st_mode) && !S_ISCHR(st.st_mode)) {
924 r = -EEXIST;
925 goto fail;
926 }
927
928 *_fd = fd;
929 return 0;
930
931fail:
932 if (fd >= 0)
933 close_nointr_nofail(fd);
934
935 return r;
936}
937
916abb21
LP
938static int mq_address_create(
939 const char *path,
940 mode_t mq_mode,
941 long maxmsg,
942 long msgsize,
943 int *_fd) {
944
945 int fd = -1, r = 0;
946 struct stat st;
947 mode_t old_mask;
948 struct mq_attr _attr, *attr = NULL;
949
950 assert(path);
951 assert(_fd);
952
953 if (maxmsg > 0 && msgsize > 0) {
954 zero(_attr);
955 _attr.mq_flags = O_NONBLOCK;
956 _attr.mq_maxmsg = maxmsg;
957 _attr.mq_msgsize = msgsize;
958 attr = &_attr;
959 }
960
961 /* Enforce the right access mode for the mq */
962 old_mask = umask(~ mq_mode);
963
964 /* Include the original umask in our mask */
965 umask(~mq_mode | old_mask);
966
967 fd = mq_open(path, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_CREAT, mq_mode, attr);
968 umask(old_mask);
969
8ea913b2 970 if (fd < 0) {
916abb21
LP
971 r = -errno;
972 goto fail;
973 }
974
975 if (fstat(fd, &st) < 0) {
976 r = -errno;
977 goto fail;
978 }
979
980 if ((st.st_mode & 0777) != (mq_mode & ~old_mask) ||
981 st.st_uid != getuid() ||
982 st.st_gid != getgid()) {
983
984 r = -EEXIST;
985 goto fail;
986 }
987
988 *_fd = fd;
989 return 0;
990
991fail:
992 if (fd >= 0)
993 close_nointr_nofail(fd);
994
995 return r;
996}
997
034c6ed7 998static int socket_open_fds(Socket *s) {
83c60c9f
LP
999 SocketPort *p;
1000 int r;
56cf987f 1001 char *label = NULL;
049f8642 1002 bool know_label = false;
83c60c9f
LP
1003
1004 assert(s);
1005
034c6ed7 1006 LIST_FOREACH(port, p, s->ports) {
83c60c9f 1007
034c6ed7
LP
1008 if (p->fd >= 0)
1009 continue;
83c60c9f
LP
1010
1011 if (p->type == SOCKET_SOCKET) {
1012
049f8642
LP
1013 if (!know_label) {
1014
1015 if ((r = socket_instantiate_service(s)) < 0)
1016 return r;
1017
9444b1f2 1018 if (UNIT_ISSET(s->service) &&
57020a3a
LP
1019 SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]) {
1020 r = label_get_create_label_from_exe(SERVICE(UNIT_DEREF(s->service))->exec_command[SERVICE_EXEC_START]->path, &label);
189583d7
LP
1021
1022 if (r < 0) {
a7444eda
LP
1023 if (r != -EPERM)
1024 return r;
1025 }
189583d7 1026 }
049f8642
LP
1027
1028 know_label = true;
1029 }
1030
b5a0699f
LP
1031 if ((r = socket_address_listen(
1032 &p->address,
1033 s->backlog,
1034 s->bind_ipv6_only,
1035 s->bind_to_device,
4fd5948e 1036 s->free_bind,
6b6d2dee 1037 s->transparent,
b5a0699f
LP
1038 s->directory_mode,
1039 s->socket_mode,
56cf987f 1040 label,
b5a0699f 1041 &p->fd)) < 0)
83c60c9f
LP
1042 goto rollback;
1043
4fd5948e
LP
1044 socket_apply_socket_options(s, p->fd);
1045
b0a3f2bc
LP
1046 } else if (p->type == SOCKET_SPECIAL) {
1047
1048 if ((r = special_address_create(
1049 p->path,
1050 &p->fd)) < 0)
1051 goto rollback;
1052
b15bdda8 1053 } else if (p->type == SOCKET_FIFO) {
83c60c9f 1054
b15bdda8
LP
1055 if ((r = fifo_address_create(
1056 p->path,
1057 s->directory_mode,
1058 s->socket_mode,
b15bdda8 1059 &p->fd)) < 0)
83c60c9f 1060 goto rollback;
83c60c9f 1061
b15bdda8 1062 socket_apply_fifo_options(s, p->fd);
916abb21 1063 } else if (p->type == SOCKET_MQUEUE) {
83c60c9f 1064
916abb21
LP
1065 if ((r = mq_address_create(
1066 p->path,
1067 s->socket_mode,
1068 s->mq_maxmsg,
1069 s->mq_msgsize,
1070 &p->fd)) < 0)
1071 goto rollback;
b15bdda8
LP
1072 } else
1073 assert_not_reached("Unknown port type");
034c6ed7
LP
1074 }
1075
56cf987f 1076 label_free(label);
034c6ed7
LP
1077 return 0;
1078
1079rollback:
1080 socket_close_fds(s);
56cf987f 1081 label_free(label);
034c6ed7
LP
1082 return r;
1083}
1084
1085static void socket_unwatch_fds(Socket *s) {
1086 SocketPort *p;
9152c765 1087
034c6ed7
LP
1088 assert(s);
1089
1090 LIST_FOREACH(port, p, s->ports) {
1091 if (p->fd < 0)
1092 continue;
1093
acbb0225 1094 unit_unwatch_fd(UNIT(s), &p->fd_watch);
83c60c9f 1095 }
034c6ed7
LP
1096}
1097
1098static int socket_watch_fds(Socket *s) {
1099 SocketPort *p;
1100 int r;
1101
1102 assert(s);
83c60c9f 1103
034c6ed7
LP
1104 LIST_FOREACH(port, p, s->ports) {
1105 if (p->fd < 0)
1106 continue;
1107
cabab516 1108 p->fd_watch.socket_accept =
4f2d528d 1109 s->accept &&
dd5ad9d4 1110 p->type == SOCKET_SOCKET &&
4f2d528d
LP
1111 socket_address_can_accept(&p->address);
1112
f94ea366 1113 if ((r = unit_watch_fd(UNIT(s), p->fd, EPOLLIN, &p->fd_watch)) < 0)
034c6ed7
LP
1114 goto fail;
1115 }
83c60c9f 1116
542563ba 1117 return 0;
83c60c9f 1118
034c6ed7
LP
1119fail:
1120 socket_unwatch_fds(s);
1121 return r;
1122}
1123
1124static void socket_set_state(Socket *s, SocketState state) {
1125 SocketState old_state;
1126 assert(s);
1127
1128 old_state = s->state;
1129 s->state = state;
1130
1131 if (state != SOCKET_START_PRE &&
1132 state != SOCKET_START_POST &&
1133 state != SOCKET_STOP_PRE &&
1134 state != SOCKET_STOP_PRE_SIGTERM &&
1135 state != SOCKET_STOP_PRE_SIGKILL &&
1136 state != SOCKET_STOP_POST &&
80876c20
LP
1137 state != SOCKET_FINAL_SIGTERM &&
1138 state != SOCKET_FINAL_SIGKILL) {
acbb0225 1139 unit_unwatch_timer(UNIT(s), &s->timer_watch);
5e94833f 1140 socket_unwatch_control_pid(s);
034c6ed7 1141 s->control_command = NULL;
a16e1123 1142 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
e537352b 1143 }
034c6ed7 1144
a16e1123
LP
1145 if (state != SOCKET_LISTENING)
1146 socket_unwatch_fds(s);
1147
034c6ed7
LP
1148 if (state != SOCKET_START_POST &&
1149 state != SOCKET_LISTENING &&
1150 state != SOCKET_RUNNING &&
1151 state != SOCKET_STOP_PRE &&
1152 state != SOCKET_STOP_PRE_SIGTERM &&
1153 state != SOCKET_STOP_PRE_SIGKILL)
1154 socket_close_fds(s);
1155
e537352b 1156 if (state != old_state)
66870f90
ZJS
1157 log_debug_unit(UNIT(s)->id,
1158 "%s changed %s -> %s", UNIT(s)->id,
1159 socket_state_to_string(old_state),
1160 socket_state_to_string(state));
acbb0225 1161
e2f3b44c 1162 unit_notify(UNIT(s), state_translation_table[old_state], state_translation_table[state], true);
034c6ed7
LP
1163}
1164
a16e1123
LP
1165static int socket_coldplug(Unit *u) {
1166 Socket *s = SOCKET(u);
1167 int r;
1168
1169 assert(s);
1170 assert(s->state == SOCKET_DEAD);
1171
1172 if (s->deserialized_state != s->state) {
1173
1174 if (s->deserialized_state == SOCKET_START_PRE ||
1175 s->deserialized_state == SOCKET_START_POST ||
1176 s->deserialized_state == SOCKET_STOP_PRE ||
1177 s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
1178 s->deserialized_state == SOCKET_STOP_PRE_SIGKILL ||
1179 s->deserialized_state == SOCKET_STOP_POST ||
1180 s->deserialized_state == SOCKET_FINAL_SIGTERM ||
1181 s->deserialized_state == SOCKET_FINAL_SIGKILL) {
1182
1183 if (s->control_pid <= 0)
1184 return -EBADMSG;
1185
36697dc0
LP
1186 r = unit_watch_pid(UNIT(s), s->control_pid);
1187 if (r < 0)
a16e1123
LP
1188 return r;
1189
36697dc0
LP
1190 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
1191 if (r < 0)
a16e1123
LP
1192 return r;
1193 }
1194
1195 if (s->deserialized_state == SOCKET_START_POST ||
1196 s->deserialized_state == SOCKET_LISTENING ||
1197 s->deserialized_state == SOCKET_RUNNING ||
1198 s->deserialized_state == SOCKET_STOP_PRE ||
1199 s->deserialized_state == SOCKET_STOP_PRE_SIGTERM ||
1200 s->deserialized_state == SOCKET_STOP_PRE_SIGKILL)
1201 if ((r = socket_open_fds(s)) < 0)
1202 return r;
1203
1204 if (s->deserialized_state == SOCKET_LISTENING)
1205 if ((r = socket_watch_fds(s)) < 0)
1206 return r;
1207
1208 socket_set_state(s, s->deserialized_state);
1209 }
1210
1211 return 0;
1212}
1213
e537352b 1214static int socket_spawn(Socket *s, ExecCommand *c, pid_t *_pid) {
034c6ed7
LP
1215 pid_t pid;
1216 int r;
9e2f7c11 1217 char **argv;
034c6ed7
LP
1218
1219 assert(s);
1220 assert(c);
1221 assert(_pid);
1222
4ad49000
LP
1223 unit_realize_cgroup(UNIT(s));
1224
36697dc0
LP
1225 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
1226 if (r < 0)
e537352b 1227 goto fail;
034c6ed7 1228
19f6d710
LP
1229 r = unit_full_printf_strv(UNIT(s), c->argv, &argv);
1230 if (r < 0)
9e2f7c11 1231 goto fail;
9e2f7c11
LP
1232
1233 r = exec_spawn(c,
1234 argv,
1235 &s->exec_context,
1236 NULL, 0,
1124fe6f 1237 UNIT(s)->manager->environment,
9e2f7c11
LP
1238 true,
1239 true,
1e3ad081 1240 true,
1124fe6f 1241 UNIT(s)->manager->confirm_spawn,
13b84ec7 1242 UNIT(s)->manager->cgroup_supported,
4ad49000 1243 UNIT(s)->cgroup_path,
62bca2c6 1244 UNIT(s)->id,
f2b68789 1245 NULL,
9e2f7c11
LP
1246 &pid);
1247
1248 strv_free(argv);
1249 if (r < 0)
034c6ed7
LP
1250 goto fail;
1251
87f0e418 1252 if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
034c6ed7
LP
1253 /* FIXME: we need to do something here */
1254 goto fail;
83c60c9f 1255
034c6ed7
LP
1256 *_pid = pid;
1257
1258 return 0;
1259
1260fail:
e537352b 1261 unit_unwatch_timer(UNIT(s), &s->timer_watch);
83c60c9f
LP
1262
1263 return r;
542563ba
LP
1264}
1265
cfc4eb4c 1266static void socket_enter_dead(Socket *s, SocketResult f) {
034c6ed7
LP
1267 assert(s);
1268
cfc4eb4c
LP
1269 if (f != SOCKET_SUCCESS)
1270 s->result = f;
034c6ed7 1271
c17ec25e 1272 exec_context_tmp_dirs_done(&s->exec_context);
cfc4eb4c 1273 socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD);
034c6ed7
LP
1274}
1275
cfc4eb4c 1276static void socket_enter_signal(Socket *s, SocketState state, SocketResult f);
80876c20 1277
cfc4eb4c 1278static void socket_enter_stop_post(Socket *s, SocketResult f) {
034c6ed7
LP
1279 int r;
1280 assert(s);
1281
cfc4eb4c
LP
1282 if (f != SOCKET_SUCCESS)
1283 s->result = f;
034c6ed7 1284
5e94833f
LP
1285 socket_unwatch_control_pid(s);
1286
a16e1123
LP
1287 s->control_command_id = SOCKET_EXEC_STOP_POST;
1288
80876c20 1289 if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) {
e537352b 1290 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1291 goto fail;
1292
80876c20
LP
1293 socket_set_state(s, SOCKET_STOP_POST);
1294 } else
cfc4eb4c 1295 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS);
034c6ed7
LP
1296
1297 return;
1298
1299fail:
66870f90
ZJS
1300 log_warning_unit(UNIT(s)->id,
1301 "%s failed to run 'stop-post' task: %s",
1302 UNIT(s)->id, strerror(-r));
cfc4eb4c 1303 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1304}
1305
cfc4eb4c 1306static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) {
034c6ed7
LP
1307 int r;
1308
1309 assert(s);
1310
cfc4eb4c
LP
1311 if (f != SOCKET_SUCCESS)
1312 s->result = f;
034c6ed7 1313
cd2086fe
LP
1314 r = unit_kill_context(
1315 UNIT(s),
1316 &s->kill_context,
1317 state != SOCKET_STOP_PRE_SIGTERM && state != SOCKET_FINAL_SIGTERM,
1318 -1,
1319 s->control_pid,
1320 false);
1321 if (r < 0)
1322 goto fail;
034c6ed7 1323
cd2086fe 1324 if (r > 0) {
36697dc0
LP
1325 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
1326 if (r < 0)
80876c20 1327 goto fail;
d6ea93e3 1328
80876c20
LP
1329 socket_set_state(s, state);
1330 } else if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
cfc4eb4c 1331 socket_enter_stop_post(s, SOCKET_SUCCESS);
80876c20 1332 else
cfc4eb4c 1333 socket_enter_dead(s, SOCKET_SUCCESS);
034c6ed7
LP
1334
1335 return;
1336
1337fail:
66870f90
ZJS
1338 log_warning_unit(UNIT(s)->id,
1339 "%s failed to kill processes: %s",
1340 UNIT(s)->id, strerror(-r));
034c6ed7
LP
1341
1342 if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
cfc4eb4c 1343 socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
034c6ed7 1344 else
cfc4eb4c 1345 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1346}
1347
cfc4eb4c 1348static void socket_enter_stop_pre(Socket *s, SocketResult f) {
034c6ed7
LP
1349 int r;
1350 assert(s);
1351
cfc4eb4c
LP
1352 if (f != SOCKET_SUCCESS)
1353 s->result = f;
034c6ed7 1354
5e94833f
LP
1355 socket_unwatch_control_pid(s);
1356
a16e1123
LP
1357 s->control_command_id = SOCKET_EXEC_STOP_PRE;
1358
80876c20 1359 if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) {
e537352b 1360 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1361 goto fail;
1362
80876c20
LP
1363 socket_set_state(s, SOCKET_STOP_PRE);
1364 } else
cfc4eb4c 1365 socket_enter_stop_post(s, SOCKET_SUCCESS);
034c6ed7
LP
1366
1367 return;
1368
1369fail:
66870f90
ZJS
1370 log_warning_unit(UNIT(s)->id,
1371 "%s failed to run 'stop-pre' task: %s",
1372 UNIT(s)->id, strerror(-r));
cfc4eb4c 1373 socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1374}
1375
e9af15c3
LP
1376static void socket_enter_listening(Socket *s) {
1377 int r;
1378 assert(s);
1379
cfc4eb4c
LP
1380 r = socket_watch_fds(s);
1381 if (r < 0) {
66870f90
ZJS
1382 log_warning_unit(UNIT(s)->id,
1383 "%s failed to watch sockets: %s",
1384 UNIT(s)->id, strerror(-r));
e9af15c3
LP
1385 goto fail;
1386 }
1387
1388 socket_set_state(s, SOCKET_LISTENING);
1389 return;
1390
1391fail:
cfc4eb4c 1392 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
e9af15c3
LP
1393}
1394
034c6ed7
LP
1395static void socket_enter_start_post(Socket *s) {
1396 int r;
1397 assert(s);
1398
cfc4eb4c
LP
1399 r = socket_open_fds(s);
1400 if (r < 0) {
66870f90
ZJS
1401 log_warning_unit(UNIT(s)->id,
1402 "%s failed to listen on sockets: %s",
1403 UNIT(s)->id, strerror(-r));
034c6ed7
LP
1404 goto fail;
1405 }
1406
5e94833f
LP
1407 socket_unwatch_control_pid(s);
1408
a16e1123
LP
1409 s->control_command_id = SOCKET_EXEC_START_POST;
1410
80876c20 1411 if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
cfc4eb4c
LP
1412 r = socket_spawn(s, s->control_command, &s->control_pid);
1413 if (r < 0) {
66870f90
ZJS
1414 log_warning_unit(UNIT(s)->id,
1415 "%s failed to run 'start-post' task: %s",
1416 UNIT(s)->id, strerror(-r));
034c6ed7
LP
1417 goto fail;
1418 }
1419
80876c20
LP
1420 socket_set_state(s, SOCKET_START_POST);
1421 } else
e9af15c3 1422 socket_enter_listening(s);
034c6ed7
LP
1423
1424 return;
1425
1426fail:
cfc4eb4c 1427 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1428}
1429
1430static void socket_enter_start_pre(Socket *s) {
1431 int r;
1432 assert(s);
1433
5e94833f
LP
1434 socket_unwatch_control_pid(s);
1435
a16e1123
LP
1436 s->control_command_id = SOCKET_EXEC_START_PRE;
1437
80876c20 1438 if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) {
e537352b 1439 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1440 goto fail;
1441
80876c20
LP
1442 socket_set_state(s, SOCKET_START_PRE);
1443 } else
034c6ed7
LP
1444 socket_enter_start_post(s);
1445
1446 return;
1447
1448fail:
66870f90
ZJS
1449 log_warning_unit(UNIT(s)->id,
1450 "%s failed to run 'start-pre' task: %s",
1451 UNIT(s)->id, strerror(-r));
cfc4eb4c 1452 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1453}
1454
4f2d528d 1455static void socket_enter_running(Socket *s, int cfd) {
034c6ed7 1456 int r;
398ef8ba 1457 DBusError error;
034c6ed7
LP
1458
1459 assert(s);
398ef8ba 1460 dbus_error_init(&error);
034c6ed7 1461
ba3e67a7
LP
1462 /* We don't take connections anymore if we are supposed to
1463 * shut down anyway */
31afa0a4 1464 if (unit_stop_pending(UNIT(s))) {
66870f90
ZJS
1465 log_debug_unit(UNIT(s)->id,
1466 "Suppressing connection request on %s since unit stop is scheduled.",
1467 UNIT(s)->id);
5d909e3e 1468
7c610628
LP
1469 if (cfd >= 0)
1470 close_nointr_nofail(cfd);
1471 else {
1472 /* Flush all sockets by closing and reopening them */
1473 socket_close_fds(s);
1474
1a710b43
MS
1475 r = socket_watch_fds(s);
1476 if (r < 0) {
66870f90
ZJS
1477 log_warning_unit(UNIT(s)->id,
1478 "%s failed to watch sockets: %s",
1479 UNIT(s)->id, strerror(-r));
cfc4eb4c 1480 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
7c610628
LP
1481 }
1482 }
1483
ba3e67a7
LP
1484 return;
1485 }
1486
4f2d528d 1487 if (cfd < 0) {
57020a3a
LP
1488 Iterator i;
1489 Unit *u;
f976f3f6 1490 bool pending = false;
f976f3f6
LP
1491
1492 /* If there's already a start pending don't bother to
1493 * do anything */
1124fe6f 1494 SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERS], i)
31afa0a4 1495 if (unit_active_or_pending(u)) {
57020a3a
LP
1496 pending = true;
1497 break;
1498 }
f976f3f6 1499
1a710b43
MS
1500 if (!pending) {
1501 r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL);
1502 if (r < 0)
f976f3f6 1503 goto fail;
1a710b43 1504 }
4f2d528d
LP
1505
1506 socket_set_state(s, SOCKET_RUNNING);
1507 } else {
b4f10a5e 1508 char *prefix, *instance = NULL, *name;
b15bdda8 1509 Service *service;
4f2d528d 1510
6cf6bbc2 1511 if (s->n_connections >= s->max_connections) {
66870f90
ZJS
1512 log_warning_unit(UNIT(s)->id,
1513 "%s: Too many incoming connections (%u)",
1514 UNIT(s)->id, s->n_connections);
6cf6bbc2
LP
1515 close_nointr_nofail(cfd);
1516 return;
1517 }
1518
1a710b43
MS
1519 r = socket_instantiate_service(s);
1520 if (r < 0)
b15bdda8
LP
1521 goto fail;
1522
1a710b43
MS
1523 r = instance_from_socket(cfd, s->n_accepted, &instance);
1524 if (r < 0) {
1525 if (r != -ENOTCONN)
1526 goto fail;
1527
1528 /* ENOTCONN is legitimate if TCP RST was received.
1529 * This connection is over, but the socket unit lives on. */
1530 close_nointr_nofail(cfd);
1531 return;
1532 }
4f2d528d 1533
1a710b43
MS
1534 prefix = unit_name_to_prefix(UNIT(s)->id);
1535 if (!prefix) {
4f2d528d
LP
1536 free(instance);
1537 r = -ENOMEM;
1538 goto fail;
1539 }
1540
1541 name = unit_name_build(prefix, instance, ".service");
1542 free(prefix);
1543 free(instance);
1544
b6dbbe1c 1545 if (!name) {
4f2d528d 1546 r = -ENOMEM;
b6dbbe1c
LP
1547 goto fail;
1548 }
4f2d528d 1549
1a710b43
MS
1550 r = unit_add_name(UNIT_DEREF(s->service), name);
1551 if (r < 0) {
b15bdda8 1552 free(name);
4f2d528d 1553 goto fail;
b15bdda8
LP
1554 }
1555
57020a3a
LP
1556 service = SERVICE(UNIT_DEREF(s->service));
1557 unit_ref_unset(&s->service);
b15bdda8 1558 s->n_accepted ++;
4f2d528d 1559
1124fe6f 1560 UNIT(service)->no_gc = false;
6c073082 1561
b15bdda8
LP
1562 unit_choose_id(UNIT(service), name);
1563 free(name);
1564
1a710b43
MS
1565 r = service_set_socket_fd(service, cfd, s);
1566 if (r < 0)
4f2d528d
LP
1567 goto fail;
1568
1569 cfd = -1;
6cf6bbc2
LP
1570 s->n_connections ++;
1571
1a710b43
MS
1572 r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL);
1573 if (r < 0)
4f2d528d 1574 goto fail;
c4e2ceae
LP
1575
1576 /* Notify clients about changed counters */
1577 unit_add_to_dbus_queue(UNIT(s));
4f2d528d 1578 }
034c6ed7 1579
034c6ed7
LP
1580 return;
1581
1582fail:
66870f90
ZJS
1583 log_warning_unit(UNIT(s)->id,
1584 "%s failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",
1585 UNIT(s)->id,
1586 cfd >= 0 ? "template" : "non-template",
1587 bus_error(&error, r));
60089004 1588 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
4f2d528d
LP
1589
1590 if (cfd >= 0)
1591 close_nointr_nofail(cfd);
398ef8ba
LP
1592
1593 dbus_error_free(&error);
034c6ed7
LP
1594}
1595
cfc4eb4c 1596static void socket_run_next(Socket *s) {
034c6ed7
LP
1597 int r;
1598
1599 assert(s);
1600 assert(s->control_command);
1601 assert(s->control_command->command_next);
1602
5e94833f
LP
1603 socket_unwatch_control_pid(s);
1604
034c6ed7
LP
1605 s->control_command = s->control_command->command_next;
1606
e537352b 1607 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1608 goto fail;
1609
1610 return;
1611
1612fail:
66870f90
ZJS
1613 log_warning_unit(UNIT(s)->id,
1614 "%s failed to run next task: %s",
1615 UNIT(s)->id, strerror(-r));
80876c20
LP
1616
1617 if (s->state == SOCKET_START_POST)
cfc4eb4c 1618 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
034c6ed7 1619 else if (s->state == SOCKET_STOP_POST)
cfc4eb4c 1620 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
034c6ed7 1621 else
cfc4eb4c 1622 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1623}
1624
87f0e418
LP
1625static int socket_start(Unit *u) {
1626 Socket *s = SOCKET(u);
83c60c9f
LP
1627
1628 assert(s);
1629
034c6ed7
LP
1630 /* We cannot fulfill this request right now, try again later
1631 * please! */
1632 if (s->state == SOCKET_STOP_PRE ||
1633 s->state == SOCKET_STOP_PRE_SIGKILL ||
1634 s->state == SOCKET_STOP_PRE_SIGTERM ||
1635 s->state == SOCKET_STOP_POST ||
80876c20
LP
1636 s->state == SOCKET_FINAL_SIGTERM ||
1637 s->state == SOCKET_FINAL_SIGKILL)
034c6ed7
LP
1638 return -EAGAIN;
1639
83c60c9f
LP
1640 if (s->state == SOCKET_START_PRE ||
1641 s->state == SOCKET_START_POST)
034c6ed7 1642 return 0;
83c60c9f 1643
034c6ed7 1644 /* Cannot run this without the service being around */
9444b1f2 1645 if (UNIT_ISSET(s->service)) {
57020a3a
LP
1646 Service *service;
1647
1648 service = SERVICE(UNIT_DEREF(s->service));
1649
1124fe6f 1650 if (UNIT(service)->load_state != UNIT_LOADED) {
d7607eac 1651 log_error_unit(u->id,
66870f90
ZJS
1652 "Socket service %s not loaded, refusing.",
1653 UNIT(service)->id);
4f2d528d 1654 return -ENOENT;
4ac9236f 1655 }
4f2d528d 1656
35b8ca3a 1657 /* If the service is already active we cannot start the
4f2d528d 1658 * socket */
57020a3a
LP
1659 if (service->state != SERVICE_DEAD &&
1660 service->state != SERVICE_FAILED &&
1661 service->state != SERVICE_AUTO_RESTART) {
d7607eac 1662 log_error_unit(u->id,
66870f90
ZJS
1663 "Socket service %s already active, refusing.",
1664 UNIT(service)->id);
4f2d528d 1665 return -EBUSY;
4ac9236f 1666 }
7b4bf06b
LP
1667
1668#ifdef HAVE_SYSV_COMPAT
1b64d026 1669 if (service->is_sysv) {
d7607eac 1670 log_error_unit(u->id,
66870f90 1671 "Using SysV services for socket activation is not supported. Refusing.");
7b4bf06b
LP
1672 return -ENOENT;
1673 }
1674#endif
4f2d528d 1675 }
e537352b 1676
fdf20a31 1677 assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED);
83c60c9f 1678
cfc4eb4c 1679 s->result = SOCKET_SUCCESS;
034c6ed7
LP
1680 socket_enter_start_pre(s);
1681 return 0;
1682}
83c60c9f 1683
87f0e418
LP
1684static int socket_stop(Unit *u) {
1685 Socket *s = SOCKET(u);
034c6ed7
LP
1686
1687 assert(s);
1688
e537352b
LP
1689 /* Already on it */
1690 if (s->state == SOCKET_STOP_PRE ||
1691 s->state == SOCKET_STOP_PRE_SIGTERM ||
1692 s->state == SOCKET_STOP_PRE_SIGKILL ||
1693 s->state == SOCKET_STOP_POST ||
80876c20 1694 s->state == SOCKET_FINAL_SIGTERM ||
3f6c78dc 1695 s->state == SOCKET_FINAL_SIGKILL)
e537352b
LP
1696 return 0;
1697
3f6c78dc
LP
1698 /* If there's already something running we go directly into
1699 * kill mode. */
1700 if (s->state == SOCKET_START_PRE ||
1701 s->state == SOCKET_START_POST) {
cfc4eb4c 1702 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS);
3f6c78dc
LP
1703 return -EAGAIN;
1704 }
1705
034c6ed7 1706 assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
83c60c9f 1707
cfc4eb4c 1708 socket_enter_stop_pre(s, SOCKET_SUCCESS);
542563ba
LP
1709 return 0;
1710}
1711
a16e1123
LP
1712static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
1713 Socket *s = SOCKET(u);
1714 SocketPort *p;
1715 int r;
1716
1717 assert(u);
1718 assert(f);
1719 assert(fds);
1720
1721 unit_serialize_item(u, f, "state", socket_state_to_string(s->state));
cfc4eb4c 1722 unit_serialize_item(u, f, "result", socket_result_to_string(s->result));
a16e1123
LP
1723 unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted);
1724
1725 if (s->control_pid > 0)
5925dd3c 1726 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
a16e1123
LP
1727
1728 if (s->control_command_id >= 0)
1729 unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id));
1730
1731 LIST_FOREACH(port, p, s->ports) {
1732 int copy;
1733
1734 if (p->fd < 0)
1735 continue;
1736
1737 if ((copy = fdset_put_dup(fds, p->fd)) < 0)
1738 return copy;
1739
1740 if (p->type == SOCKET_SOCKET) {
1741 char *t;
1742
ee092817
LP
1743 r = socket_address_print(&p->address, &t);
1744 if (r < 0)
a16e1123
LP
1745 return r;
1746
7a22745a
LP
1747 if (socket_address_family(&p->address) == AF_NETLINK)
1748 unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t);
1749 else
1750 unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t);
a16e1123 1751 free(t);
b0a3f2bc
LP
1752 } else if (p->type == SOCKET_SPECIAL)
1753 unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path);
ee092817
LP
1754 else if (p->type == SOCKET_MQUEUE)
1755 unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path);
b0a3f2bc 1756 else {
a16e1123
LP
1757 assert(p->type == SOCKET_FIFO);
1758 unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path);
1759 }
1760 }
1761
c17ec25e
MS
1762 exec_context_serialize(&s->exec_context, UNIT(s), f);
1763
a16e1123
LP
1764 return 0;
1765}
1766
1767static int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1768 Socket *s = SOCKET(u);
a16e1123
LP
1769
1770 assert(u);
1771 assert(key);
1772 assert(value);
1773 assert(fds);
1774
1775 if (streq(key, "state")) {
1776 SocketState state;
1777
ee092817
LP
1778 state = socket_state_from_string(value);
1779 if (state < 0)
66870f90
ZJS
1780 log_debug_unit(u->id,
1781 "Failed to parse state value %s", value);
a16e1123
LP
1782 else
1783 s->deserialized_state = state;
cfc4eb4c
LP
1784 } else if (streq(key, "result")) {
1785 SocketResult f;
a16e1123 1786
cfc4eb4c
LP
1787 f = socket_result_from_string(value);
1788 if (f < 0)
66870f90
ZJS
1789 log_debug_unit(u->id,
1790 "Failed to parse result value %s", value);
cfc4eb4c
LP
1791 else if (f != SOCKET_SUCCESS)
1792 s->result = f;
a16e1123
LP
1793
1794 } else if (streq(key, "n-accepted")) {
1795 unsigned k;
1796
e364ad06 1797 if (safe_atou(value, &k) < 0)
66870f90
ZJS
1798 log_debug_unit(u->id,
1799 "Failed to parse n-accepted value %s", value);
a16e1123
LP
1800 else
1801 s->n_accepted += k;
1802 } else if (streq(key, "control-pid")) {
5925dd3c 1803 pid_t pid;
a16e1123 1804
e364ad06 1805 if (parse_pid(value, &pid) < 0)
66870f90
ZJS
1806 log_debug_unit(u->id,
1807 "Failed to parse control-pid value %s", value);
a16e1123 1808 else
5925dd3c 1809 s->control_pid = pid;
a16e1123
LP
1810 } else if (streq(key, "control-command")) {
1811 SocketExecCommand id;
1812
66870f90
ZJS
1813 id = socket_exec_command_from_string(value);
1814 if (id < 0)
1815 log_debug_unit(u->id,
1816 "Failed to parse exec-command value %s", value);
a16e1123
LP
1817 else {
1818 s->control_command_id = id;
1819 s->control_command = s->exec_command[id];
1820 }
1821 } else if (streq(key, "fifo")) {
1822 int fd, skip = 0;
1823 SocketPort *p;
1824
1825 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1826 log_debug_unit(u->id,
1827 "Failed to parse fifo value %s", value);
a16e1123
LP
1828 else {
1829
1830 LIST_FOREACH(port, p, s->ports)
b0a3f2bc
LP
1831 if (p->type == SOCKET_FIFO &&
1832 streq_ptr(p->path, value+skip))
1833 break;
1834
1835 if (p) {
1836 if (p->fd >= 0)
1837 close_nointr_nofail(p->fd);
1838 p->fd = fdset_remove(fds, fd);
1839 }
1840 }
1841
1842 } else if (streq(key, "special")) {
1843 int fd, skip = 0;
1844 SocketPort *p;
1845
1846 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1847 log_debug_unit(u->id,
1848 "Failed to parse special value %s", value);
b0a3f2bc
LP
1849 else {
1850
1851 LIST_FOREACH(port, p, s->ports)
1852 if (p->type == SOCKET_SPECIAL &&
1853 streq_ptr(p->path, value+skip))
a16e1123
LP
1854 break;
1855
1856 if (p) {
1857 if (p->fd >= 0)
1858 close_nointr_nofail(p->fd);
1859 p->fd = fdset_remove(fds, fd);
1860 }
1861 }
1862
ee092817
LP
1863 } else if (streq(key, "mqueue")) {
1864 int fd, skip = 0;
1865 SocketPort *p;
1866
1867 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1868 log_debug_unit(u->id,
1869 "Failed to parse mqueue value %s", value);
ee092817
LP
1870 else {
1871
1872 LIST_FOREACH(port, p, s->ports)
1873 if (p->type == SOCKET_MQUEUE &&
1874 streq_ptr(p->path, value+skip))
1875 break;
1876
1877 if (p) {
1878 if (p->fd >= 0)
1879 close_nointr_nofail(p->fd);
1880 p->fd = fdset_remove(fds, fd);
1881 }
1882 }
1883
a16e1123 1884 } else if (streq(key, "socket")) {
27ca8d7a 1885 int fd, type, skip = 0;
a16e1123
LP
1886 SocketPort *p;
1887
27ca8d7a 1888 if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1889 log_debug_unit(u->id,
1890 "Failed to parse socket value %s", value);
a16e1123
LP
1891 else {
1892
1893 LIST_FOREACH(port, p, s->ports)
27ca8d7a 1894 if (socket_address_is(&p->address, value+skip, type))
a16e1123
LP
1895 break;
1896
1897 if (p) {
1898 if (p->fd >= 0)
1899 close_nointr_nofail(p->fd);
1900 p->fd = fdset_remove(fds, fd);
1901 }
1902 }
1903
7a22745a
LP
1904 } else if (streq(key, "netlink")) {
1905 int fd, skip = 0;
1906 SocketPort *p;
1907
1908 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1909 log_debug_unit(u->id,
1910 "Failed to parse socket value %s", value);
7a22745a
LP
1911 else {
1912
1913 LIST_FOREACH(port, p, s->ports)
1914 if (socket_address_is_netlink(&p->address, value+skip))
1915 break;
1916
1917 if (p) {
1918 if (p->fd >= 0)
1919 close_nointr_nofail(p->fd);
1920 p->fd = fdset_remove(fds, fd);
1921 }
1922 }
c17ec25e
MS
1923 } else if (streq(key, "tmp-dir")) {
1924 char *t;
1925
1926 t = strdup(value);
1927 if (!t)
1928 return log_oom();
1929
1930 s->exec_context.tmp_dir = t;
1931 } else if (streq(key, "var-tmp-dir")) {
1932 char *t;
1933
1934 t = strdup(value);
1935 if (!t)
1936 return log_oom();
7a22745a 1937
c17ec25e 1938 s->exec_context.var_tmp_dir = t;
a16e1123 1939 } else
66870f90
ZJS
1940 log_debug_unit(UNIT(s)->id,
1941 "Unknown serialization key '%s'", key);
a16e1123
LP
1942
1943 return 0;
1944}
1945
01e10de3
LP
1946static int socket_distribute_fds(Unit *u, FDSet *fds) {
1947 Socket *s = SOCKET(u);
1948 SocketPort *p;
1949
1950 assert(u);
1951
1952 LIST_FOREACH(port, p, s->ports) {
1953 Iterator i;
1954 int fd;
1955
1956 if (p->type != SOCKET_SOCKET)
1957 continue;
1958
1959 if (p->fd >= 0)
1960 continue;
1961
1962 FDSET_FOREACH(fd, fds, i) {
1963 if (socket_address_matches_fd(&p->address, fd)) {
1964 p->fd = fdset_remove(fds, fd);
1965 s->deserialized_state = SOCKET_LISTENING;
1966 break;
1967 }
1968 }
1969 }
1970
1971 return 0;
1972}
1973
44a6b1b6 1974_pure_ static UnitActiveState socket_active_state(Unit *u) {
87f0e418 1975 assert(u);
5cb5a6ff 1976
acbb0225 1977 return state_translation_table[SOCKET(u)->state];
5cb5a6ff
LP
1978}
1979
44a6b1b6 1980_pure_ static const char *socket_sub_state_to_string(Unit *u) {
10a94420
LP
1981 assert(u);
1982
a16e1123 1983 return socket_state_to_string(SOCKET(u)->state);
10a94420
LP
1984}
1985
67419600
OS
1986const char* socket_port_type_to_string(SocketPort *p) {
1987
1988 assert(p);
1989
1990 switch (p->type) {
1991 case SOCKET_SOCKET:
1992 switch (p->address.type) {
1993 case SOCK_STREAM: return "Stream";
1994 case SOCK_DGRAM: return "Datagram";
1995 case SOCK_SEQPACKET: return "SequentialPacket";
1996 case SOCK_RAW:
1997 if (socket_address_family(&p->address) == AF_NETLINK)
1998 return "Netlink";
1999 default: return "Invalid";
2000 }
2001 case SOCKET_SPECIAL: return "Special";
2002 case SOCKET_MQUEUE: return "MessageQueue";
2003 case SOCKET_FIFO: return "FIFO";
2004 default: return NULL;
2005 }
2006}
2007
44a6b1b6 2008_pure_ static bool socket_check_gc(Unit *u) {
6cf6bbc2
LP
2009 Socket *s = SOCKET(u);
2010
2011 assert(u);
2012
2013 return s->n_connections > 0;
2014}
2015
acbb0225 2016static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
87f0e418 2017 Socket *s = SOCKET(u);
4f2d528d 2018 int cfd = -1;
9152c765 2019
034c6ed7 2020 assert(s);
8d567588 2021 assert(fd >= 0);
9152c765 2022
871d7de4
LP
2023 if (s->state != SOCKET_LISTENING)
2024 return;
2025
66870f90 2026 log_debug_unit(u->id, "Incoming traffic on %s", u->id);
9152c765 2027
4f2d528d 2028 if (events != EPOLLIN) {
641e01dc
LP
2029
2030 if (events & EPOLLHUP)
66870f90
ZJS
2031 log_error_unit(u->id,
2032 "%s: Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that.",
2033 u->id);
641e01dc 2034 else
66870f90
ZJS
2035 log_error_unit(u->id,
2036 "%s: Got unexpected poll event (0x%x) on socket.",
2037 u->id, events);
641e01dc 2038
8d567588 2039 goto fail;
4f2d528d
LP
2040 }
2041
cabab516 2042 if (w->socket_accept) {
4f2d528d
LP
2043 for (;;) {
2044
b14eda96
LP
2045 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK);
2046 if (cfd < 0) {
4f2d528d
LP
2047
2048 if (errno == EINTR)
2049 continue;
2050
66870f90
ZJS
2051 log_error_unit(u->id,
2052 "Failed to accept socket: %m");
8d567588 2053 goto fail;
4f2d528d
LP
2054 }
2055
2056 break;
2057 }
4fd5948e
LP
2058
2059 socket_apply_socket_options(s, cfd);
4f2d528d 2060 }
9152c765 2061
4f2d528d 2062 socket_enter_running(s, cfd);
8d567588
LP
2063 return;
2064
2065fail:
cfc4eb4c 2066 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
9152c765
LP
2067}
2068
87f0e418
LP
2069static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
2070 Socket *s = SOCKET(u);
cfc4eb4c 2071 SocketResult f;
5cb5a6ff
LP
2072
2073 assert(s);
034c6ed7 2074 assert(pid >= 0);
5cb5a6ff 2075
8c47c732
LP
2076 if (pid != s->control_pid)
2077 return;
542563ba 2078
034c6ed7
LP
2079 s->control_pid = 0;
2080
96342de6 2081 if (is_clean_exit(code, status, NULL))
cfc4eb4c
LP
2082 f = SOCKET_SUCCESS;
2083 else if (code == CLD_EXITED)
2084 f = SOCKET_FAILURE_EXIT_CODE;
2085 else if (code == CLD_KILLED)
2086 f = SOCKET_FAILURE_SIGNAL;
2087 else if (code == CLD_DUMPED)
2088 f = SOCKET_FAILURE_CORE_DUMP;
2089 else
2090 assert_not_reached("Unknown code");
8c47c732 2091
b708e7ce 2092 if (s->control_command) {
6ea832a2 2093 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
a16e1123 2094
b708e7ce 2095 if (s->control_command->ignore)
cfc4eb4c 2096 f = SOCKET_SUCCESS;
b708e7ce
LP
2097 }
2098
66870f90
ZJS
2099 log_full_unit(f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
2100 u->id,
2101 "%s control process exited, code=%s status=%i",
2102 u->id, sigchld_code_to_string(code), status);
034c6ed7 2103
cfc4eb4c
LP
2104 if (f != SOCKET_SUCCESS)
2105 s->result = f;
2106
2107 if (s->control_command &&
2108 s->control_command->command_next &&
2109 f == SOCKET_SUCCESS) {
2110
66870f90
ZJS
2111 log_debug_unit(u->id,
2112 "%s running next command for state %s",
2113 u->id, socket_state_to_string(s->state));
cfc4eb4c 2114 socket_run_next(s);
acbb0225 2115 } else {
a16e1123
LP
2116 s->control_command = NULL;
2117 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
2118
034c6ed7
LP
2119 /* No further commands for this step, so let's figure
2120 * out what to do next */
5cb5a6ff 2121
66870f90
ZJS
2122 log_debug_unit(u->id,
2123 "%s got final SIGCHLD for state %s",
2124 u->id, socket_state_to_string(s->state));
acbb0225 2125
034c6ed7
LP
2126 switch (s->state) {
2127
2128 case SOCKET_START_PRE:
cfc4eb4c 2129 if (f == SOCKET_SUCCESS)
acbb0225 2130 socket_enter_start_post(s);
034c6ed7 2131 else
cfc4eb4c 2132 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f);
034c6ed7
LP
2133 break;
2134
2135 case SOCKET_START_POST:
cfc4eb4c 2136 if (f == SOCKET_SUCCESS)
e9af15c3 2137 socket_enter_listening(s);
034c6ed7 2138 else
cfc4eb4c 2139 socket_enter_stop_pre(s, f);
034c6ed7
LP
2140 break;
2141
2142 case SOCKET_STOP_PRE:
2143 case SOCKET_STOP_PRE_SIGTERM:
2144 case SOCKET_STOP_PRE_SIGKILL:
cfc4eb4c 2145 socket_enter_stop_post(s, f);
034c6ed7
LP
2146 break;
2147
2148 case SOCKET_STOP_POST:
80876c20
LP
2149 case SOCKET_FINAL_SIGTERM:
2150 case SOCKET_FINAL_SIGKILL:
cfc4eb4c 2151 socket_enter_dead(s, f);
034c6ed7
LP
2152 break;
2153
2154 default:
2155 assert_not_reached("Uh, control process died at wrong time.");
2156 }
2157 }
c4e2ceae
LP
2158
2159 /* Notify clients about changed exit status */
2160 unit_add_to_dbus_queue(u);
034c6ed7 2161}
5cb5a6ff 2162
acbb0225 2163static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
87f0e418 2164 Socket *s = SOCKET(u);
5cb5a6ff 2165
034c6ed7
LP
2166 assert(s);
2167 assert(elapsed == 1);
acbb0225 2168 assert(w == &s->timer_watch);
034c6ed7
LP
2169
2170 switch (s->state) {
2171
2172 case SOCKET_START_PRE:
66870f90
ZJS
2173 log_warning_unit(u->id,
2174 "%s starting timed out. Terminating.", u->id);
cfc4eb4c 2175 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
da19d5c1 2176 break;
80876c20 2177
034c6ed7 2178 case SOCKET_START_POST:
66870f90
ZJS
2179 log_warning_unit(u->id,
2180 "%s starting timed out. Stopping.", u->id);
cfc4eb4c 2181 socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2182 break;
2183
2184 case SOCKET_STOP_PRE:
66870f90
ZJS
2185 log_warning_unit(u->id,
2186 "%s stopping timed out. Terminating.", u->id);
cfc4eb4c 2187 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2188 break;
2189
2190 case SOCKET_STOP_PRE_SIGTERM:
4819ff03 2191 if (s->kill_context.send_sigkill) {
66870f90
ZJS
2192 log_warning_unit(u->id,
2193 "%s stopping timed out. Killing.", u->id);
cfc4eb4c 2194 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT);
ba035df2 2195 } else {
66870f90
ZJS
2196 log_warning_unit(u->id,
2197 "%s stopping timed out. Skipping SIGKILL. Ignoring.",
2198 u->id);
cfc4eb4c 2199 socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
ba035df2 2200 }
034c6ed7
LP
2201 break;
2202
2203 case SOCKET_STOP_PRE_SIGKILL:
66870f90
ZJS
2204 log_warning_unit(u->id,
2205 "%s still around after SIGKILL. Ignoring.", u->id);
cfc4eb4c 2206 socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2207 break;
2208
2209 case SOCKET_STOP_POST:
66870f90
ZJS
2210 log_warning_unit(u->id,
2211 "%s stopping timed out (2). Terminating.", u->id);
cfc4eb4c 2212 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2213 break;
2214
80876c20 2215 case SOCKET_FINAL_SIGTERM:
4819ff03 2216 if (s->kill_context.send_sigkill) {
66870f90
ZJS
2217 log_warning_unit(u->id,
2218 "%s stopping timed out (2). Killing.", u->id);
cfc4eb4c 2219 socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT);
ba035df2 2220 } else {
66870f90
ZJS
2221 log_warning_unit(u->id,
2222 "%s stopping timed out (2). Skipping SIGKILL. Ignoring.",
2223 u->id);
cfc4eb4c 2224 socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
ba035df2 2225 }
034c6ed7
LP
2226 break;
2227
80876c20 2228 case SOCKET_FINAL_SIGKILL:
66870f90
ZJS
2229 log_warning_unit(u->id,
2230 "%s still around after SIGKILL (2). Entering failed mode.",
2231 u->id);
cfc4eb4c 2232 socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2233 break;
2234
2235 default:
2236 assert_not_reached("Timeout at wrong time.");
2237 }
5cb5a6ff
LP
2238}
2239
44d8db9e
LP
2240int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
2241 int *rfds;
2242 unsigned rn_fds, k;
2243 SocketPort *p;
2244
2245 assert(s);
2246 assert(fds);
2247 assert(n_fds);
2248
2249 /* Called from the service code for requesting our fds */
2250
2251 rn_fds = 0;
2252 LIST_FOREACH(port, p, s->ports)
2253 if (p->fd >= 0)
2254 rn_fds++;
2255
de3756ab
LP
2256 if (rn_fds <= 0) {
2257 *fds = NULL;
2258 *n_fds = 0;
2259 return 0;
2260 }
2261
e364ad06 2262 if (!(rfds = new(int, rn_fds)))
44d8db9e
LP
2263 return -ENOMEM;
2264
2265 k = 0;
2266 LIST_FOREACH(port, p, s->ports)
2267 if (p->fd >= 0)
2268 rfds[k++] = p->fd;
2269
2270 assert(k == rn_fds);
2271
2272 *fds = rfds;
2273 *n_fds = rn_fds;
2274
2275 return 0;
2276}
2277
d137a488 2278static void socket_notify_service_dead(Socket *s, bool failed_permanent) {
ceee3d82
LP
2279 assert(s);
2280
6cf6bbc2
LP
2281 /* The service is dead. Dang!
2282 *
2283 * This is strictly for one-instance-for-all-connections
2284 * services. */
ceee3d82
LP
2285
2286 if (s->state == SOCKET_RUNNING) {
66870f90
ZJS
2287 log_debug_unit(UNIT(s)->id,
2288 "%s got notified about service death (failed permanently: %s)",
2289 UNIT(s)->id, yes_no(failed_permanent));
6bda96a0
LP
2290 if (failed_permanent)
2291 socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_FAILED_PERMANENT);
c2f34808
MS
2292 else
2293 socket_enter_listening(s);
ceee3d82
LP
2294 }
2295}
2296
6cf6bbc2
LP
2297void socket_connection_unref(Socket *s) {
2298 assert(s);
2299
2300 /* The service is dead. Yay!
2301 *
35b8ca3a 2302 * This is strictly for one-instance-per-connection
6cf6bbc2
LP
2303 * services. */
2304
2305 assert(s->n_connections > 0);
2306 s->n_connections--;
2307
66870f90
ZJS
2308 log_debug_unit(UNIT(s)->id,
2309 "%s: One connection closed, %u left.", UNIT(s)->id, s->n_connections);
6cf6bbc2
LP
2310}
2311
fdf20a31 2312static void socket_reset_failed(Unit *u) {
5632e374
LP
2313 Socket *s = SOCKET(u);
2314
2315 assert(s);
2316
fdf20a31 2317 if (s->state == SOCKET_FAILED)
5632e374
LP
2318 socket_set_state(s, SOCKET_DEAD);
2319
cfc4eb4c 2320 s->result = SOCKET_SUCCESS;
5632e374
LP
2321}
2322
d137a488
UTL
2323static void socket_trigger_notify(Unit *u, Unit *other) {
2324 Socket *s = SOCKET(u);
2325 Service *se = SERVICE(other);
2326
2327 assert(u);
2328 assert(other);
2329
2330 /* Don't propagate state changes from the service if we are
2331 already down or accepting connections */
2332 if ((s->state != SOCKET_RUNNING &&
2333 s->state != SOCKET_LISTENING) ||
2334 s->accept)
2335 return;
2336
2337 if (other->load_state != UNIT_LOADED ||
2338 other->type != UNIT_SERVICE)
2339 return;
2340
2341 if (se->state == SERVICE_FAILED)
2342 socket_notify_service_dead(s, se->result == SERVICE_FAILURE_START_LIMIT);
2343
2344 if (se->state == SERVICE_DEAD ||
2345 se->state == SERVICE_STOP ||
2346 se->state == SERVICE_STOP_SIGTERM ||
2347 se->state == SERVICE_STOP_SIGKILL ||
2348 se->state == SERVICE_STOP_POST ||
2349 se->state == SERVICE_FINAL_SIGTERM ||
2350 se->state == SERVICE_FINAL_SIGKILL ||
2351 se->state == SERVICE_AUTO_RESTART)
2352 socket_notify_service_dead(s, false);
2353
2354 if (se->state == SERVICE_RUNNING)
2355 socket_set_state(s, SOCKET_RUNNING);
2356}
2357
c74f17d9 2358static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) {
814cc562 2359 return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
8a0867d6
LP
2360}
2361
a16e1123
LP
2362static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
2363 [SOCKET_DEAD] = "dead",
2364 [SOCKET_START_PRE] = "start-pre",
2365 [SOCKET_START_POST] = "start-post",
2366 [SOCKET_LISTENING] = "listening",
2367 [SOCKET_RUNNING] = "running",
2368 [SOCKET_STOP_PRE] = "stop-pre",
2369 [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
2370 [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
2371 [SOCKET_STOP_POST] = "stop-post",
2372 [SOCKET_FINAL_SIGTERM] = "final-sigterm",
2373 [SOCKET_FINAL_SIGKILL] = "final-sigkill",
fdf20a31 2374 [SOCKET_FAILED] = "failed"
a16e1123
LP
2375};
2376
2377DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
2378
2379static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
2380 [SOCKET_EXEC_START_PRE] = "StartPre",
2381 [SOCKET_EXEC_START_POST] = "StartPost",
2382 [SOCKET_EXEC_STOP_PRE] = "StopPre",
2383 [SOCKET_EXEC_STOP_POST] = "StopPost"
2384};
2385
2386DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand);
2387
cfc4eb4c
LP
2388static const char* const socket_result_table[_SOCKET_RESULT_MAX] = {
2389 [SOCKET_SUCCESS] = "success",
2390 [SOCKET_FAILURE_RESOURCES] = "resources",
2391 [SOCKET_FAILURE_TIMEOUT] = "timeout",
2392 [SOCKET_FAILURE_EXIT_CODE] = "exit-code",
2393 [SOCKET_FAILURE_SIGNAL] = "signal",
c2f34808 2394 [SOCKET_FAILURE_CORE_DUMP] = "core-dump",
6bda96a0 2395 [SOCKET_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent"
cfc4eb4c
LP
2396};
2397
2398DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult);
2399
87f0e418 2400const UnitVTable socket_vtable = {
7d17cfbc 2401 .object_size = sizeof(Socket),
3ef63c31 2402
f975e971
LP
2403 .sections =
2404 "Unit\0"
2405 "Socket\0"
2406 "Install\0",
5cb5a6ff 2407
4ad49000 2408 .private_section = "Socket",
71645aca 2409 .exec_context_offset = offsetof(Socket, exec_context),
4ad49000 2410 .cgroup_context_offset = offsetof(Socket, cgroup_context),
71645aca 2411
034c6ed7
LP
2412 .init = socket_init,
2413 .done = socket_done,
a16e1123
LP
2414 .load = socket_load,
2415
8a0867d6
LP
2416 .kill = socket_kill,
2417
a16e1123 2418 .coldplug = socket_coldplug,
034c6ed7 2419
5cb5a6ff
LP
2420 .dump = socket_dump,
2421
542563ba
LP
2422 .start = socket_start,
2423 .stop = socket_stop,
5cb5a6ff 2424
a16e1123
LP
2425 .serialize = socket_serialize,
2426 .deserialize_item = socket_deserialize_item,
01e10de3 2427 .distribute_fds = socket_distribute_fds,
a16e1123 2428
5cb5a6ff 2429 .active_state = socket_active_state,
10a94420 2430 .sub_state_to_string = socket_sub_state_to_string,
5cb5a6ff 2431
6cf6bbc2
LP
2432 .check_gc = socket_check_gc,
2433
9152c765 2434 .fd_event = socket_fd_event,
034c6ed7 2435 .sigchld_event = socket_sigchld_event,
4139c1b2
LP
2436 .timer_event = socket_timer_event,
2437
d137a488
UTL
2438 .trigger_notify = socket_trigger_notify,
2439
fdf20a31 2440 .reset_failed = socket_reset_failed,
5632e374 2441
c4e2ceae
LP
2442 .bus_interface = "org.freedesktop.systemd1.Socket",
2443 .bus_message_handler = bus_socket_message_handler,
c6918296 2444 .bus_invalidating_properties = bus_socket_invalidating_properties,
74c964d3
LP
2445 .bus_set_property = bus_socket_set_property,
2446 .bus_commit_properties = bus_socket_commit_properties,
c6918296
MS
2447
2448 .status_message_formats = {
2449 /*.starting_stopping = {
2450 [0] = "Starting socket %s...",
2451 [1] = "Stopping socket %s...",
2452 },*/
2453 .finished_start_job = {
2454 [JOB_DONE] = "Listening on %s.",
2455 [JOB_FAILED] = "Failed to listen on %s.",
2456 [JOB_DEPENDENCY] = "Dependency failed for %s.",
2457 [JOB_TIMEOUT] = "Timed out starting %s.",
2458 },
2459 .finished_stop_job = {
2460 [JOB_DONE] = "Closed %s.",
2461 [JOB_FAILED] = "Failed stopping %s.",
2462 [JOB_TIMEOUT] = "Timed out stopping %s.",
2463 },
2464 },
5cb5a6ff 2465};