1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2010 Lennart Poettering
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.
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.
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/>.
21 #include <arpa/inet.h>
26 #include <netinet/ip.h>
35 #include "alloc-util.h"
38 #include "format-util.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"
49 #include "user-util.h"
53 #if 0 /// UNNEEDED by elogind
55 # define IDN_FLAGS NI_IDN
60 static const char* const socket_address_type_table[] = {
61 [SOCK_STREAM] = "Stream",
62 [SOCK_DGRAM] = "Datagram",
64 [SOCK_RDM] = "ReliableDatagram",
65 [SOCK_SEQPACKET] = "SequentialPacket",
66 [SOCK_DCCP] = "DatagramCongestionControl",
69 DEFINE_STRING_TABLE_LOOKUP(socket_address_type, int);
71 int socket_address_parse(SocketAddress *a, const char *s) {
80 a->type = SOCK_STREAM;
85 /* IPv6 in [x:.....:z]:p notation */
91 n = strndupa(s+1, e-s-1);
94 if (inet_pton(AF_INET6, n, &a->sockaddr.in6.sin6_addr) <= 0)
95 return errno > 0 ? -errno : -EINVAL;
102 r = safe_atou(e, &u);
103 r = parse_ip_port(e, &port);
107 if (u <= 0 || u > 0xFFFF)
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);
115 } else if (*s == '/') {
121 if (l >= sizeof(a->sockaddr.un.sun_path))
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;
128 } else if (*s == '@') {
129 /* Abstract AF_UNIX socket */
133 if (l >= sizeof(a->sockaddr.un.sun_path) - 1)
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;
140 } else if (startswith(s, "vsock:")) {
141 /* AF_VSOCK socket in vsock:cid:port notation */
142 const char *cid_start = s + STRLEN("vsock:");
145 e = strchr(cid_start, ':');
149 r = safe_atou(e+1, &u);
150 r = safe_atou(e+1, &port);
154 n = strndupa(cid_start, e - cid_start);
156 r = safe_atou(n, &a->sockaddr.vm.svm_cid);
160 a->sockaddr.vm.svm_cid = VMADDR_CID_ANY;
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);
172 r = safe_atou(e+1, &u);
173 r = parse_ip_port(e + 1, &port);
177 if (u <= 0 || u > 0xFFFF)
180 n = strndupa(s, e-s);
182 /* IPv4 in w.x.y.z:p notation? */
183 r = inet_pton(AF_INET, n, &a->sockaddr.in.sin_addr);
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);
196 if (strlen(n) > IF_NAMESIZE-1)
199 /* Uh, our last resort, an interface name */
200 idx = if_nametoindex(n);
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);
214 r = safe_atou(s, &u);
215 r = parse_ip_port(s, &port);
219 if (u <= 0 || u > 0xFFFF)
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);
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);
241 int socket_address_parse_and_warn(SocketAddress *a, const char *s) {
245 /* Similar to socket_address_parse() but warns for IPv6 sockets when we don't support them. */
247 r = socket_address_parse(&b, s);
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;
260 int socket_address_parse_netlink(SocketAddress *a, const char *s) {
263 _cleanup_free_ char *sfamily = NULL;
271 if (sscanf(s, "%ms %u", &sfamily, &group) < 1)
272 return errno > 0 ? -errno : -EINVAL;
274 family = netlink_family_from_string(sfamily);
278 a->sockaddr.nl.nl_family = AF_NETLINK;
279 a->sockaddr.nl.nl_groups = group;
282 a->size = sizeof(struct sockaddr_nl);
283 a->protocol = family;
288 int socket_address_verify(const SocketAddress *a) {
291 switch (socket_address_family(a)) {
294 if (a->size != sizeof(struct sockaddr_in))
297 if (a->sockaddr.in.sin_port == 0)
300 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
306 if (a->size != sizeof(struct sockaddr_in6))
309 if (a->sockaddr.in6.sin6_port == 0)
312 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
318 if (a->size < offsetof(struct sockaddr_un, sun_path))
321 if (a->size > offsetof(struct sockaddr_un, sun_path)) {
323 if (a->sockaddr.un.sun_path[0] != 0) {
327 e = memchr(a->sockaddr.un.sun_path, 0, sizeof(a->sockaddr.un.sun_path));
331 if (a->size != offsetof(struct sockaddr_un, sun_path) + (e - a->sockaddr.un.sun_path) + 1)
336 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM, SOCK_SEQPACKET))
343 if (a->size != sizeof(struct sockaddr_nl))
346 if (!IN_SET(a->type, SOCK_RAW, SOCK_DGRAM))
352 if (a->size != sizeof(struct sockaddr_vm))
355 if (!IN_SET(a->type, SOCK_STREAM, SOCK_DGRAM))
361 return -EAFNOSUPPORT;
365 int socket_address_print(const SocketAddress *a, char **ret) {
371 r = socket_address_verify(a);
375 if (socket_address_family(a) == AF_NETLINK) {
376 _cleanup_free_ char *sfamily = NULL;
378 r = netlink_family_to_string_alloc(a->protocol, &sfamily);
382 r = asprintf(ret, "%s %u", sfamily, a->sockaddr.nl.nl_groups);
389 return sockaddr_pretty(&a->sockaddr.sa, a->size, false, true, ret);
392 bool socket_address_can_accept(const SocketAddress *a) {
396 IN_SET(a->type, SOCK_STREAM, SOCK_SEQPACKET);
399 bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) {
403 /* Invalid addresses are unequal to all */
404 if (socket_address_verify(a) < 0 ||
405 socket_address_verify(b) < 0)
408 if (a->type != b->type)
411 if (socket_address_family(a) != socket_address_family(b))
414 switch (socket_address_family(a)) {
417 if (a->sockaddr.in.sin_addr.s_addr != b->sockaddr.in.sin_addr.s_addr)
420 if (a->sockaddr.in.sin_port != b->sockaddr.in.sin_port)
426 if (memcmp(&a->sockaddr.in6.sin6_addr, &b->sockaddr.in6.sin6_addr, sizeof(a->sockaddr.in6.sin6_addr)) != 0)
429 if (a->sockaddr.in6.sin6_port != b->sockaddr.in6.sin6_port)
435 if (a->size <= offsetof(struct sockaddr_un, sun_path) ||
436 b->size <= offsetof(struct sockaddr_un, sun_path))
439 if ((a->sockaddr.un.sun_path[0] == 0) != (b->sockaddr.un.sun_path[0] == 0))
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))
446 if (a->size != b->size)
449 if (memcmp(a->sockaddr.un.sun_path, b->sockaddr.un.sun_path, a->size) != 0)
456 if (a->protocol != b->protocol)
459 if (a->sockaddr.nl.nl_groups != b->sockaddr.nl.nl_groups)
465 if (a->sockaddr.vm.svm_cid != b->sockaddr.vm.svm_cid)
468 if (a->sockaddr.vm.svm_port != b->sockaddr.vm.svm_port)
474 /* Cannot compare, so we assume the addresses are different */
481 bool socket_address_is(const SocketAddress *a, const char *s, int type) {
482 struct SocketAddress b;
487 if (socket_address_parse(&b, s) < 0)
492 return socket_address_equal(a, &b);
495 bool socket_address_is_netlink(const SocketAddress *a, const char *s) {
496 struct SocketAddress b;
501 if (socket_address_parse_netlink(&b, s) < 0)
504 return socket_address_equal(a, &b);
507 const char* socket_address_get_path(const SocketAddress *a) {
510 if (socket_address_family(a) != AF_UNIX)
513 if (a->sockaddr.un.sun_path[0] == 0)
516 return a->sockaddr.un.sun_path;
519 bool socket_ipv6_is_supported(void) {
520 if (access("/proc/net/if_inet6", F_OK) != 0)
526 bool socket_address_matches_fd(const SocketAddress *a, int fd) {
533 b.size = sizeof(b.sockaddr);
534 if (getsockname(fd, &b.sockaddr.sa, &b.size) < 0)
537 if (b.sockaddr.sa.sa_family != a->sockaddr.sa.sa_family)
540 solen = sizeof(b.type);
541 if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &b.type, &solen) < 0)
544 if (b.type != a->type)
547 if (a->protocol != 0) {
548 solen = sizeof(b.protocol);
549 if (getsockopt(fd, SOL_SOCKET, SO_PROTOCOL, &b.protocol, &solen) < 0)
552 if (b.protocol != a->protocol)
556 return socket_address_equal(a, &b);
560 int sockaddr_port(const struct sockaddr *_sa, unsigned *ret_port) {
561 union sockaddr_union *sa = (union sockaddr_union*) _sa;
563 /* Note, this returns the port as 'unsigned' rather than 'uint16_t', as AF_VSOCK knows larger ports */
567 switch (sa->sa.sa_family) {
570 *ret_port = be16toh(sa->in.sin_port);
574 *ret_port = be16toh(sa->in6.sin6_port);
578 *ret_port = sa->vm.svm_port;
582 return -EAFNOSUPPORT;
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;
593 assert(salen >= sizeof(sa->sa.sa_family));
595 switch (sa->sa.sa_family) {
600 a = be32toh(sa->in.sin_addr.s_addr);
605 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF,
606 be16toh(sa->in.sin_port));
610 a >> 24, (a >> 16) & 0xFF, (a >> 8) & 0xFF, a & 0xFF);
617 static const unsigned char ipv4_prefix[] = {
618 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xFF, 0xFF
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;
627 a[0], a[1], a[2], a[3],
628 be16toh(sa->in6.sin6_port));
632 a[0], a[1], a[2], a[3]);
636 char a[INET6_ADDRSTRLEN];
638 inet_ntop(AF_INET6, &sa->in6.sin6_addr, a, sizeof(a));
644 be16toh(sa->in6.sin6_port));
658 if (salen <= offsetof(struct sockaddr_un, sun_path)) {
659 p = strdup("<unnamed>");
663 } else if (sa->un.sun_path[0] == 0) {
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 */
671 p = new(char, sizeof(sa->un.sun_path)+1);
676 memcpy(p+1, sa->un.sun_path+1, sizeof(sa->un.sun_path)-1);
677 p[sizeof(sa->un.sun_path)] = 0;
680 p = strndup(sa->un.sun_path, sizeof(sa->un.sun_path));
694 r = asprintf(&p, "vsock:%u", sa->vm.svm_cid);
708 int getpeername_pretty(int fd, bool include_port, char **ret) {
709 union sockaddr_union sa;
710 socklen_t salen = sizeof(sa);
716 if (getpeername(fd, &sa.sa, &salen) < 0)
719 if (sa.sa.sa_family == AF_UNIX) {
720 struct ucred ucred = {};
722 /* UNIX connection sockets are anonymous, so let's use
723 * PID/UID as pretty credentials instead */
725 r = getpeercred(fd, &ucred);
729 if (asprintf(ret, "PID "PID_FMT"/UID "UID_FMT, ucred.pid, ucred.uid) < 0)
735 /* For remote sockets we translate IPv6 addresses back to IPv4
736 * if applicable, since that's nicer. */
738 return sockaddr_pretty(&sa.sa, salen, true, include_port, ret);
741 int getsockname_pretty(int fd, char **ret) {
742 union sockaddr_union sa;
743 socklen_t salen = sizeof(sa);
748 if (getsockname(fd, &sa.sa, &salen) < 0)
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
756 return sockaddr_pretty(&sa.sa, salen, false, true, ret);
759 int socknameinfo_pretty(union sockaddr_union *sa, socklen_t salen, char **_ret) {
761 char host[NI_MAXHOST], *ret;
765 r = getnameinfo(&sa->sa, salen, host, sizeof(host), NULL, 0, IDN_FLAGS);
767 int saved_errno = errno;
769 r = sockaddr_pretty(&sa->sa, salen, true, true, &ret);
773 log_debug_errno(saved_errno, "getnameinfo(%s) failed: %m", ret);
784 int getnameinfo_pretty(int fd, char **ret) {
785 union sockaddr_union sa;
786 socklen_t salen = sizeof(sa);
791 if (getsockname(fd, &sa.sa, &salen) < 0)
794 return socknameinfo_pretty(&sa, salen, ret);
797 int socket_address_unlink(SocketAddress *a) {
800 if (socket_address_family(a) != AF_UNIX)
803 if (a->sockaddr.un.sun_path[0] == 0)
806 if (unlink(a->sockaddr.un.sun_path) < 0)
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",
833 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int, INT_MAX);
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"
841 DEFINE_STRING_TABLE_LOOKUP(socket_address_bind_ipv6_only, SocketAddressBindIPv6Only);
843 SocketAddressBindIPv6Only parse_socket_address_bind_ipv6_only_or_bool(const char *n) {
846 r = parse_boolean(n);
848 return SOCKET_ADDRESS_IPV6_ONLY;
850 return SOCKET_ADDRESS_BOTH;
852 return socket_address_bind_ipv6_only_from_string(n);
855 bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b) {
859 if (a->sa.sa_family != b->sa.sa_family)
862 if (a->sa.sa_family == AF_INET)
863 return a->in.sin_addr.s_addr == b->in.sin_addr.s_addr;
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;
868 if (a->sa.sa_family == AF_VSOCK)
869 return a->vm.svm_cid == b->vm.svm_cid;
875 int fd_inc_sndbuf(int fd, size_t n) {
877 socklen_t l = sizeof(value);
879 r = getsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, &l);
880 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
883 /* If we have the privileges we will ignore the kernel limit. */
886 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUFFORCE, &value, sizeof(value)) < 0)
887 if (setsockopt(fd, SOL_SOCKET, SO_SNDBUF, &value, sizeof(value)) < 0)
893 int fd_inc_rcvbuf(int fd, size_t n) {
895 socklen_t l = sizeof(value);
897 r = getsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, &l);
898 if (r >= 0 && l == sizeof(value) && (size_t) value >= n*2)
901 /* If we have the privileges we will ignore the kernel limit. */
904 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUFFORCE, &value, sizeof(value)) < 0)
905 if (setsockopt(fd, SOL_SOCKET, SO_RCVBUF, &value, sizeof(value)) < 0)
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",
918 DEFINE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int, 0xff);
920 bool ifname_valid(const char *p) {
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. */
930 if (strlen(p) >= IFNAMSIZ)
933 if (dot_or_dot_dot(p))
937 if ((unsigned char) *p >= 127U)
940 if ((unsigned char) *p <= 32U)
943 if (IN_SET(*p, ':', '/'))
946 numeric = numeric && (*p >= '0' && *p <= '9');
956 bool address_label_valid(const char *p) {
961 if (strlen(p) >= IFNAMSIZ)
965 if ((uint8_t) *p >= 127U)
968 if ((uint8_t) *p <= 31U)
977 int getpeercred(int fd, struct ucred *ucred) {
978 socklen_t n = sizeof(struct ucred);
985 r = getsockopt(fd, SOL_SOCKET, SO_PEERCRED, &u, &n);
989 if (n != sizeof(struct ucred))
992 /* Check if the data is actually useful and not suppressed due to namespacing issues */
993 if (!pid_is_valid(u.pid))
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. */
1003 int getpeersec(int fd, char **ret) {
1004 _cleanup_free_ char *s = NULL;
1011 s = new0(char, n+1);
1015 if (getsockopt(fd, SOL_SOCKET, SO_PEERSEC, s, &n) >= 0)
1018 if (errno != ERANGE)
1033 int getpeergroups(int fd, gid_t **ret) {
1034 socklen_t n = sizeof(gid_t) * 64;
1035 _cleanup_free_ gid_t *d = NULL;
1045 if (getsockopt(fd, SOL_SOCKET, SO_PEERGROUPS, d, &n) >= 0)
1048 if (errno != ERANGE)
1054 assert_se(n % sizeof(gid_t) == 0);
1057 if ((socklen_t) (int) n != n)
1069 const struct sockaddr *sa, socklen_t len,
1073 struct cmsghdr cmsghdr;
1074 uint8_t buf[CMSG_SPACE(sizeof(int))];
1076 struct msghdr mh = {
1077 .msg_name = (struct sockaddr*) sa,
1079 .msg_control = &control,
1080 .msg_controllen = sizeof(control),
1082 struct cmsghdr *cmsg;
1084 assert(transport_fd >= 0);
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));
1093 mh.msg_controllen = CMSG_SPACE(sizeof(int));
1094 if (sendmsg(transport_fd, &mh, MSG_NOSIGNAL | flags) < 0)
1100 #if 0 /// UNNEEDED by elogind
1101 int receive_one_fd(int transport_fd, int flags) {
1103 struct cmsghdr cmsghdr;
1104 uint8_t buf[CMSG_SPACE(sizeof(int))];
1106 struct msghdr mh = {
1107 .msg_control = &control,
1108 .msg_controllen = sizeof(control),
1110 struct cmsghdr *cmsg, *found = NULL;
1112 assert(transport_fd >= 0);
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().
1122 if (recvmsg(transport_fd, &mh, MSG_NOSIGNAL | MSG_CMSG_CLOEXEC | flags) < 0)
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))) {
1136 cmsg_close_all(&mh);
1140 return *(int*) CMSG_DATA(found);
1143 ssize_t next_datagram_size_fd(int fd) {
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. */
1153 l = recv(fd, NULL, 0, MSG_PEEK|MSG_TRUNC);
1155 if (IN_SET(errno, EOPNOTSUPP, EFAULT))
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. */
1171 if (ioctl(fd, FIONREAD, &k) < 0)
1177 int flush_accept(int fd) {
1179 struct pollfd pollfd = {
1186 /* Similar to flush_fd() but flushes all incoming connection by accepting them and immediately closing them. */
1191 r = poll(&pollfd, 1, 0);
1201 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
1206 if (errno == EAGAIN)
1216 struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length) {
1217 struct cmsghdr *cmsg;
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))
1230 int socket_ioctl_fd(void) {
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. */
1238 fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC, 0);
1240 fd = socket(AF_NETLINK, SOCK_RAW|SOCK_CLOEXEC, NETLINK_GENERIC);