]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/basic/socket-util.c
Merge pull request #4618 from grawity/signal-direction
[thirdparty/systemd.git] / src / basic / socket-util.c
1 /***
2 This file is part of systemd.
3
4 Copyright 2010 Lennart Poettering
5
6 systemd is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License as published by
8 the Free Software Foundation; either version 2.1 of the License, or
9 (at your option) any later version.
10
11 systemd is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with systemd; If not, see <http://www.gnu.org/licenses/>.
18 ***/
19
20 #include <arpa/inet.h>
21 #include <errno.h>
22 #include <limits.h>
23 #include <net/if.h>
24 #include <netdb.h>
25 #include <netinet/ip.h>
26 #include <poll.h>
27 #include <stddef.h>
28 #include <stdint.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <string.h>
32 #include <unistd.h>
33
34 #include "alloc-util.h"
35 #include "fd-util.h"
36 #include "fileio.h"
37 #include "format-util.h"
38 #include "log.h"
39 #include "macro.h"
40 #include "missing.h"
41 #include "parse-util.h"
42 #include "path-util.h"
43 #include "socket-util.h"
44 #include "string-table.h"
45 #include "string-util.h"
46 #include "strv.h"
47 #include "user-util.h"
48 #include "utf8.h"
49 #include "util.h"
50
51 int socket_address_parse(SocketAddress *a, const char *s) {
52 char *e, *n;
53 unsigned u;
54 int r;
55
56 assert(a);
57 assert(s);
58
59 zero(*a);
60 a->type = SOCK_STREAM;
61
62 if (*s == '[') {
63 /* IPv6 in [x:.....:z]:p notation */
64
65 e = strchr(s+1, ']');
66 if (!e)
67 return -EINVAL;
68
69 n = strndupa(s+1, e-s-1);
70
71 errno = 0;
72 if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
73 return errno > 0 ? -errno : -EINVAL;
74
75 e++;
76 if (*e != ':')
77 return -EINVAL;
78
79 e++;
80 r = safe_atou(e, &u);
81 if (r < 0)
82 return r;
83
84 if (u <= 0 || u > 0xFFFF)
85 return -EINVAL;
86
87 a->sockaddr.in6.sin6_family = AF_INET6;
88 a->sockaddr.in6.sin6_port = htobe16((uint16_t)u);
89 a->size = sizeof(struct sockaddr_in6);
90
91 } else if (*s == '/') {
92 /* AF_UNIX socket */
93
94 size_t l;
95
96 l = strlen(s);
97 if (l >= sizeof(a->sockaddr.un.sun_path))
98 return -EINVAL;
99
100 a->sockaddr.un.sun_family = AF_UNIX;
101 memcpy(a->sockaddr.un.sun_path, s, l);
102 a->size = offsetof(struct sockaddr_un, sun_path) + l + 1;
103
104 } else if (*s == '@') {
105 /* Abstract AF_UNIX socket */
106 size_t l;
107
108 l = strlen(s+1);
109 if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
110 return -EINVAL;
111
112 a->sockaddr.un.sun_family = AF_UNIX;
113 memcpy(a->sockaddr.un.sun_path+1, s+1, l);
114 a->size = offsetof(struct sockaddr_un, sun_path) + 1 + l;
115
116 } else {
117 e = strchr(s, ':');
118 if (e) {
119 r = safe_atou(e+1, &u);
120 if (r < 0)
121 return r;
122
123 if (u <= 0 || u > 0xFFFF)
124 return -EINVAL;
125
126 n = strndupa(s, e-s);
127
128 /* IPv4 in w.x.y.z:p notation? */
129 r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
130 if (r < 0)
131 return -errno;
132
133 if (r > 0) {
134 /* Gotcha, it's a traditional IPv4 address */
135 a->sockaddr.in.sin_family = AF_INET;
136 a->sockaddr.in.sin_port = htobe16((uint16_t)u);
137 a->size = sizeof(struct sockaddr_in);
138 } else {
139 unsigned idx;
140
141 if (strlen(n) > IF_NAMESIZE-1)
142 return -EINVAL;
143
144 /* Uh, our last resort, an interface name */
145 idx = if_nametoindex(n);
146 if (idx == 0)
147 return -EINVAL;
148
149 a->sockaddr.in6.sin6_family = AF_INET6;
150 a->sockaddr.in6.sin6_port = htobe16((uint16_t)u);
151 a->sockaddr.in6.sin6_scope_id = idx;
152 a->sockaddr.in6.sin6_addr = in6addr_any;
153 a->size = sizeof(struct sockaddr_in6);
154 }
155 } else {
156
157 /* Just a port */
158 r = safe_atou(s, &u);
159 if (r < 0)
160 return r;
161
162 if (u <= 0 || u > 0xFFFF)
163 return -EINVAL;
164
165 if (socket_ipv6_is_supported()) {
166 a->sockaddr.in6.sin6_family = AF_INET6;
167 a->sockaddr.in6.sin6_port = htobe16((uint16_t)u);
168 a->sockaddr.in6.sin6_addr = in6addr_any;
169 a->size = sizeof(struct sockaddr_in6);
170 } else {
171 a->sockaddr.in.sin_family = AF_INET;
172 a->sockaddr.in.sin_port = htobe16((uint16_t)u);
173 a->sockaddr.in.sin_addr.s_addr = INADDR_ANY;
174 a->size = sizeof(struct sockaddr_in);
175 }
176 }
177 }
178
179 return 0;
180 }
181
182 int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
183 SocketAddress b;
184 int r;
185
186 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
187
188 r = socket_address_parse(&b, s);
189 if (r < 0)
190 return r;
191
192 if (!socket_ipv6_is_supported() && b.sockaddr.sa.sa_family == AF_INET6) {
193 log_warning("Binding to IPv6 address not available since kernel does not support IPv6.");
194 return -EAFNOSUPPORT;
195 }
196
197 *a = b;
198 return 0;
199 }
200
201 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
202 int family;
203 unsigned group = 0;
204 _cleanup_free_ char *sfamily = NULL;
205 assert(a);
206 assert(s);
207
208 zero(*a);
209 a->type = SOCK_RAW;
210
211 errno = 0;
212 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
213 return errno > 0 ? -errno : -EINVAL;
214
215 family = netlink_family_from_string(sfamily);
216 if (family < 0)
217 return -EINVAL;
218
219 a->sockaddr.nl.nl_family = AF_NETLINK;
220 a->sockaddr.nl.nl_groups = group;
221
222 a->type = SOCK_RAW;
223 a->size = sizeof(struct sockaddr_nl);
224 a->protocol = family;
225
226 return 0;
227 }
228
229 int socket_address_verify(const SocketAddress *a) {
230 assert(a);
231
232 switch (socket_address_family(a)) {
233
234 case AF_INET:
235 if (a->size != sizeof(struct sockaddr_in))
236 return -EINVAL;
237
238 if (a->sockaddr.in.sin_port == 0)
239 return -EINVAL;
240
241 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
242 return -EINVAL;
243
244 return 0;
245
246 case AF_INET6:
247 if (a->size != sizeof(struct sockaddr_in6))
248 return -EINVAL;
249
250 if (a->sockaddr.in6.sin6_port == 0)
251 return -EINVAL;
252
253 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM)
254 return -EINVAL;
255
256 return 0;
257
258 case AF_UNIX:
259 if (a->size < offsetof(struct sockaddr_un, sun_path))
260 return -EINVAL;
261
262 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
263
264 if (a->sockaddr.un.sun_path[0] != 0) {
265 char *e;
266
267 /* path */
268 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
269 if (!e)
270 return -EINVAL;
271
272 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
273 return -EINVAL;
274 }
275 }
276
277 if (a->type != SOCK_STREAM && a->type != SOCK_DGRAM && a->type != SOCK_SEQPACKET)
278 return -EINVAL;
279
280 return 0;
281
282 case AF_NETLINK:
283
284 if (a->size != sizeof(struct sockaddr_nl))
285 return -EINVAL;
286
287 if (a->type != SOCK_RAW && a->type != SOCK_DGRAM)
288 return -EINVAL;
289
290 return 0;
291
292 default:
293 return -EAFNOSUPPORT;
294 }
295 }
296
297 int socket_address_print(const SocketAddress *a, char **ret) {
298 int r;
299
300 assert(a);
301 assert(ret);
302
303 r = socket_address_verify(a);
304 if (r < 0)
305 return r;
306
307 if (socket_address_family(a) == AF_NETLINK) {
308 _cleanup_free_ char *sfamily = NULL;
309
310 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
311 if (r < 0)
312 return r;
313
314 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
315 if (r < 0)
316 return -ENOMEM;
317
318 return 0;
319 }
320
321 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
322 }
323
324 bool socket_address_can_accept(const SocketAddress *a) {
325 assert(a);
326
327 return
328 a->type == SOCK_STREAM ||
329 a->type == SOCK_SEQPACKET;
330 }
331
332 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
333 assert(a);
334 assert(b);
335
336 /* Invalid addresses are unequal to all */
337 if (socket_address_verify(a) < 0 ||
338 socket_address_verify(b) < 0)
339 return false;
340
341 if (a->type != b->type)
342 return false;
343
344 if (socket_address_family(a) != socket_address_family(b))
345 return false;
346
347 switch (socket_address_family(a)) {
348
349 case AF_INET:
350 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
351 return false;
352
353 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
354 return false;
355
356 break;
357
358 case AF_INET6:
359 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
360 return false;
361
362 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
363 return false;
364
365 break;
366
367 case AF_UNIX:
368 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
369 b->size <= offsetof(struct sockaddr_un, sun_path))
370 return false;
371
372 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
373 return false;
374
375 if (a->sockaddr.un.sun_path[0]) {
376 if (!path_equal_or_files_same(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path))
377 return false;
378 } else {
379 if (a->size != b->size)
380 return false;
381
382 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
383 return false;
384 }
385
386 break;
387
388 case AF_NETLINK:
389 if (a->protocol != b->protocol)
390 return false;
391
392 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
393 return false;
394
395 break;
396
397 default:
398 /* Cannot compare, so we assume the addresses are different */
399 return false;
400 }
401
402 return true;
403 }
404
405 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
406 struct SocketAddress b;
407
408 assert(a);
409 assert(s);
410
411 if (socket_address_parse(&b, s) < 0)
412 return false;
413
414 b.type = type;
415
416 return socket_address_equal(a, &b);
417 }
418
419 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
420 struct SocketAddress b;
421
422 assert(a);
423 assert(s);
424
425 if (socket_address_parse_netlink(&b, s) < 0)
426 return false;
427
428 return socket_address_equal(a, &b);
429 }
430
431 const char* socket_address_get_path(const SocketAddress *a) {
432 assert(a);
433
434 if (socket_address_family(a) != AF_UNIX)
435 return NULL;
436
437 if (a->sockaddr.un.sun_path[0] == 0)
438 return NULL;
439
440 return a->sockaddr.un.sun_path;
441 }
442
443 bool socket_ipv6_is_supported(void) {
444 if (access("/proc/net/if_inet6", F_OK) != 0)
445 return false;
446
447 return true;
448 }
449
450 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
451 SocketAddress b;
452 socklen_t solen;
453
454 assert(a);
455 assert(fd >= 0);
456
457 b.size = sizeof(b.sockaddr);
458 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
459 return false;
460
461 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
462 return false;
463
464 solen = sizeof(b.type);
465 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
466 return false;
467
468 if (b.type != a->type)
469 return false;
470
471 if (a->protocol != 0) {
472 solen = sizeof(b.protocol);
473 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
474 return false;
475
476 if (b.protocol != a->protocol)
477 return false;
478 }
479
480 return socket_address_equal(a, &b);
481 }
482
483 int sockaddr_port(const struct sockaddr *_sa) {
484 union sockaddr_union *sa = (union sockaddr_union*) _sa;
485
486 assert(sa);
487
488 if (!IN_SET(sa->sa.sa_family, AF_INET, AF_INET6))
489 return -EAFNOSUPPORT;
490
491 return be16toh(sa->sa.sa_family == AF_INET6 ? sa->in6.sin6_port : sa->in.sin_port);
492 }
493
494 int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret) {
495 union sockaddr_union *sa = (union sockaddr_union*) _sa;
496 char *p;
497 int r;
498
499 assert(sa);
500 assert(salen >= sizeof(sa->sa.sa_family));
501
502 switch (sa->sa.sa_family) {
503
504 case AF_INET: {
505 uint32_t a;
506
507 a = be32toh(sa->in.sin_addr.s_addr);
508
509 if (include_port)
510 r = asprintf(&p,
511 "%u.%u.%u.%u:%u",
512 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
513 be16toh(sa->in.sin_port));
514 else
515 r = asprintf(&p,
516 "%u.%u.%u.%u",
517 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
518 if (r < 0)
519 return -ENOMEM;
520 break;
521 }
522
523 case AF_INET6: {
524 static const unsigned char ipv4_prefix[] = {
525 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
526 };
527
528 if (translate_ipv6 &&
529 memcmp(&sa->in6.sin6_addr, ipv4_prefix, sizeof(ipv4_prefix)) == 0) {
530 const uint8_t *a = sa->in6.sin6_addr.s6_addr+12;
531 if (include_port)
532 r = asprintf(&p,
533 "%u.%u.%u.%u:%u",
534 a[0], a[1], a[2], a[3],
535 be16toh(sa->in6.sin6_port));
536 else
537 r = asprintf(&p,
538 "%u.%u.%u.%u",
539 a[0], a[1], a[2], a[3]);
540 if (r < 0)
541 return -ENOMEM;
542 } else {
543 char a[INET6_ADDRSTRLEN];
544
545 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
546
547 if (include_port) {
548 r = asprintf(&p,
549 "[%s]:%u",
550 a,
551 be16toh(sa->in6.sin6_port));
552 if (r < 0)
553 return -ENOMEM;
554 } else {
555 p = strdup(a);
556 if (!p)
557 return -ENOMEM;
558 }
559 }
560
561 break;
562 }
563
564 case AF_UNIX:
565 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
566 p = strdup("<unnamed>");
567 if (!p)
568 return -ENOMEM;
569
570 } else if (sa->un.sun_path[0] == 0) {
571 /* abstract */
572
573 /* FIXME: We assume we can print the
574 * socket path here and that it hasn't
575 * more than one NUL byte. That is
576 * actually an invalid assumption */
577
578 p = new(char, sizeof(sa->un.sun_path)+1);
579 if (!p)
580 return -ENOMEM;
581
582 p[0] = '@';
583 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
584 p[sizeof(sa->un.sun_path)] = 0;
585
586 } else {
587 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
588 if (!p)
589 return -ENOMEM;
590 }
591
592 break;
593
594 default:
595 return -EOPNOTSUPP;
596 }
597
598
599 *ret = p;
600 return 0;
601 }
602
603 int getpeername_pretty(int fd, bool include_port, char **ret) {
604 union sockaddr_union sa;
605 socklen_t salen = sizeof(sa);
606 int r;
607
608 assert(fd >= 0);
609 assert(ret);
610
611 if (getpeername(fd, &sa.sa, &salen) < 0)
612 return -errno;
613
614 if (sa.sa.sa_family == AF_UNIX) {
615 struct ucred ucred = {};
616
617 /* UNIX connection sockets are anonymous, so let's use
618 * PID/UID as pretty credentials instead */
619
620 r = getpeercred(fd, &ucred);
621 if (r < 0)
622 return r;
623
624 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
625 return -ENOMEM;
626
627 return 0;
628 }
629
630 /* For remote sockets we translate IPv6 addresses back to IPv4
631 * if applicable, since that's nicer. */
632
633 return sockaddr_pretty(&sa.sa, salen, true, include_port, ret);
634 }
635
636 int getsockname_pretty(int fd, char **ret) {
637 union sockaddr_union sa;
638 socklen_t salen = sizeof(sa);
639
640 assert(fd >= 0);
641 assert(ret);
642
643 if (getsockname(fd, &sa.sa, &salen) < 0)
644 return -errno;
645
646 /* For local sockets we do not translate IPv6 addresses back
647 * to IPv6 if applicable, since this is usually used for
648 * listening sockets where the difference between IPv4 and
649 * IPv6 matters. */
650
651 return sockaddr_pretty(&sa.sa, salen, false, true, ret);
652 }
653
654 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
655 int r;
656 char host[NI_MAXHOST], *ret;
657
658 assert(_ret);
659
660 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0,
661 NI_IDN|NI_IDN_USE_STD3_ASCII_RULES);
662 if (r != 0) {
663 int saved_errno = errno;
664
665 r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
666 if (r < 0)
667 return r;
668
669 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
670 } else {
671 ret = strdup(host);
672 if (!ret)
673 return -ENOMEM;
674 }
675
676 *_ret = ret;
677 return 0;
678 }
679
680 int getnameinfo_pretty(int fd, char **ret) {
681 union sockaddr_union sa;
682 socklen_t salen = sizeof(sa);
683
684 assert(fd >= 0);
685 assert(ret);
686
687 if (getsockname(fd, &sa.sa, &salen) < 0)
688 return -errno;
689
690 return socknameinfo_pretty(&sa, salen, ret);
691 }
692
693 int socket_address_unlink(SocketAddress *a) {
694 assert(a);
695
696 if (socket_address_family(a) != AF_UNIX)
697 return 0;
698
699 if (a->sockaddr.un.sun_path[0] == 0)
700 return 0;
701
702 if (unlink(a->sockaddr.un.sun_path) < 0)
703 return -errno;
704
705 return 1;
706 }
707
708 static const char* const netlink_family_table[] = {
709 [NETLINK_ROUTE] = "route",
710 [NETLINK_FIREWALL] = "firewall",
711 [NETLINK_INET_DIAG] = "inet-diag",
712 [NETLINK_NFLOG] = "nflog",
713 [NETLINK_XFRM] = "xfrm",
714 [NETLINK_SELINUX] = "selinux",
715 [NETLINK_ISCSI] = "iscsi",
716 [NETLINK_AUDIT] = "audit",
717 [NETLINK_FIB_LOOKUP] = "fib-lookup",
718 [NETLINK_CONNECTOR] = "connector",
719 [NETLINK_NETFILTER] = "netfilter",
720 [NETLINK_IP6_FW] = "ip6-fw",
721 [NETLINK_DNRTMSG] = "dnrtmsg",
722 [NETLINK_KOBJECT_UEVENT] = "kobject-uevent",
723 [NETLINK_GENERIC] = "generic",
724 [NETLINK_SCSITRANSPORT] = "scsitransport",
725 [NETLINK_ECRYPTFS] = "ecryptfs"
726 };
727
728 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
729
730 static const char* const socket_address_bind_ipv6_only_table[_SOCKET_ADDRESS_BIND_IPV6_ONLY_MAX] = {
731 [SOCKET_ADDRESS_DEFAULT] = "default",
732 [SOCKET_ADDRESS_BOTH] = "both",
733 [SOCKET_ADDRESS_IPV6_ONLY] = "ipv6-only"
734 };
735
736 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
737
738 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
739 assert(a);
740 assert(b);
741
742 if (a->sa.sa_family != b->sa.sa_family)
743 return false;
744
745 if (a->sa.sa_family == AF_INET)
746 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
747
748 if (a->sa.sa_family == AF_INET6)
749 return memcmp(&a->in6.sin6_addr, &b->in6.sin6_addr, sizeof(a->in6.sin6_addr)) == 0;
750
751 return false;
752 }
753
754 int fd_inc_sndbuf(int fd, size_t n) {
755 int r, value;
756 socklen_t l = sizeof(value);
757
758 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
759 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
760 return 0;
761
762 /* If we have the privileges we will ignore the kernel limit. */
763
764 value = (int) n;
765 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
766 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
767 return -errno;
768
769 return 1;
770 }
771
772 int fd_inc_rcvbuf(int fd, size_t n) {
773 int r, value;
774 socklen_t l = sizeof(value);
775
776 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
777 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
778 return 0;
779
780 /* If we have the privileges we will ignore the kernel limit. */
781
782 value = (int) n;
783 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
784 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
785 return -errno;
786 return 1;
787 }
788
789 static const char* const ip_tos_table[] = {
790 [IPTOS_LOWDELAY] = "low-delay",
791 [IPTOS_THROUGHPUT] = "throughput",
792 [IPTOS_RELIABILITY] = "reliability",
793 [IPTOS_LOWCOST] = "low-cost",
794 };
795
796 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
797
798 bool ifname_valid(const char *p) {
799 bool numeric = true;
800
801 /* Checks whether a network interface name is valid. This is inspired by dev_valid_name() in the kernel sources
802 * but slightly stricter, as we only allow non-control, non-space ASCII characters in the interface name. We
803 * also don't permit names that only container numbers, to avoid confusion with numeric interface indexes. */
804
805 if (isempty(p))
806 return false;
807
808 if (strlen(p) >= IFNAMSIZ)
809 return false;
810
811 if (STR_IN_SET(p, ".", ".."))
812 return false;
813
814 while (*p) {
815 if ((unsigned char) *p >= 127U)
816 return false;
817
818 if ((unsigned char) *p <= 32U)
819 return false;
820
821 if (*p == ':' || *p == '/')
822 return false;
823
824 numeric = numeric && (*p >= '0' && *p <= '9');
825 p++;
826 }
827
828 if (numeric)
829 return false;
830
831 return true;
832 }
833
834 int getpeercred(int fd, struct ucred *ucred) {
835 socklen_t n = sizeof(struct ucred);
836 struct ucred u;
837 int r;
838
839 assert(fd >= 0);
840 assert(ucred);
841
842 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
843 if (r < 0)
844 return -errno;
845
846 if (n != sizeof(struct ucred))
847 return -EIO;
848
849 /* Check if the data is actually useful and not suppressed due
850 * to namespacing issues */
851 if (u.pid <= 0)
852 return -ENODATA;
853 if (u.uid == UID_INVALID)
854 return -ENODATA;
855 if (u.gid == GID_INVALID)
856 return -ENODATA;
857
858 *ucred = u;
859 return 0;
860 }
861
862 int getpeersec(int fd, char **ret) {
863 socklen_t n = 64;
864 char *s;
865 int r;
866
867 assert(fd >= 0);
868 assert(ret);
869
870 s = new0(char, n);
871 if (!s)
872 return -ENOMEM;
873
874 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
875 if (r < 0) {
876 free(s);
877
878 if (errno != ERANGE)
879 return -errno;
880
881 s = new0(char, n);
882 if (!s)
883 return -ENOMEM;
884
885 r = getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n);
886 if (r < 0) {
887 free(s);
888 return -errno;
889 }
890 }
891
892 if (isempty(s)) {
893 free(s);
894 return -EOPNOTSUPP;
895 }
896
897 *ret = s;
898 return 0;
899 }
900
901 int send_one_fd_sa(
902 int transport_fd,
903 int fd,
904 const struct sockaddr *sa, socklen_t len,
905 int flags) {
906
907 union {
908 struct cmsghdr cmsghdr;
909 uint8_t buf[CMSG_SPACE(sizeof(int))];
910 } control = {};
911 struct msghdr mh = {
912 .msg_name = (struct sockaddr*) sa,
913 .msg_namelen = len,
914 .msg_control = &control,
915 .msg_controllen = sizeof(control),
916 };
917 struct cmsghdr *cmsg;
918
919 assert(transport_fd >= 0);
920 assert(fd >= 0);
921
922 cmsg = CMSG_FIRSTHDR(&mh);
923 cmsg->cmsg_level = SOL_SOCKET;
924 cmsg->cmsg_type = SCM_RIGHTS;
925 cmsg->cmsg_len = CMSG_LEN(sizeof(int));
926 memcpy(CMSG_DATA(cmsg), &fd, sizeof(int));
927
928 mh.msg_controllen = CMSG_SPACE(sizeof(int));
929 if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
930 return -errno;
931
932 return 0;
933 }
934
935 int receive_one_fd(int transport_fd, int flags) {
936 union {
937 struct cmsghdr cmsghdr;
938 uint8_t buf[CMSG_SPACE(sizeof(int))];
939 } control = {};
940 struct msghdr mh = {
941 .msg_control = &control,
942 .msg_controllen = sizeof(control),
943 };
944 struct cmsghdr *cmsg, *found = NULL;
945
946 assert(transport_fd >= 0);
947
948 /*
949 * Receive a single FD via @transport_fd. We don't care for
950 * the transport-type. We retrieve a single FD at most, so for
951 * packet-based transports, the caller must ensure to send
952 * only a single FD per packet. This is best used in
953 * combination with send_one_fd().
954 */
955
956 if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
957 return -errno;
958
959 CMSG_FOREACH(cmsg, &mh) {
960 if (cmsg->cmsg_level == SOL_SOCKET &&
961 cmsg->cmsg_type == SCM_RIGHTS &&
962 cmsg->cmsg_len == CMSG_LEN(sizeof(int))) {
963 assert(!found);
964 found = cmsg;
965 break;
966 }
967 }
968
969 if (!found) {
970 cmsg_close_all(&mh);
971 return -EIO;
972 }
973
974 return *(int*) CMSG_DATA(found);
975 }
976
977 ssize_t next_datagram_size_fd(int fd) {
978 ssize_t l;
979 int k;
980
981 /* This is a bit like FIONREAD/SIOCINQ, however a bit more powerful. The difference being: recv(MSG_PEEK) will
982 * actually cause the next datagram in the queue to be validated regarding checksums, which FIONREAD doesn't
983 * do. This difference is actually of major importance as we need to be sure that the size returned here
984 * actually matches what we will read with recvmsg() next, as otherwise we might end up allocating a buffer of
985 * the wrong size. */
986
987 l = recv(fd, NULL, 0, MSG_PEEK|MSG_TRUNC);
988 if (l < 0) {
989 if (errno == EOPNOTSUPP || errno == EFAULT)
990 goto fallback;
991
992 return -errno;
993 }
994 if (l == 0)
995 goto fallback;
996
997 return l;
998
999 fallback:
1000 k = 0;
1001
1002 /* Some sockets (AF_PACKET) do not support null-sized recv() with MSG_TRUNC set, let's fall back to FIONREAD
1003 * for them. Checksums don't matter for raw sockets anyway, hence this should be fine. */
1004
1005 if (ioctl(fd, FIONREAD, &k) < 0)
1006 return -errno;
1007
1008 return (ssize_t) k;
1009 }
1010
1011 int flush_accept(int fd) {
1012
1013 struct pollfd pollfd = {
1014 .fd = fd,
1015 .events = POLLIN,
1016 };
1017 int r;
1018
1019
1020 /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
1021
1022 for (;;) {
1023 int cfd;
1024
1025 r = poll(&pollfd, 1, 0);
1026 if (r < 0) {
1027 if (errno == EINTR)
1028 continue;
1029
1030 return -errno;
1031
1032 } else if (r == 0)
1033 return 0;
1034
1035 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1036 if (cfd < 0) {
1037 if (errno == EINTR)
1038 continue;
1039
1040 if (errno == EAGAIN)
1041 return 0;
1042
1043 return -errno;
1044 }
1045
1046 close(cfd);
1047 }
1048 }
1049
1050 struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length) {
1051 struct cmsghdr *cmsg;
1052
1053 assert(mh);
1054
1055 CMSG_FOREACH(cmsg, mh)
1056 if (cmsg->cmsg_level == level &&
1057 cmsg->cmsg_type == type &&
1058 (length == (socklen_t) -1 || length == cmsg->cmsg_len))
1059 return cmsg;
1060
1061 return NULL;
1062 }
1063
1064 int socket_ioctl_fd(void) {
1065 int fd;
1066
1067 /* Create a socket to invoke the various network interface ioctl()s on. Traditionally only AF_INET was good for
1068 * that. Since kernel 4.6 AF_NETLINK works for this too. We first try to use AF_INET hence, but if that's not
1069 * available (for example, because it is made unavailable via SECCOMP or such), we'll fall back to the more
1070 * generic AF_NETLINK. */
1071
1072 fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
1073 if (fd < 0)
1074 fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_GENERIC);
1075 if (fd < 0)
1076 return -errno;
1077
1078 return fd;
1079 }