• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 20647873619

01 Jan 2026 11:49PM UTC coverage: 72.697% (+0.02%) from 72.676%
20647873619

push

github

yuwata
vmspawn: Add --user/--system and support user session machined registration

The UX of registering with the user session machined
instance is much better as there won't be an authorization
prompt. To make that available for users, let's add --user
and --system switches for vmspawn. For backwards compat, we'll
still try to register with the system machined instance if the
user machined instance is not available.

0 of 35 new or added lines in 2 files covered. (0.0%)

286 existing lines in 41 files now uncovered.

310072 of 426528 relevant lines covered (72.7%)

1140521.48 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.19
/src/basic/socket-util.h
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2
#pragma once
3

4
#include <linux/if_ether.h>
5
#include <linux/if_infiniband.h>
6
#include <linux/if_packet.h>
7
#include <linux/netlink.h>
8
#include <linux/vm_sockets.h>
9
#include <netinet/in.h>
10
#include <sys/socket.h>
11
#include <sys/un.h>
12

13
#include "basic-forward.h"
14
#include "memory-util.h"
15
#include "missing-network.h"
16

17
union sockaddr_union {
18
        /* The minimal, abstract version */
19
        struct sockaddr sa;
20

21
        /* The libc provided version that allocates "enough room" for every protocol */
22
        struct sockaddr_storage storage;
23

24
        /* Protocol-specific implementations */
25
        struct sockaddr_in in;
26
        struct sockaddr_in6 in6;
27
        struct sockaddr_un un;
28
        struct sockaddr_nl nl;
29
        struct sockaddr_ll ll;
30
        struct sockaddr_vm vm;
31

32
        /* Ensure there is enough space to store Infiniband addresses */
33
        uint8_t ll_buffer[offsetof(struct sockaddr_ll, sll_addr) + CONST_MAX(ETH_ALEN, INFINIBAND_ALEN)];
34

35
        /* Ensure there is enough space after the AF_UNIX sun_path for one more NUL byte, just to be sure that the path
36
         * component is always followed by at least one NUL byte. */
37
        uint8_t un_buffer[sizeof(struct sockaddr_un) + 1];
38
};
39

40
#define SUN_PATH_LEN (sizeof(((struct sockaddr_un){}).sun_path))
41

42
typedef struct SocketAddress {
43
        union sockaddr_union sockaddr;
44

45
        /* We store the size here explicitly due to the weird
46
         * sockaddr_un semantics for abstract sockets */
47
        socklen_t size;
48

49
        /* Socket type, i.e. SOCK_STREAM, SOCK_DGRAM, ... */
50
        int type;
51

52
        /* Socket protocol, IPPROTO_xxx, usually 0, except for netlink */
53
        int protocol;
54
} SocketAddress;
55

56
#define socket_address_family(a) ((a)->sockaddr.sa.sa_family)
57

58
DECLARE_STRING_TABLE_LOOKUP(socket_address_type, int);
59

60
int sockaddr_un_unlink(const struct sockaddr_un *sa);
61

62
static inline int socket_address_unlink(const SocketAddress *a) {
266✔
63
        return socket_address_family(a) == AF_UNIX ? sockaddr_un_unlink(&a->sockaddr.un) : 0;
266✔
64
}
65

66
bool socket_address_can_accept(const SocketAddress *a) _pure_;
67

68
int socket_address_verify(const SocketAddress *a, bool strict) _pure_;
69
int socket_address_print(const SocketAddress *a, char **ret);
70
bool socket_address_matches_fd(const SocketAddress *a, int fd);
71

72
bool socket_address_equal(const SocketAddress *a, const SocketAddress *b) _pure_;
73

74
const char* socket_address_get_path(const SocketAddress *a);
75

76
bool socket_ipv6_is_supported(void);
77
bool socket_ipv6_is_enabled(void);
78

79
int sockaddr_port(const struct sockaddr *_sa, unsigned *port);
80
const union in_addr_union *sockaddr_in_addr(const struct sockaddr *sa);
81
int sockaddr_set_in_addr(union sockaddr_union *u, int family, const union in_addr_union *a, uint16_t port);
82

