]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/core/socket.c
update TODO
[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
36697dc0
LP
1229 argv = unit_full_printf_strv(UNIT(s), c->argv);
1230 if (!argv) {
9e2f7c11
LP
1231 r = -ENOMEM;
1232 goto fail;
1233 }
1234
1235 r = exec_spawn(c,
1236 argv,
1237 &s->exec_context,
1238 NULL, 0,
1124fe6f 1239 UNIT(s)->manager->environment,
9e2f7c11
LP
1240 true,
1241 true,
1e3ad081 1242 true,
1124fe6f 1243 UNIT(s)->manager->confirm_spawn,
4ad49000
LP
1244 UNIT(s)->cgroup_mask,
1245 UNIT(s)->cgroup_path,
62bca2c6 1246 UNIT(s)->id,
f2b68789 1247 NULL,
9e2f7c11
LP
1248 &pid);
1249
1250 strv_free(argv);
1251 if (r < 0)
034c6ed7
LP
1252 goto fail;
1253
87f0e418 1254 if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
034c6ed7
LP
1255 /* FIXME: we need to do something here */
1256 goto fail;
83c60c9f 1257
034c6ed7
LP
1258 *_pid = pid;
1259
1260 return 0;
1261
1262fail:
e537352b 1263 unit_unwatch_timer(UNIT(s), &s->timer_watch);
83c60c9f
LP
1264
1265 return r;
542563ba
LP
1266}
1267
cfc4eb4c 1268static void socket_enter_dead(Socket *s, SocketResult f) {
034c6ed7
LP
1269 assert(s);
1270
cfc4eb4c
LP
1271 if (f != SOCKET_SUCCESS)
1272 s->result = f;
034c6ed7 1273
c17ec25e 1274 exec_context_tmp_dirs_done(&s->exec_context);
cfc4eb4c 1275 socket_set_state(s, s->result != SOCKET_SUCCESS ? SOCKET_FAILED : SOCKET_DEAD);
034c6ed7
LP
1276}
1277
cfc4eb4c 1278static void socket_enter_signal(Socket *s, SocketState state, SocketResult f);
80876c20 1279
cfc4eb4c 1280static void socket_enter_stop_post(Socket *s, SocketResult f) {
034c6ed7
LP
1281 int r;
1282 assert(s);
1283
cfc4eb4c
LP
1284 if (f != SOCKET_SUCCESS)
1285 s->result = f;
034c6ed7 1286
5e94833f
LP
1287 socket_unwatch_control_pid(s);
1288
a16e1123
LP
1289 s->control_command_id = SOCKET_EXEC_STOP_POST;
1290
80876c20 1291 if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_POST])) {
e537352b 1292 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1293 goto fail;
1294
80876c20
LP
1295 socket_set_state(s, SOCKET_STOP_POST);
1296 } else
cfc4eb4c 1297 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_SUCCESS);
034c6ed7
LP
1298
1299 return;
1300
1301fail:
66870f90
ZJS
1302 log_warning_unit(UNIT(s)->id,
1303 "%s failed to run 'stop-post' task: %s",
1304 UNIT(s)->id, strerror(-r));
cfc4eb4c 1305 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1306}
1307
cfc4eb4c 1308static void socket_enter_signal(Socket *s, SocketState state, SocketResult f) {
034c6ed7
LP
1309 int r;
1310
1311 assert(s);
1312
cfc4eb4c
LP
1313 if (f != SOCKET_SUCCESS)
1314 s->result = f;
034c6ed7 1315
cd2086fe
LP
1316 r = unit_kill_context(
1317 UNIT(s),
1318 &s->kill_context,
1319 state != SOCKET_STOP_PRE_SIGTERM && state != SOCKET_FINAL_SIGTERM,
1320 -1,
1321 s->control_pid,
1322 false);
1323 if (r < 0)
1324 goto fail;
034c6ed7 1325
cd2086fe 1326 if (r > 0) {
36697dc0
LP
1327 r = unit_watch_timer(UNIT(s), CLOCK_MONOTONIC, true, s->timeout_usec, &s->timer_watch);
1328 if (r < 0)
80876c20 1329 goto fail;
d6ea93e3 1330
80876c20
LP
1331 socket_set_state(s, state);
1332 } else if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
cfc4eb4c 1333 socket_enter_stop_post(s, SOCKET_SUCCESS);
80876c20 1334 else
cfc4eb4c 1335 socket_enter_dead(s, SOCKET_SUCCESS);
034c6ed7
LP
1336
1337 return;
1338
1339fail:
66870f90
ZJS
1340 log_warning_unit(UNIT(s)->id,
1341 "%s failed to kill processes: %s",
1342 UNIT(s)->id, strerror(-r));
034c6ed7
LP
1343
1344 if (state == SOCKET_STOP_PRE_SIGTERM || state == SOCKET_STOP_PRE_SIGKILL)
cfc4eb4c 1345 socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
034c6ed7 1346 else
cfc4eb4c 1347 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1348}
1349
cfc4eb4c 1350static void socket_enter_stop_pre(Socket *s, SocketResult f) {
034c6ed7
LP
1351 int r;
1352 assert(s);
1353
cfc4eb4c
LP
1354 if (f != SOCKET_SUCCESS)
1355 s->result = f;
034c6ed7 1356
5e94833f
LP
1357 socket_unwatch_control_pid(s);
1358
a16e1123
LP
1359 s->control_command_id = SOCKET_EXEC_STOP_PRE;
1360
80876c20 1361 if ((s->control_command = s->exec_command[SOCKET_EXEC_STOP_PRE])) {
e537352b 1362 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1363 goto fail;
1364
80876c20
LP
1365 socket_set_state(s, SOCKET_STOP_PRE);
1366 } else
cfc4eb4c 1367 socket_enter_stop_post(s, SOCKET_SUCCESS);
034c6ed7
LP
1368
1369 return;
1370
1371fail:
66870f90
ZJS
1372 log_warning_unit(UNIT(s)->id,
1373 "%s failed to run 'stop-pre' task: %s",
1374 UNIT(s)->id, strerror(-r));
cfc4eb4c 1375 socket_enter_stop_post(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1376}
1377
e9af15c3
LP
1378static void socket_enter_listening(Socket *s) {
1379 int r;
1380 assert(s);
1381
cfc4eb4c
LP
1382 r = socket_watch_fds(s);
1383 if (r < 0) {
66870f90
ZJS
1384 log_warning_unit(UNIT(s)->id,
1385 "%s failed to watch sockets: %s",
1386 UNIT(s)->id, strerror(-r));
e9af15c3
LP
1387 goto fail;
1388 }
1389
1390 socket_set_state(s, SOCKET_LISTENING);
1391 return;
1392
1393fail:
cfc4eb4c 1394 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
e9af15c3
LP
1395}
1396
034c6ed7
LP
1397static void socket_enter_start_post(Socket *s) {
1398 int r;
1399 assert(s);
1400
cfc4eb4c
LP
1401 r = socket_open_fds(s);
1402 if (r < 0) {
66870f90
ZJS
1403 log_warning_unit(UNIT(s)->id,
1404 "%s failed to listen on sockets: %s",
1405 UNIT(s)->id, strerror(-r));
034c6ed7
LP
1406 goto fail;
1407 }
1408
5e94833f
LP
1409 socket_unwatch_control_pid(s);
1410
a16e1123
LP
1411 s->control_command_id = SOCKET_EXEC_START_POST;
1412
80876c20 1413 if ((s->control_command = s->exec_command[SOCKET_EXEC_START_POST])) {
cfc4eb4c
LP
1414 r = socket_spawn(s, s->control_command, &s->control_pid);
1415 if (r < 0) {
66870f90
ZJS
1416 log_warning_unit(UNIT(s)->id,
1417 "%s failed to run 'start-post' task: %s",
1418 UNIT(s)->id, strerror(-r));
034c6ed7
LP
1419 goto fail;
1420 }
1421
80876c20
LP
1422 socket_set_state(s, SOCKET_START_POST);
1423 } else
e9af15c3 1424 socket_enter_listening(s);
034c6ed7
LP
1425
1426 return;
1427
1428fail:
cfc4eb4c 1429 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1430}
1431
1432static void socket_enter_start_pre(Socket *s) {
1433 int r;
1434 assert(s);
1435
5e94833f
LP
1436 socket_unwatch_control_pid(s);
1437
a16e1123
LP
1438 s->control_command_id = SOCKET_EXEC_START_PRE;
1439
80876c20 1440 if ((s->control_command = s->exec_command[SOCKET_EXEC_START_PRE])) {
e537352b 1441 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1442 goto fail;
1443
80876c20
LP
1444 socket_set_state(s, SOCKET_START_PRE);
1445 } else
034c6ed7
LP
1446 socket_enter_start_post(s);
1447
1448 return;
1449
1450fail:
66870f90
ZJS
1451 log_warning_unit(UNIT(s)->id,
1452 "%s failed to run 'start-pre' task: %s",
1453 UNIT(s)->id, strerror(-r));
cfc4eb4c 1454 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1455}
1456
4f2d528d 1457static void socket_enter_running(Socket *s, int cfd) {
034c6ed7 1458 int r;
398ef8ba 1459 DBusError error;
034c6ed7
LP
1460
1461 assert(s);
398ef8ba 1462 dbus_error_init(&error);
034c6ed7 1463
ba3e67a7
LP
1464 /* We don't take connections anymore if we are supposed to
1465 * shut down anyway */
31afa0a4 1466 if (unit_stop_pending(UNIT(s))) {
66870f90
ZJS
1467 log_debug_unit(UNIT(s)->id,
1468 "Suppressing connection request on %s since unit stop is scheduled.",
1469 UNIT(s)->id);
5d909e3e 1470
7c610628
LP
1471 if (cfd >= 0)
1472 close_nointr_nofail(cfd);
1473 else {
1474 /* Flush all sockets by closing and reopening them */
1475 socket_close_fds(s);
1476
1a710b43
MS
1477 r = socket_watch_fds(s);
1478 if (r < 0) {
66870f90
ZJS
1479 log_warning_unit(UNIT(s)->id,
1480 "%s failed to watch sockets: %s",
1481 UNIT(s)->id, strerror(-r));
cfc4eb4c 1482 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
7c610628
LP
1483 }
1484 }
1485
ba3e67a7
LP
1486 return;
1487 }
1488
4f2d528d 1489 if (cfd < 0) {
57020a3a
LP
1490 Iterator i;
1491 Unit *u;
f976f3f6 1492 bool pending = false;
f976f3f6
LP
1493
1494 /* If there's already a start pending don't bother to
1495 * do anything */
1124fe6f 1496 SET_FOREACH(u, UNIT(s)->dependencies[UNIT_TRIGGERS], i)
31afa0a4 1497 if (unit_active_or_pending(u)) {
57020a3a
LP
1498 pending = true;
1499 break;
1500 }
f976f3f6 1501
1a710b43
MS
1502 if (!pending) {
1503 r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT_DEREF(s->service), JOB_REPLACE, true, &error, NULL);
1504 if (r < 0)
f976f3f6 1505 goto fail;
1a710b43 1506 }
4f2d528d
LP
1507
1508 socket_set_state(s, SOCKET_RUNNING);
1509 } else {
b4f10a5e 1510 char *prefix, *instance = NULL, *name;
b15bdda8 1511 Service *service;
4f2d528d 1512
6cf6bbc2 1513 if (s->n_connections >= s->max_connections) {
66870f90
ZJS
1514 log_warning_unit(UNIT(s)->id,
1515 "%s: Too many incoming connections (%u)",
1516 UNIT(s)->id, s->n_connections);
6cf6bbc2
LP
1517 close_nointr_nofail(cfd);
1518 return;
1519 }
1520
1a710b43
MS
1521 r = socket_instantiate_service(s);
1522 if (r < 0)
b15bdda8
LP
1523 goto fail;
1524
1a710b43
MS
1525 r = instance_from_socket(cfd, s->n_accepted, &instance);
1526 if (r < 0) {
1527 if (r != -ENOTCONN)
1528 goto fail;
1529
1530 /* ENOTCONN is legitimate if TCP RST was received.
1531 * This connection is over, but the socket unit lives on. */
1532 close_nointr_nofail(cfd);
1533 return;
1534 }
4f2d528d 1535
1a710b43
MS
1536 prefix = unit_name_to_prefix(UNIT(s)->id);
1537 if (!prefix) {
4f2d528d
LP
1538 free(instance);
1539 r = -ENOMEM;
1540 goto fail;
1541 }
1542
1543 name = unit_name_build(prefix, instance, ".service");
1544 free(prefix);
1545 free(instance);
1546
b6dbbe1c 1547 if (!name) {
4f2d528d 1548 r = -ENOMEM;
b6dbbe1c
LP
1549 goto fail;
1550 }
4f2d528d 1551
1a710b43
MS
1552 r = unit_add_name(UNIT_DEREF(s->service), name);
1553 if (r < 0) {
b15bdda8 1554 free(name);
4f2d528d 1555 goto fail;
b15bdda8
LP
1556 }
1557
57020a3a
LP
1558 service = SERVICE(UNIT_DEREF(s->service));
1559 unit_ref_unset(&s->service);
b15bdda8 1560 s->n_accepted ++;
4f2d528d 1561
1124fe6f 1562 UNIT(service)->no_gc = false;
6c073082 1563
b15bdda8
LP
1564 unit_choose_id(UNIT(service), name);
1565 free(name);
1566
1a710b43
MS
1567 r = service_set_socket_fd(service, cfd, s);
1568 if (r < 0)
4f2d528d
LP
1569 goto fail;
1570
1571 cfd = -1;
6cf6bbc2
LP
1572 s->n_connections ++;
1573
1a710b43
MS
1574 r = manager_add_job(UNIT(s)->manager, JOB_START, UNIT(service), JOB_REPLACE, true, &error, NULL);
1575 if (r < 0)
4f2d528d 1576 goto fail;
c4e2ceae
LP
1577
1578 /* Notify clients about changed counters */
1579 unit_add_to_dbus_queue(UNIT(s));
4f2d528d 1580 }
034c6ed7 1581
034c6ed7
LP
1582 return;
1583
1584fail:
66870f90
ZJS
1585 log_warning_unit(UNIT(s)->id,
1586 "%s failed to queue service startup job (Maybe the service file is missing or not a %s unit?): %s",
1587 UNIT(s)->id,
1588 cfd >= 0 ? "template" : "non-template",
1589 bus_error(&error, r));
60089004 1590 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
4f2d528d
LP
1591
1592 if (cfd >= 0)
1593 close_nointr_nofail(cfd);
398ef8ba
LP
1594
1595 dbus_error_free(&error);
034c6ed7
LP
1596}
1597
cfc4eb4c 1598static void socket_run_next(Socket *s) {
034c6ed7
LP
1599 int r;
1600
1601 assert(s);
1602 assert(s->control_command);
1603 assert(s->control_command->command_next);
1604
5e94833f
LP
1605 socket_unwatch_control_pid(s);
1606
034c6ed7
LP
1607 s->control_command = s->control_command->command_next;
1608
e537352b 1609 if ((r = socket_spawn(s, s->control_command, &s->control_pid)) < 0)
034c6ed7
LP
1610 goto fail;
1611
1612 return;
1613
1614fail:
66870f90
ZJS
1615 log_warning_unit(UNIT(s)->id,
1616 "%s failed to run next task: %s",
1617 UNIT(s)->id, strerror(-r));
80876c20
LP
1618
1619 if (s->state == SOCKET_START_POST)
cfc4eb4c 1620 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
034c6ed7 1621 else if (s->state == SOCKET_STOP_POST)
cfc4eb4c 1622 socket_enter_dead(s, SOCKET_FAILURE_RESOURCES);
034c6ed7 1623 else
cfc4eb4c 1624 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_RESOURCES);
034c6ed7
LP
1625}
1626
87f0e418
LP
1627static int socket_start(Unit *u) {
1628 Socket *s = SOCKET(u);
83c60c9f
LP
1629
1630 assert(s);
1631
034c6ed7
LP
1632 /* We cannot fulfill this request right now, try again later
1633 * please! */
1634 if (s->state == SOCKET_STOP_PRE ||
1635 s->state == SOCKET_STOP_PRE_SIGKILL ||
1636 s->state == SOCKET_STOP_PRE_SIGTERM ||
1637 s->state == SOCKET_STOP_POST ||
80876c20
LP
1638 s->state == SOCKET_FINAL_SIGTERM ||
1639 s->state == SOCKET_FINAL_SIGKILL)
034c6ed7
LP
1640 return -EAGAIN;
1641
83c60c9f
LP
1642 if (s->state == SOCKET_START_PRE ||
1643 s->state == SOCKET_START_POST)
034c6ed7 1644 return 0;
83c60c9f 1645
034c6ed7 1646 /* Cannot run this without the service being around */
9444b1f2 1647 if (UNIT_ISSET(s->service)) {
57020a3a
LP
1648 Service *service;
1649
1650 service = SERVICE(UNIT_DEREF(s->service));
1651
1124fe6f 1652 if (UNIT(service)->load_state != UNIT_LOADED) {
d7607eac 1653 log_error_unit(u->id,
66870f90
ZJS
1654 "Socket service %s not loaded, refusing.",
1655 UNIT(service)->id);
4f2d528d 1656 return -ENOENT;
4ac9236f 1657 }
4f2d528d 1658
35b8ca3a 1659 /* If the service is already active we cannot start the
4f2d528d 1660 * socket */
57020a3a
LP
1661 if (service->state != SERVICE_DEAD &&
1662 service->state != SERVICE_FAILED &&
1663 service->state != SERVICE_AUTO_RESTART) {
d7607eac 1664 log_error_unit(u->id,
66870f90
ZJS
1665 "Socket service %s already active, refusing.",
1666 UNIT(service)->id);
4f2d528d 1667 return -EBUSY;
4ac9236f 1668 }
7b4bf06b
LP
1669
1670#ifdef HAVE_SYSV_COMPAT
1b64d026 1671 if (service->is_sysv) {
d7607eac 1672 log_error_unit(u->id,
66870f90 1673 "Using SysV services for socket activation is not supported. Refusing.");
7b4bf06b
LP
1674 return -ENOENT;
1675 }
1676#endif
4f2d528d 1677 }
e537352b 1678
fdf20a31 1679 assert(s->state == SOCKET_DEAD || s->state == SOCKET_FAILED);
83c60c9f 1680
cfc4eb4c 1681 s->result = SOCKET_SUCCESS;
034c6ed7
LP
1682 socket_enter_start_pre(s);
1683 return 0;
1684}
83c60c9f 1685
87f0e418
LP
1686static int socket_stop(Unit *u) {
1687 Socket *s = SOCKET(u);
034c6ed7
LP
1688
1689 assert(s);
1690
e537352b
LP
1691 /* Already on it */
1692 if (s->state == SOCKET_STOP_PRE ||
1693 s->state == SOCKET_STOP_PRE_SIGTERM ||
1694 s->state == SOCKET_STOP_PRE_SIGKILL ||
1695 s->state == SOCKET_STOP_POST ||
80876c20 1696 s->state == SOCKET_FINAL_SIGTERM ||
3f6c78dc 1697 s->state == SOCKET_FINAL_SIGKILL)
e537352b
LP
1698 return 0;
1699
3f6c78dc
LP
1700 /* If there's already something running we go directly into
1701 * kill mode. */
1702 if (s->state == SOCKET_START_PRE ||
1703 s->state == SOCKET_START_POST) {
cfc4eb4c 1704 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_SUCCESS);
3f6c78dc
LP
1705 return -EAGAIN;
1706 }
1707
034c6ed7 1708 assert(s->state == SOCKET_LISTENING || s->state == SOCKET_RUNNING);
83c60c9f 1709
cfc4eb4c 1710 socket_enter_stop_pre(s, SOCKET_SUCCESS);
542563ba
LP
1711 return 0;
1712}
1713
a16e1123
LP
1714static int socket_serialize(Unit *u, FILE *f, FDSet *fds) {
1715 Socket *s = SOCKET(u);
1716 SocketPort *p;
1717 int r;
1718
1719 assert(u);
1720 assert(f);
1721 assert(fds);
1722
1723 unit_serialize_item(u, f, "state", socket_state_to_string(s->state));
cfc4eb4c 1724 unit_serialize_item(u, f, "result", socket_result_to_string(s->result));
a16e1123
LP
1725 unit_serialize_item_format(u, f, "n-accepted", "%u", s->n_accepted);
1726
1727 if (s->control_pid > 0)
5925dd3c 1728 unit_serialize_item_format(u, f, "control-pid", "%lu", (unsigned long) s->control_pid);
a16e1123
LP
1729
1730 if (s->control_command_id >= 0)
1731 unit_serialize_item(u, f, "control-command", socket_exec_command_to_string(s->control_command_id));
1732
1733 LIST_FOREACH(port, p, s->ports) {
1734 int copy;
1735
1736 if (p->fd < 0)
1737 continue;
1738
1739 if ((copy = fdset_put_dup(fds, p->fd)) < 0)
1740 return copy;
1741
1742 if (p->type == SOCKET_SOCKET) {
1743 char *t;
1744
ee092817
LP
1745 r = socket_address_print(&p->address, &t);
1746 if (r < 0)
a16e1123
LP
1747 return r;
1748
7a22745a
LP
1749 if (socket_address_family(&p->address) == AF_NETLINK)
1750 unit_serialize_item_format(u, f, "netlink", "%i %s", copy, t);
1751 else
1752 unit_serialize_item_format(u, f, "socket", "%i %i %s", copy, p->address.type, t);
a16e1123 1753 free(t);
b0a3f2bc
LP
1754 } else if (p->type == SOCKET_SPECIAL)
1755 unit_serialize_item_format(u, f, "special", "%i %s", copy, p->path);
ee092817
LP
1756 else if (p->type == SOCKET_MQUEUE)
1757 unit_serialize_item_format(u, f, "mqueue", "%i %s", copy, p->path);
b0a3f2bc 1758 else {
a16e1123
LP
1759 assert(p->type == SOCKET_FIFO);
1760 unit_serialize_item_format(u, f, "fifo", "%i %s", copy, p->path);
1761 }
1762 }
1763
c17ec25e
MS
1764 exec_context_serialize(&s->exec_context, UNIT(s), f);
1765
a16e1123
LP
1766 return 0;
1767}
1768
1769static int socket_deserialize_item(Unit *u, const char *key, const char *value, FDSet *fds) {
1770 Socket *s = SOCKET(u);
a16e1123
LP
1771
1772 assert(u);
1773 assert(key);
1774 assert(value);
1775 assert(fds);
1776
1777 if (streq(key, "state")) {
1778 SocketState state;
1779
ee092817
LP
1780 state = socket_state_from_string(value);
1781 if (state < 0)
66870f90
ZJS
1782 log_debug_unit(u->id,
1783 "Failed to parse state value %s", value);
a16e1123
LP
1784 else
1785 s->deserialized_state = state;
cfc4eb4c
LP
1786 } else if (streq(key, "result")) {
1787 SocketResult f;
a16e1123 1788
cfc4eb4c
LP
1789 f = socket_result_from_string(value);
1790 if (f < 0)
66870f90
ZJS
1791 log_debug_unit(u->id,
1792 "Failed to parse result value %s", value);
cfc4eb4c
LP
1793 else if (f != SOCKET_SUCCESS)
1794 s->result = f;
a16e1123
LP
1795
1796 } else if (streq(key, "n-accepted")) {
1797 unsigned k;
1798
e364ad06 1799 if (safe_atou(value, &k) < 0)
66870f90
ZJS
1800 log_debug_unit(u->id,
1801 "Failed to parse n-accepted value %s", value);
a16e1123
LP
1802 else
1803 s->n_accepted += k;
1804 } else if (streq(key, "control-pid")) {
5925dd3c 1805 pid_t pid;
a16e1123 1806
e364ad06 1807 if (parse_pid(value, &pid) < 0)
66870f90
ZJS
1808 log_debug_unit(u->id,
1809 "Failed to parse control-pid value %s", value);
a16e1123 1810 else
5925dd3c 1811 s->control_pid = pid;
a16e1123
LP
1812 } else if (streq(key, "control-command")) {
1813 SocketExecCommand id;
1814
66870f90
ZJS
1815 id = socket_exec_command_from_string(value);
1816 if (id < 0)
1817 log_debug_unit(u->id,
1818 "Failed to parse exec-command value %s", value);
a16e1123
LP
1819 else {
1820 s->control_command_id = id;
1821 s->control_command = s->exec_command[id];
1822 }
1823 } else if (streq(key, "fifo")) {
1824 int fd, skip = 0;
1825 SocketPort *p;
1826
1827 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1828 log_debug_unit(u->id,
1829 "Failed to parse fifo value %s", value);
a16e1123
LP
1830 else {
1831
1832 LIST_FOREACH(port, p, s->ports)
b0a3f2bc
LP
1833 if (p->type == SOCKET_FIFO &&
1834 streq_ptr(p->path, value+skip))
1835 break;
1836
1837 if (p) {
1838 if (p->fd >= 0)
1839 close_nointr_nofail(p->fd);
1840 p->fd = fdset_remove(fds, fd);
1841 }
1842 }
1843
1844 } else if (streq(key, "special")) {
1845 int fd, skip = 0;
1846 SocketPort *p;
1847
1848 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1849 log_debug_unit(u->id,
1850 "Failed to parse special value %s", value);
b0a3f2bc
LP
1851 else {
1852
1853 LIST_FOREACH(port, p, s->ports)
1854 if (p->type == SOCKET_SPECIAL &&
1855 streq_ptr(p->path, value+skip))
a16e1123
LP
1856 break;
1857
1858 if (p) {
1859 if (p->fd >= 0)
1860 close_nointr_nofail(p->fd);
1861 p->fd = fdset_remove(fds, fd);
1862 }
1863 }
1864
ee092817
LP
1865 } else if (streq(key, "mqueue")) {
1866 int fd, skip = 0;
1867 SocketPort *p;
1868
1869 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1870 log_debug_unit(u->id,
1871 "Failed to parse mqueue value %s", value);
ee092817
LP
1872 else {
1873
1874 LIST_FOREACH(port, p, s->ports)
1875 if (p->type == SOCKET_MQUEUE &&
1876 streq_ptr(p->path, value+skip))
1877 break;
1878
1879 if (p) {
1880 if (p->fd >= 0)
1881 close_nointr_nofail(p->fd);
1882 p->fd = fdset_remove(fds, fd);
1883 }
1884 }
1885
a16e1123 1886 } else if (streq(key, "socket")) {
27ca8d7a 1887 int fd, type, skip = 0;
a16e1123
LP
1888 SocketPort *p;
1889
27ca8d7a 1890 if (sscanf(value, "%i %i %n", &fd, &type, &skip) < 2 || fd < 0 || type < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1891 log_debug_unit(u->id,
1892 "Failed to parse socket value %s", value);
a16e1123
LP
1893 else {
1894
1895 LIST_FOREACH(port, p, s->ports)
27ca8d7a 1896 if (socket_address_is(&p->address, value+skip, type))
a16e1123
LP
1897 break;
1898
1899 if (p) {
1900 if (p->fd >= 0)
1901 close_nointr_nofail(p->fd);
1902 p->fd = fdset_remove(fds, fd);
1903 }
1904 }
1905
7a22745a
LP
1906 } else if (streq(key, "netlink")) {
1907 int fd, skip = 0;
1908 SocketPort *p;
1909
1910 if (sscanf(value, "%i %n", &fd, &skip) < 1 || fd < 0 || !fdset_contains(fds, fd))
66870f90
ZJS
1911 log_debug_unit(u->id,
1912 "Failed to parse socket value %s", value);
7a22745a
LP
1913 else {
1914
1915 LIST_FOREACH(port, p, s->ports)
1916 if (socket_address_is_netlink(&p->address, value+skip))
1917 break;
1918
1919 if (p) {
1920 if (p->fd >= 0)
1921 close_nointr_nofail(p->fd);
1922 p->fd = fdset_remove(fds, fd);
1923 }
1924 }
c17ec25e
MS
1925 } else if (streq(key, "tmp-dir")) {
1926 char *t;
1927
1928 t = strdup(value);
1929 if (!t)
1930 return log_oom();
1931
1932 s->exec_context.tmp_dir = t;
1933 } else if (streq(key, "var-tmp-dir")) {
1934 char *t;
1935
1936 t = strdup(value);
1937 if (!t)
1938 return log_oom();
7a22745a 1939
c17ec25e 1940 s->exec_context.var_tmp_dir = t;
a16e1123 1941 } else
66870f90
ZJS
1942 log_debug_unit(UNIT(s)->id,
1943 "Unknown serialization key '%s'", key);
a16e1123
LP
1944
1945 return 0;
1946}
1947
01e10de3
LP
1948static int socket_distribute_fds(Unit *u, FDSet *fds) {
1949 Socket *s = SOCKET(u);
1950 SocketPort *p;
1951
1952 assert(u);
1953
1954 LIST_FOREACH(port, p, s->ports) {
1955 Iterator i;
1956 int fd;
1957
1958 if (p->type != SOCKET_SOCKET)
1959 continue;
1960
1961 if (p->fd >= 0)
1962 continue;
1963
1964 FDSET_FOREACH(fd, fds, i) {
1965 if (socket_address_matches_fd(&p->address, fd)) {
1966 p->fd = fdset_remove(fds, fd);
1967 s->deserialized_state = SOCKET_LISTENING;
1968 break;
1969 }
1970 }
1971 }
1972
1973 return 0;
1974}
1975
44a6b1b6 1976_pure_ static UnitActiveState socket_active_state(Unit *u) {
87f0e418 1977 assert(u);
5cb5a6ff 1978
acbb0225 1979 return state_translation_table[SOCKET(u)->state];
5cb5a6ff
LP
1980}
1981
44a6b1b6 1982_pure_ static const char *socket_sub_state_to_string(Unit *u) {
10a94420
LP
1983 assert(u);
1984
a16e1123 1985 return socket_state_to_string(SOCKET(u)->state);
10a94420
LP
1986}
1987
67419600
OS
1988const char* socket_port_type_to_string(SocketPort *p) {
1989
1990 assert(p);
1991
1992 switch (p->type) {
1993 case SOCKET_SOCKET:
1994 switch (p->address.type) {
1995 case SOCK_STREAM: return "Stream";
1996 case SOCK_DGRAM: return "Datagram";
1997 case SOCK_SEQPACKET: return "SequentialPacket";
1998 case SOCK_RAW:
1999 if (socket_address_family(&p->address) == AF_NETLINK)
2000 return "Netlink";
2001 default: return "Invalid";
2002 }
2003 case SOCKET_SPECIAL: return "Special";
2004 case SOCKET_MQUEUE: return "MessageQueue";
2005 case SOCKET_FIFO: return "FIFO";
2006 default: return NULL;
2007 }
2008}
2009
44a6b1b6 2010_pure_ static bool socket_check_gc(Unit *u) {
6cf6bbc2
LP
2011 Socket *s = SOCKET(u);
2012
2013 assert(u);
2014
2015 return s->n_connections > 0;
2016}
2017
acbb0225 2018static void socket_fd_event(Unit *u, int fd, uint32_t events, Watch *w) {
87f0e418 2019 Socket *s = SOCKET(u);
4f2d528d 2020 int cfd = -1;
9152c765 2021
034c6ed7 2022 assert(s);
8d567588 2023 assert(fd >= 0);
9152c765 2024
871d7de4
LP
2025 if (s->state != SOCKET_LISTENING)
2026 return;
2027
66870f90 2028 log_debug_unit(u->id, "Incoming traffic on %s", u->id);
9152c765 2029
4f2d528d 2030 if (events != EPOLLIN) {
641e01dc
LP
2031
2032 if (events & EPOLLHUP)
66870f90
ZJS
2033 log_error_unit(u->id,
2034 "%s: Got POLLHUP on a listening socket. The service probably invoked shutdown() on it, and should better not do that.",
2035 u->id);
641e01dc 2036 else
66870f90
ZJS
2037 log_error_unit(u->id,
2038 "%s: Got unexpected poll event (0x%x) on socket.",
2039 u->id, events);
641e01dc 2040
8d567588 2041 goto fail;
4f2d528d
LP
2042 }
2043
cabab516 2044 if (w->socket_accept) {
4f2d528d
LP
2045 for (;;) {
2046
b14eda96
LP
2047 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK);
2048 if (cfd < 0) {
4f2d528d
LP
2049
2050 if (errno == EINTR)
2051 continue;
2052
66870f90
ZJS
2053 log_error_unit(u->id,
2054 "Failed to accept socket: %m");
8d567588 2055 goto fail;
4f2d528d
LP
2056 }
2057
2058 break;
2059 }
4fd5948e
LP
2060
2061 socket_apply_socket_options(s, cfd);
4f2d528d 2062 }
9152c765 2063
4f2d528d 2064 socket_enter_running(s, cfd);
8d567588
LP
2065 return;
2066
2067fail:
cfc4eb4c 2068 socket_enter_stop_pre(s, SOCKET_FAILURE_RESOURCES);
9152c765
LP
2069}
2070
87f0e418
LP
2071static void socket_sigchld_event(Unit *u, pid_t pid, int code, int status) {
2072 Socket *s = SOCKET(u);
cfc4eb4c 2073 SocketResult f;
5cb5a6ff
LP
2074
2075 assert(s);
034c6ed7 2076 assert(pid >= 0);
5cb5a6ff 2077
8c47c732
LP
2078 if (pid != s->control_pid)
2079 return;
542563ba 2080
034c6ed7
LP
2081 s->control_pid = 0;
2082
96342de6 2083 if (is_clean_exit(code, status, NULL))
cfc4eb4c
LP
2084 f = SOCKET_SUCCESS;
2085 else if (code == CLD_EXITED)
2086 f = SOCKET_FAILURE_EXIT_CODE;
2087 else if (code == CLD_KILLED)
2088 f = SOCKET_FAILURE_SIGNAL;
2089 else if (code == CLD_DUMPED)
2090 f = SOCKET_FAILURE_CORE_DUMP;
2091 else
2092 assert_not_reached("Unknown code");
8c47c732 2093
b708e7ce 2094 if (s->control_command) {
6ea832a2 2095 exec_status_exit(&s->control_command->exec_status, &s->exec_context, pid, code, status);
a16e1123 2096
b708e7ce 2097 if (s->control_command->ignore)
cfc4eb4c 2098 f = SOCKET_SUCCESS;
b708e7ce
LP
2099 }
2100
66870f90
ZJS
2101 log_full_unit(f == SOCKET_SUCCESS ? LOG_DEBUG : LOG_NOTICE,
2102 u->id,
2103 "%s control process exited, code=%s status=%i",
2104 u->id, sigchld_code_to_string(code), status);
034c6ed7 2105
cfc4eb4c
LP
2106 if (f != SOCKET_SUCCESS)
2107 s->result = f;
2108
2109 if (s->control_command &&
2110 s->control_command->command_next &&
2111 f == SOCKET_SUCCESS) {
2112
66870f90
ZJS
2113 log_debug_unit(u->id,
2114 "%s running next command for state %s",
2115 u->id, socket_state_to_string(s->state));
cfc4eb4c 2116 socket_run_next(s);
acbb0225 2117 } else {
a16e1123
LP
2118 s->control_command = NULL;
2119 s->control_command_id = _SOCKET_EXEC_COMMAND_INVALID;
2120
034c6ed7
LP
2121 /* No further commands for this step, so let's figure
2122 * out what to do next */
5cb5a6ff 2123
66870f90
ZJS
2124 log_debug_unit(u->id,
2125 "%s got final SIGCHLD for state %s",
2126 u->id, socket_state_to_string(s->state));
acbb0225 2127
034c6ed7
LP
2128 switch (s->state) {
2129
2130 case SOCKET_START_PRE:
cfc4eb4c 2131 if (f == SOCKET_SUCCESS)
acbb0225 2132 socket_enter_start_post(s);
034c6ed7 2133 else
cfc4eb4c 2134 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, f);
034c6ed7
LP
2135 break;
2136
2137 case SOCKET_START_POST:
cfc4eb4c 2138 if (f == SOCKET_SUCCESS)
e9af15c3 2139 socket_enter_listening(s);
034c6ed7 2140 else
cfc4eb4c 2141 socket_enter_stop_pre(s, f);
034c6ed7
LP
2142 break;
2143
2144 case SOCKET_STOP_PRE:
2145 case SOCKET_STOP_PRE_SIGTERM:
2146 case SOCKET_STOP_PRE_SIGKILL:
cfc4eb4c 2147 socket_enter_stop_post(s, f);
034c6ed7
LP
2148 break;
2149
2150 case SOCKET_STOP_POST:
80876c20
LP
2151 case SOCKET_FINAL_SIGTERM:
2152 case SOCKET_FINAL_SIGKILL:
cfc4eb4c 2153 socket_enter_dead(s, f);
034c6ed7
LP
2154 break;
2155
2156 default:
2157 assert_not_reached("Uh, control process died at wrong time.");
2158 }
2159 }
c4e2ceae
LP
2160
2161 /* Notify clients about changed exit status */
2162 unit_add_to_dbus_queue(u);
034c6ed7 2163}
5cb5a6ff 2164
acbb0225 2165static void socket_timer_event(Unit *u, uint64_t elapsed, Watch *w) {
87f0e418 2166 Socket *s = SOCKET(u);
5cb5a6ff 2167
034c6ed7
LP
2168 assert(s);
2169 assert(elapsed == 1);
acbb0225 2170 assert(w == &s->timer_watch);
034c6ed7
LP
2171
2172 switch (s->state) {
2173
2174 case SOCKET_START_PRE:
66870f90
ZJS
2175 log_warning_unit(u->id,
2176 "%s starting timed out. Terminating.", u->id);
cfc4eb4c 2177 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
da19d5c1 2178 break;
80876c20 2179
034c6ed7 2180 case SOCKET_START_POST:
66870f90
ZJS
2181 log_warning_unit(u->id,
2182 "%s starting timed out. Stopping.", u->id);
cfc4eb4c 2183 socket_enter_stop_pre(s, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2184 break;
2185
2186 case SOCKET_STOP_PRE:
66870f90
ZJS
2187 log_warning_unit(u->id,
2188 "%s stopping timed out. Terminating.", u->id);
cfc4eb4c 2189 socket_enter_signal(s, SOCKET_STOP_PRE_SIGTERM, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2190 break;
2191
2192 case SOCKET_STOP_PRE_SIGTERM:
4819ff03 2193 if (s->kill_context.send_sigkill) {
66870f90
ZJS
2194 log_warning_unit(u->id,
2195 "%s stopping timed out. Killing.", u->id);
cfc4eb4c 2196 socket_enter_signal(s, SOCKET_STOP_PRE_SIGKILL, SOCKET_FAILURE_TIMEOUT);
ba035df2 2197 } else {
66870f90
ZJS
2198 log_warning_unit(u->id,
2199 "%s stopping timed out. Skipping SIGKILL. Ignoring.",
2200 u->id);
cfc4eb4c 2201 socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
ba035df2 2202 }
034c6ed7
LP
2203 break;
2204
2205 case SOCKET_STOP_PRE_SIGKILL:
66870f90
ZJS
2206 log_warning_unit(u->id,
2207 "%s still around after SIGKILL. Ignoring.", u->id);
cfc4eb4c 2208 socket_enter_stop_post(s, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2209 break;
2210
2211 case SOCKET_STOP_POST:
66870f90
ZJS
2212 log_warning_unit(u->id,
2213 "%s stopping timed out (2). Terminating.", u->id);
cfc4eb4c 2214 socket_enter_signal(s, SOCKET_FINAL_SIGTERM, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2215 break;
2216
80876c20 2217 case SOCKET_FINAL_SIGTERM:
4819ff03 2218 if (s->kill_context.send_sigkill) {
66870f90
ZJS
2219 log_warning_unit(u->id,
2220 "%s stopping timed out (2). Killing.", u->id);
cfc4eb4c 2221 socket_enter_signal(s, SOCKET_FINAL_SIGKILL, SOCKET_FAILURE_TIMEOUT);
ba035df2 2222 } else {
66870f90
ZJS
2223 log_warning_unit(u->id,
2224 "%s stopping timed out (2). Skipping SIGKILL. Ignoring.",
2225 u->id);
cfc4eb4c 2226 socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
ba035df2 2227 }
034c6ed7
LP
2228 break;
2229
80876c20 2230 case SOCKET_FINAL_SIGKILL:
66870f90
ZJS
2231 log_warning_unit(u->id,
2232 "%s still around after SIGKILL (2). Entering failed mode.",
2233 u->id);
cfc4eb4c 2234 socket_enter_dead(s, SOCKET_FAILURE_TIMEOUT);
034c6ed7
LP
2235 break;
2236
2237 default:
2238 assert_not_reached("Timeout at wrong time.");
2239 }
5cb5a6ff
LP
2240}
2241
44d8db9e
LP
2242int socket_collect_fds(Socket *s, int **fds, unsigned *n_fds) {
2243 int *rfds;
2244 unsigned rn_fds, k;
2245 SocketPort *p;
2246
2247 assert(s);
2248 assert(fds);
2249 assert(n_fds);
2250
2251 /* Called from the service code for requesting our fds */
2252
2253 rn_fds = 0;
2254 LIST_FOREACH(port, p, s->ports)
2255 if (p->fd >= 0)
2256 rn_fds++;
2257
de3756ab
LP
2258 if (rn_fds <= 0) {
2259 *fds = NULL;
2260 *n_fds = 0;
2261 return 0;
2262 }
2263
e364ad06 2264 if (!(rfds = new(int, rn_fds)))
44d8db9e
LP
2265 return -ENOMEM;
2266
2267 k = 0;
2268 LIST_FOREACH(port, p, s->ports)
2269 if (p->fd >= 0)
2270 rfds[k++] = p->fd;
2271
2272 assert(k == rn_fds);
2273
2274 *fds = rfds;
2275 *n_fds = rn_fds;
2276
2277 return 0;
2278}
2279
d137a488 2280static void socket_notify_service_dead(Socket *s, bool failed_permanent) {
ceee3d82
LP
2281 assert(s);
2282
6cf6bbc2
LP
2283 /* The service is dead. Dang!
2284 *
2285 * This is strictly for one-instance-for-all-connections
2286 * services. */
ceee3d82
LP
2287
2288 if (s->state == SOCKET_RUNNING) {
66870f90
ZJS
2289 log_debug_unit(UNIT(s)->id,
2290 "%s got notified about service death (failed permanently: %s)",
2291 UNIT(s)->id, yes_no(failed_permanent));
6bda96a0
LP
2292 if (failed_permanent)
2293 socket_enter_stop_pre(s, SOCKET_FAILURE_SERVICE_FAILED_PERMANENT);
c2f34808
MS
2294 else
2295 socket_enter_listening(s);
ceee3d82
LP
2296 }
2297}
2298
6cf6bbc2
LP
2299void socket_connection_unref(Socket *s) {
2300 assert(s);
2301
2302 /* The service is dead. Yay!
2303 *
35b8ca3a 2304 * This is strictly for one-instance-per-connection
6cf6bbc2
LP
2305 * services. */
2306
2307 assert(s->n_connections > 0);
2308 s->n_connections--;
2309
66870f90
ZJS
2310 log_debug_unit(UNIT(s)->id,
2311 "%s: One connection closed, %u left.", UNIT(s)->id, s->n_connections);
6cf6bbc2
LP
2312}
2313
fdf20a31 2314static void socket_reset_failed(Unit *u) {
5632e374
LP
2315 Socket *s = SOCKET(u);
2316
2317 assert(s);
2318
fdf20a31 2319 if (s->state == SOCKET_FAILED)
5632e374
LP
2320 socket_set_state(s, SOCKET_DEAD);
2321
cfc4eb4c 2322 s->result = SOCKET_SUCCESS;
5632e374
LP
2323}
2324
d137a488
UTL
2325static void socket_trigger_notify(Unit *u, Unit *other) {
2326 Socket *s = SOCKET(u);
2327 Service *se = SERVICE(other);
2328
2329 assert(u);
2330 assert(other);
2331
2332 /* Don't propagate state changes from the service if we are
2333 already down or accepting connections */
2334 if ((s->state != SOCKET_RUNNING &&
2335 s->state != SOCKET_LISTENING) ||
2336 s->accept)
2337 return;
2338
2339 if (other->load_state != UNIT_LOADED ||
2340 other->type != UNIT_SERVICE)
2341 return;
2342
2343 if (se->state == SERVICE_FAILED)
2344 socket_notify_service_dead(s, se->result == SERVICE_FAILURE_START_LIMIT);
2345
2346 if (se->state == SERVICE_DEAD ||
2347 se->state == SERVICE_STOP ||
2348 se->state == SERVICE_STOP_SIGTERM ||
2349 se->state == SERVICE_STOP_SIGKILL ||
2350 se->state == SERVICE_STOP_POST ||
2351 se->state == SERVICE_FINAL_SIGTERM ||
2352 se->state == SERVICE_FINAL_SIGKILL ||
2353 se->state == SERVICE_AUTO_RESTART)
2354 socket_notify_service_dead(s, false);
2355
2356 if (se->state == SERVICE_RUNNING)
2357 socket_set_state(s, SOCKET_RUNNING);
2358}
2359
c74f17d9 2360static int socket_kill(Unit *u, KillWho who, int signo, DBusError *error) {
814cc562 2361 return unit_kill_common(u, who, signo, -1, SOCKET(u)->control_pid, error);
8a0867d6
LP
2362}
2363
a16e1123
LP
2364static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
2365 [SOCKET_DEAD] = "dead",
2366 [SOCKET_START_PRE] = "start-pre",
2367 [SOCKET_START_POST] = "start-post",
2368 [SOCKET_LISTENING] = "listening",
2369 [SOCKET_RUNNING] = "running",
2370 [SOCKET_STOP_PRE] = "stop-pre",
2371 [SOCKET_STOP_PRE_SIGTERM] = "stop-pre-sigterm",
2372 [SOCKET_STOP_PRE_SIGKILL] = "stop-pre-sigkill",
2373 [SOCKET_STOP_POST] = "stop-post",
2374 [SOCKET_FINAL_SIGTERM] = "final-sigterm",
2375 [SOCKET_FINAL_SIGKILL] = "final-sigkill",
fdf20a31 2376 [SOCKET_FAILED] = "failed"
a16e1123
LP
2377};
2378
2379DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
2380
2381static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
2382 [SOCKET_EXEC_START_PRE] = "StartPre",
2383 [SOCKET_EXEC_START_POST] = "StartPost",
2384 [SOCKET_EXEC_STOP_PRE] = "StopPre",
2385 [SOCKET_EXEC_STOP_POST] = "StopPost"
2386};
2387
2388DEFINE_STRING_TABLE_LOOKUP(socket_exec_command, SocketExecCommand);
2389
cfc4eb4c
LP
2390static const char* const socket_result_table[_SOCKET_RESULT_MAX] = {
2391 [SOCKET_SUCCESS] = "success",
2392 [SOCKET_FAILURE_RESOURCES] = "resources",
2393 [SOCKET_FAILURE_TIMEOUT] = "timeout",
2394 [SOCKET_FAILURE_EXIT_CODE] = "exit-code",
2395 [SOCKET_FAILURE_SIGNAL] = "signal",
c2f34808 2396 [SOCKET_FAILURE_CORE_DUMP] = "core-dump",
6bda96a0 2397 [SOCKET_FAILURE_SERVICE_FAILED_PERMANENT] = "service-failed-permanent"
cfc4eb4c
LP
2398};
2399
2400DEFINE_STRING_TABLE_LOOKUP(socket_result, SocketResult);
2401
87f0e418 2402const UnitVTable socket_vtable = {
7d17cfbc 2403 .object_size = sizeof(Socket),
3ef63c31 2404
f975e971
LP
2405 .sections =
2406 "Unit\0"
2407 "Socket\0"
2408 "Install\0",
5cb5a6ff 2409
4ad49000 2410 .private_section = "Socket",
71645aca 2411 .exec_context_offset = offsetof(Socket, exec_context),
4ad49000 2412 .cgroup_context_offset = offsetof(Socket, cgroup_context),
71645aca 2413
034c6ed7
LP
2414 .init = socket_init,
2415 .done = socket_done,
a16e1123
LP
2416 .load = socket_load,
2417
8a0867d6
LP
2418 .kill = socket_kill,
2419
a16e1123 2420 .coldplug = socket_coldplug,
034c6ed7 2421
5cb5a6ff
LP
2422 .dump = socket_dump,
2423
542563ba
LP
2424 .start = socket_start,
2425 .stop = socket_stop,
5cb5a6ff 2426
a16e1123
LP
2427 .serialize = socket_serialize,
2428 .deserialize_item = socket_deserialize_item,
01e10de3 2429 .distribute_fds = socket_distribute_fds,
a16e1123 2430
5cb5a6ff 2431 .active_state = socket_active_state,
10a94420 2432 .sub_state_to_string = socket_sub_state_to_string,
5cb5a6ff 2433
6cf6bbc2
LP
2434 .check_gc = socket_check_gc,
2435
9152c765 2436 .fd_event = socket_fd_event,
034c6ed7 2437 .sigchld_event = socket_sigchld_event,
4139c1b2
LP
2438 .timer_event = socket_timer_event,
2439
d137a488
UTL
2440 .trigger_notify = socket_trigger_notify,
2441
fdf20a31 2442 .reset_failed = socket_reset_failed,
5632e374 2443
c4e2ceae
LP
2444 .bus_interface = "org.freedesktop.systemd1.Socket",
2445 .bus_message_handler = bus_socket_message_handler,
c6918296 2446 .bus_invalidating_properties = bus_socket_invalidating_properties,
74c964d3
LP
2447 .bus_set_property = bus_socket_set_property,
2448 .bus_commit_properties = bus_socket_commit_properties,
c6918296
MS
2449
2450 .status_message_formats = {
2451 /*.starting_stopping = {
2452 [0] = "Starting socket %s...",
2453 [1] = "Stopping socket %s...",
2454 },*/
2455 .finished_start_job = {
2456 [JOB_DONE] = "Listening on %s.",
2457 [JOB_FAILED] = "Failed to listen on %s.",
2458 [JOB_DEPENDENCY] = "Dependency failed for %s.",
2459 [JOB_TIMEOUT] = "Timed out starting %s.",
2460 },
2461 .finished_stop_job = {
2462 [JOB_DONE] = "Closed %s.",
2463 [JOB_FAILED] = "Failed stopping %s.",
2464 [JOB_TIMEOUT] = "Timed out stopping %s.",
2465 },
2466 },
5cb5a6ff 2467};