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