83
int sockaddr_pretty(const struct sockaddr *_sa, socklen_t salen, bool translate_ipv6, bool include_port, char **ret);
84
int getpeername_pretty(int fd, bool include_port, char **ret);
85
int getsockname_pretty(int fd, char **ret);
86

87
int socknameinfo_pretty(const struct sockaddr *sa, socklen_t salen, char **_ret);
88

89
DECLARE_STRING_TABLE_LOOKUP_WITH_FALLBACK(netlink_family, int);
90

91
bool sockaddr_equal(const union sockaddr_union *a, const union sockaddr_union *b);
92

93
int fd_set_sndbuf(int fd, size_t n, bool increase);
94
static inline int fd_inc_sndbuf(int fd, size_t n) {
410,729✔
95
        return fd_set_sndbuf(fd, n, true);
410,729✔
96
}
97
int fd_set_rcvbuf(int fd, size_t n, bool increase);
98
static inline int fd_increase_rxbuf(int fd, size_t n) {
27,390✔
99
        return fd_set_rcvbuf(fd, n, true);
27,390✔
100
}
101

102
DECLARE_STRING_TABLE_LOOKUP_WITH_FALLBACK(ip_tos, int);
103

104
typedef enum {
105
        IFNAME_VALID_ALTERNATIVE = 1 << 0, /* Allow "altnames" too */
106
        IFNAME_VALID_NUMERIC     = 1 << 1, /* Allow decimal formatted ifindexes too */
107
        IFNAME_VALID_SPECIAL     = 1 << 2, /* Allow the special names "all" and "default" */
108
        _IFNAME_VALID_ALL        = IFNAME_VALID_ALTERNATIVE | IFNAME_VALID_NUMERIC | IFNAME_VALID_SPECIAL,
109
} IfnameValidFlags;
110
bool ifname_valid_char(char a) _const_;
111
bool ifname_valid_full(const char *p, IfnameValidFlags flags) _pure_;
112
static inline bool ifname_valid(const char *p) {
5,693✔
113
        return ifname_valid_full(p, 0);
5,693✔
114
}
115
bool address_label_valid(const char *p) _pure_;
116

117
int getpeercred(int fd, struct ucred *ucred);
118
int getpeersec(int fd, char **ret);
119
int getpeergroups(int fd, gid_t **ret);
120
int getpeerpidfd(int fd);
121
int getpeerpidref(int fd, PidRef *ret);
122

123
ssize_t send_many_fds_iov_sa(
124
                int transport_fd,
125
                int *fds_array, size_t n_fds_array,
126
                const struct iovec *iov, size_t iovlen,
127
                const struct sockaddr *sa, socklen_t len,
128
                int flags);
129
static inline ssize_t send_many_fds_iov(
1✔
130
                int transport_fd,
131
                int *fds_array, size_t n_fds_array,
132
                const struct iovec *iov, size_t iovlen,
133
                int flags) {
134

135
        return send_many_fds_iov_sa(transport_fd, fds_array, n_fds_array, iov, iovlen, NULL, 0, flags);
1✔
136
}
137
static inline int send_many_fds(
138
                int transport_fd,
139
                int *fds_array,
140
                size_t n_fds_array,
141
                int flags) {
142

143
        return send_many_fds_iov_sa(transport_fd, fds_array, n_fds_array, NULL, 0, NULL, 0, flags);
144
}
145
ssize_t send_one_fd_iov_sa(
146
                int transport_fd,
147
                int fd,
148
                const struct iovec *iov, size_t iovlen,
149
                const struct sockaddr *sa, socklen_t len,
150
                int flags);
151
int send_one_fd_sa(int transport_fd,
152
                   int fd,
153
                   const struct sockaddr *sa, socklen_t len,
154
                   int flags);
155
#define send_one_fd_iov(transport_fd, fd, iov, iovlen, flags) send_one_fd_iov_sa(transport_fd, fd, iov, iovlen, NULL, 0, flags)
156
#define send_one_fd(transport_fd, fd, flags) send_one_fd_iov_sa(transport_fd, fd, NULL, 0, NULL, 0, flags)
157
ssize_t receive_one_fd_iov(int transport_fd, struct iovec *iov, size_t iovlen, int flags, int *ret_fd);
158
int receive_one_fd(int transport_fd, int flags);
159
ssize_t receive_many_fds_iov(int transport_fd, struct iovec *iov, size_t iovlen, int **ret_fds_array, size_t *ret_n_fds_array, int flags);
160
int receive_many_fds(int transport_fd, int **ret_fds_array, size_t *ret_n_fds_array, int flags);
161

