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