162
ssize_t next_datagram_size_fd(int fd);
163

164
int flush_accept(int fd);
165
ssize_t flush_mqueue(int fd);
166

167
#define CMSG_FOREACH(cmsg, mh)                                          \
168
        for ((cmsg) = CMSG_FIRSTHDR(mh); (cmsg); (cmsg) = CMSG_NXTHDR((mh), (cmsg)))
169

170
/* Returns the cmsghdr's data pointer, but safely cast to the specified type. Does two alignment checks: one
171
 * at compile time, that the requested type has a smaller or same alignment as 'struct cmsghdr', and one
172
 * during runtime, that the actual pointer matches the alignment too. This is supposed to catch cases such as
173
 * 'struct timeval' is embedded into 'struct cmsghdr' on architectures where the alignment of the former is 8
174
 * bytes (because of a 64-bit time_t), but of the latter is 4 bytes (because size_t is 32 bits), such as
175
 * riscv32. */
176
#define CMSG_TYPED_DATA(cmsg, type)                                     \
177
        ({                                                              \
178
                struct cmsghdr *_cmsg = (cmsg);                         \
179
                assert_cc(alignof(type) <= alignof(struct cmsghdr));    \
180
                _cmsg ? CAST_ALIGN_PTR(type, CMSG_DATA(_cmsg)) : (type*) NULL; \
181
        })
182

183
struct cmsghdr* cmsg_find(struct msghdr *mh, int level, int type, socklen_t length);
184
void* cmsg_find_and_copy_data(struct msghdr *mh, int level, int type, void *buf, size_t buf_len);
185

186
/* Type-safe, dereferencing version of cmsg_find() */
187
#define CMSG_FIND_DATA(mh, level, type, ctype)                          \
188
        CMSG_TYPED_DATA(cmsg_find(mh, level, type, CMSG_LEN(sizeof(ctype))), ctype)
189

190
/* Type-safe version of cmsg_find_and_copy_data() */
191
#define CMSG_FIND_AND_COPY_DATA(mh, level, type, ctype)             \
192
        (ctype*) cmsg_find_and_copy_data(mh, level, type, &(ctype){}, sizeof(ctype))
193

194
/* Resolves to a type that can carry cmsghdr structures. Make sure things are properly aligned, i.e. the type
195
 * itself is placed properly in memory and the size is also aligned to what's appropriate for "cmsghdr"
196
 * structures. */
197
#define CMSG_BUFFER_TYPE(size)                                          \
198
        union {                                                         \
199
                struct cmsghdr cmsghdr;                                 \
200
                uint8_t buf[size];                                      \
201
                uint8_t align_check[(size) >= CMSG_SPACE(0) &&          \
202
                                    (size) == CMSG_ALIGN(size) ? 1 : -1]; \
203
        }
204

205
size_t sockaddr_ll_len(const struct sockaddr_ll *sa);
206

207
size_t sockaddr_un_len(const struct sockaddr_un *sa);
208

209
size_t sockaddr_len(const union sockaddr_union *sa);
210

211
int socket_ioctl_fd(void);
212

213
int sockaddr_un_set_path(struct sockaddr_un *ret, const char *path);
214

215
static inline int setsockopt_int(int fd, int level, int optname, int value) {
1,141,494✔
216
        if (setsockopt(fd, level, optname, &value, sizeof(value)) < 0)
1,141,494✔
217
                return -errno;
71,188✔
218

219
        return 0;
220
}
221

222
int getsockopt_int(int fd, int level, int optname, int *ret);
223

224
int socket_bind_to_ifname(int fd, const char *ifname);
225
int socket_bind_to_ifindex(int fd, int ifindex);
226

227
int socket_autobind(int fd, char **ret_name);
228

229
/* glibc duplicates timespec/timeval on certain 32-bit arches, once in 32-bit and once in 64-bit.
230
 * See __convert_scm_timestamps() in glibc source code. Hence, we need additional buffer space for them
231
 * to prevent truncating control msg (recvmsg() MSG_CTRUNC). */
232
#define CMSG_SPACE_TIMEVAL                                              \
233
        (CMSG_SPACE(sizeof(struct timeval)) + CMSG_SPACE(2 * sizeof(uint64_t)))
234
#define CMSG_SPACE_TIMESPEC                                             \
235
        (CMSG_SPACE(sizeof(struct timespec)) + CMSG_SPACE(2 * sizeof(uint64_t)))
236

237
ssize_t recvmsg_safe(int sockfd, struct msghdr *msg, int flags);
238

239
int socket_get_family(int fd);
240
int socket_set_recvpktinfo(int fd, int af, bool b);
241
int socket_set_unicast_if(int fd, int af, int ifi);
242

243
int socket_set_option(int fd, int af, int opt_ipv4, int opt_ipv6, int val);
244
static inline int socket_set_recverr(int fd, int af, bool b) {
15,254✔
245
        return socket_set_option(fd, af, IP_RECVERR, IPV6_RECVERR, b);
15,254✔
246
}
247
static inline int socket_set_recvttl(int fd, int af, bool b) {
1,522✔
248
        return socket_set_option(fd, af, IP_RECVTTL, IPV6_RECVHOPLIMIT, b);
1,522✔
249
}
250
static inline int socket_set_ttl(int fd, int af, int ttl) {
1,122✔
251
        return socket_set_option(fd, af, IP_TTL, IPV6_UNICAST_HOPS, ttl);
1,122✔
252
}
253
static inline int socket_set_freebind(int fd, int af, bool b) {
6✔
254
        return socket_set_option(fd, af, IP_FREEBIND, IPV6_FREEBIND, b);
6✔
255
}
UNCOV
256
static inline int socket_set_transparent(int fd, int af, bool b) {
×
UNCOV
257
        return socket_set_option(fd, af, IP_TRANSPARENT, IPV6_TRANSPARENT, b);
×
258
}
259
static inline int socket_set_recvfragsize(int fd, int af, bool b) {
15,460✔
260
        return socket_set_option(fd, af, IP_RECVFRAGSIZE, IPV6_RECVFRAGSIZE, b);
15,460✔
261
}
262

263
int socket_get_mtu(int fd, int af, size_t *ret);
264

265
/* an initializer for struct ucred that initialized all fields to the invalid value appropriate for each */
266
#define UCRED_INVALID { .pid = 0, .uid = UID_INVALID, .gid = GID_INVALID }
267

268
int connect_unix_path(int fd, int dir_fd, const char *path);
269

UNCOV
270
static inline bool VSOCK_CID_IS_REGULAR(unsigned cid) {
×
271
        /* 0, 1, 2, UINT32_MAX are special, refuse those */
UNCOV
272
        return cid > 2 && cid < UINT32_MAX;
×
273
}
274

275
int vsock_parse_port(const char *s, unsigned *ret);
276
int vsock_parse_cid(const char *s, unsigned *ret);
277

278
/* Parses AF_UNIX and AF_VSOCK addresses. AF_INET[6] require some netlink calls, so it cannot be in
279
 * src/basic/ and is done from 'socket_local_address from src/shared/. Return -EPROTO in case of
280
 * protocol mismatch. */
281
int socket_address_parse_unix(SocketAddress *ret_address, const char *s);
282
int socket_address_parse_vsock(SocketAddress *ret_address, const char *s);
283
int socket_address_equal_unix(const char *a, const char *b);
284

285
/* libc's SOMAXCONN is defined to 128 or 4096 (at least on glibc). But actually, the value can be much
286
 * larger. In our codebase we want to set it to the max usually, since nowadays socket memory is properly
287
 * tracked by memcg, and hence we don't need to enforce extra limits here. Moreover, the kernel caps it to
288
 * /proc/sys/net/core/somaxconn anyway, thus by setting this to unbounded we just make that sysctl file
289
 * authoritative. */
290
#define SOMAXCONN_DELUXE INT_MAX
291

292
int vsock_get_local_cid(unsigned *ret);
293

294
int netlink_socket_get_multicast_groups(int fd, size_t *ret_len, uint32_t **ret_groups);
295

296
int socket_get_cookie(int fd, uint64_t *ret);
297

298
void cmsg_close_all(struct msghdr *mh);
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc