]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-llmnr.c
resolved: rework parsing of /etc/hosts
[thirdparty/systemd.git] / src / resolve / resolved-llmnr.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
5f402ae8 2
5f402ae8 3#include <netinet/in.h>
cf0fbc49 4#include <resolv.h>
5f402ae8 5
3ffd4af2 6#include "fd-util.h"
5f402ae8 7#include "resolved-llmnr.h"
3ffd4af2 8#include "resolved-manager.h"
5f402ae8
DM
9
10void manager_llmnr_stop(Manager *m) {
11 assert(m);
12
13 m->llmnr_ipv4_udp_event_source = sd_event_source_unref(m->llmnr_ipv4_udp_event_source);
14 m->llmnr_ipv4_udp_fd = safe_close(m->llmnr_ipv4_udp_fd);
15
16 m->llmnr_ipv6_udp_event_source = sd_event_source_unref(m->llmnr_ipv6_udp_event_source);
17 m->llmnr_ipv6_udp_fd = safe_close(m->llmnr_ipv6_udp_fd);
18
19 m->llmnr_ipv4_tcp_event_source = sd_event_source_unref(m->llmnr_ipv4_tcp_event_source);
20 m->llmnr_ipv4_tcp_fd = safe_close(m->llmnr_ipv4_tcp_fd);
21
22 m->llmnr_ipv6_tcp_event_source = sd_event_source_unref(m->llmnr_ipv6_tcp_event_source);
23 m->llmnr_ipv6_tcp_fd = safe_close(m->llmnr_ipv6_tcp_fd);
24}
25
26int manager_llmnr_start(Manager *m) {
27 int r;
28
29 assert(m);
30
af49ca27 31 if (m->llmnr_support == RESOLVE_SUPPORT_NO)
5f402ae8
DM
32 return 0;
33
34 r = manager_llmnr_ipv4_udp_fd(m);
35 if (r == -EADDRINUSE)
36 goto eaddrinuse;
37 if (r < 0)
38 return r;
39
40 r = manager_llmnr_ipv4_tcp_fd(m);
41 if (r == -EADDRINUSE)
42 goto eaddrinuse;
43 if (r < 0)
44 return r;
45
46 if (socket_ipv6_is_supported()) {
47 r = manager_llmnr_ipv6_udp_fd(m);
48 if (r == -EADDRINUSE)
49 goto eaddrinuse;
50 if (r < 0)
51 return r;
52
53 r = manager_llmnr_ipv6_tcp_fd(m);
54 if (r == -EADDRINUSE)
55 goto eaddrinuse;
56 if (r < 0)
57 return r;
58 }
59
60 return 0;
61
62eaddrinuse:
007ef0a2 63 log_warning("Another LLMNR responder prohibits binding the socket to the same port. Turning off LLMNR support.");
af49ca27 64 m->llmnr_support = RESOLVE_SUPPORT_NO;
5f402ae8
DM
65 manager_llmnr_stop(m);
66
67 return 0;
68}
69
70static int on_llmnr_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
71 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
72 DnsTransaction *t = NULL;
73 Manager *m = userdata;
74 DnsScope *scope;
75 int r;
76
b30bf55d
LP
77 assert(s);
78 assert(fd >= 0);
79 assert(m);
80
5f402ae8
DM
81 r = manager_recv(m, fd, DNS_PROTOCOL_LLMNR, &p);
82 if (r <= 0)
83 return r;
84
6cae1ebe
LP
85 if (manager_our_packet(m, p))
86 return 0;
87
5f402ae8 88 scope = manager_find_scope(m, p);
f1b1a5c4
LP
89 if (!scope) {
90 log_debug("Got LLMNR UDP packet on unknown scope. Ignoring.");
91 return 0;
92 }
93
94 if (dns_packet_validate_reply(p) > 0) {
b30bf55d 95 log_debug("Got LLMNR UDP reply packet for id %u", DNS_PACKET_ID(p));
5f402ae8
DM
96
97 dns_scope_check_conflicts(scope, p);
98
99 t = hashmap_get(m->dns_transactions, UINT_TO_PTR(DNS_PACKET_ID(p)));
100 if (t)
101 dns_transaction_process_reply(t, p);
102
103 } else if (dns_packet_validate_query(p) > 0) {
b30bf55d 104 log_debug("Got LLMNR UDP query packet for id %u", DNS_PACKET_ID(p));
5f402ae8
DM
105
106 dns_scope_process_query(scope, NULL, p);
107 } else
2c6bf498 108 log_debug("Invalid LLMNR UDP packet, ignoring.");
5f402ae8
DM
109
110 return 0;
111}
112
113int manager_llmnr_ipv4_udp_fd(Manager *m) {
114 union sockaddr_union sa = {
115 .in.sin_family = AF_INET,
22a37591 116 .in.sin_port = htobe16(LLMNR_PORT),
5f402ae8 117 };
3f548fff 118 _cleanup_close_ int s = -1;
5f402ae8
DM
119 int r;
120
121 assert(m);
122
123 if (m->llmnr_ipv4_udp_fd >= 0)
124 return m->llmnr_ipv4_udp_fd;
125
3f548fff
YW
126 s = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
127 if (s < 0)
007ef0a2 128 return log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to create socket: %m");
5f402ae8
DM
129
130 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
3f548fff
YW
131 r = setsockopt_int(s, IPPROTO_IP, IP_TTL, 255);
132 if (r < 0)
133 return log_error_errno(r, "LLMNR-IPv4(UDP): Failed to set IP_TTL: %m");
5f402ae8 134
3f548fff
YW
135 r = setsockopt_int(s, IPPROTO_IP, IP_MULTICAST_TTL, 255);
136 if (r < 0)
137 return log_error_errno(r, "LLMNR-IPv4(UDP): Failed to set IP_MULTICAST_TTL: %m");
5f402ae8 138
3f548fff
YW
139 r = setsockopt_int(s, IPPROTO_IP, IP_MULTICAST_LOOP, true);
140 if (r < 0)
141 return log_error_errno(r, "LLMNR-IPv4(UDP): Failed to set IP_MULTICAST_LOOP: %m");
5f402ae8 142
3f548fff
YW
143 r = setsockopt_int(s, IPPROTO_IP, IP_PKTINFO, true);
144 if (r < 0)
145 return log_error_errno(r, "LLMNR-IPv4(UDP): Failed to set IP_PKTINFO: %m");
5f402ae8 146
3f548fff
YW
147 r = setsockopt_int(s, IPPROTO_IP, IP_RECVTTL, true);
148 if (r < 0)
149 return log_error_errno(r, "LLMNR-IPv4(UDP): Failed to set IP_RECVTTL: %m");
5f402ae8
DM
150
151 /* Disable Don't-Fragment bit in the IP header */
3f548fff
YW
152 r = setsockopt_int(s, IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DONT);
153 if (r < 0)
154 return log_error_errno(r, "LLMNR-IPv4(UDP): Failed to set IP_MTU_DISCOVER: %m");
5f402ae8 155
007ef0a2 156 /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
3f548fff 157 r = bind(s, &sa.sa, sizeof(sa.in));
5f402ae8 158 if (r < 0) {
3f548fff
YW
159 if (errno != EADDRINUSE)
160 return log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to bind socket: %m");
007ef0a2
YW
161
162 log_warning("LLMNR-IPv4(UDP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
163
164 /* try again with SO_REUSEADDR */
3f548fff
YW
165 r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
166 if (r < 0)
167 return log_error_errno(r, "LLMNR-IPv4(UDP): Failed to set SO_REUSEADDR: %m");
168
169 r = bind(s, &sa.sa, sizeof(sa.in));
170 if (r < 0)
171 return log_error_errno(errno, "LLMNR-IPv4(UDP): Failed to bind socket: %m");
007ef0a2
YW
172 } else {
173 /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
3f548fff
YW
174 r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
175 if (r < 0)
176 return log_error_errno(r, "LLMNR-IPv4(UDP): Failed to set SO_REUSEADDR: %m");
5f402ae8
DM
177 }
178
3f548fff 179 r = sd_event_add_io(m->event, &m->llmnr_ipv4_udp_event_source, s, EPOLLIN, on_llmnr_packet, m);
5f402ae8 180 if (r < 0)
3f548fff 181 return log_error_errno(r, "LLMNR-IPv4(UDP): Failed to create event source: %m");
5f402ae8 182
aa4a9deb
LP
183 (void) sd_event_source_set_description(m->llmnr_ipv4_udp_event_source, "llmnr-ipv4-udp");
184
3f548fff 185 return m->llmnr_ipv4_udp_fd = TAKE_FD(s);
5f402ae8
DM
186}
187
188int manager_llmnr_ipv6_udp_fd(Manager *m) {
189 union sockaddr_union sa = {
190 .in6.sin6_family = AF_INET6,
22a37591 191 .in6.sin6_port = htobe16(LLMNR_PORT),
5f402ae8 192 };
3f548fff 193 _cleanup_close_ int s = -1;
5f402ae8
DM
194 int r;
195
196 assert(m);
197
198 if (m->llmnr_ipv6_udp_fd >= 0)
199 return m->llmnr_ipv6_udp_fd;
200
3f548fff
YW
201 s = socket(AF_INET6, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
202 if (s < 0)
007ef0a2 203 return log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to create socket: %m");
5f402ae8 204
3f548fff
YW
205 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, 255);
206 if (r < 0)
207 return log_error_errno(r, "LLMNR-IPv6(UDP): Failed to set IPV6_UNICAST_HOPS: %m");
5f402ae8
DM
208
209 /* RFC 4795, section 2.5 recommends setting the TTL of UDP packets to 255. */
3f548fff
YW
210 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_MULTICAST_HOPS, 255);
211 if (r < 0)
212 return log_error_errno(r, "LLMNR-IPv6(UDP): Failed to set IPV6_MULTICAST_HOPS: %m");
5f402ae8 213
3f548fff
YW
214 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_MULTICAST_LOOP, true);
215 if (r < 0)
216 return log_error_errno(r, "LLMNR-IPv6(UDP): Failed to set IPV6_MULTICAST_LOOP: %m");
5f402ae8 217
3f548fff
YW
218 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_V6ONLY, true);
219 if (r < 0)
220 return log_error_errno(r, "LLMNR-IPv6(UDP): Failed to set IPV6_V6ONLY: %m");
5f402ae8 221
3f548fff
YW
222 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, true);
223 if (r < 0)
224 return log_error_errno(r, "LLMNR-IPv6(UDP): Failed to set IPV6_RECVPKTINFO: %m");
5f402ae8 225
3f548fff
YW
226 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, true);
227 if (r < 0)
228 return log_error_errno(r, "LLMNR-IPv6(UDP): Failed to set IPV6_RECVHOPLIMIT: %m");
5f402ae8 229
007ef0a2 230 /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
3f548fff 231 r = bind(s, &sa.sa, sizeof(sa.in6));
5f402ae8 232 if (r < 0) {
3f548fff
YW
233 if (errno != EADDRINUSE)
234 return log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to bind socket: %m");
007ef0a2
YW
235
236 log_warning("LLMNR-IPv6(UDP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
237
238 /* try again with SO_REUSEADDR */
3f548fff
YW
239 r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
240 if (r < 0)
241 return log_error_errno(r, "LLMNR-IPv6(UDP): Failed to set SO_REUSEADDR: %m");
242
243 r = bind(s, &sa.sa, sizeof(sa.in6));
244 if (r < 0)
245 return log_error_errno(errno, "LLMNR-IPv6(UDP): Failed to bind socket: %m");
007ef0a2
YW
246 } else {
247 /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
3f548fff
YW
248 r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
249 if (r < 0)
250 return log_error_errno(r, "LLMNR-IPv6(UDP): Failed to set SO_REUSEADDR: %m");
5f402ae8
DM
251 }
252
3f548fff 253 r = sd_event_add_io(m->event, &m->llmnr_ipv6_udp_event_source, s, EPOLLIN, on_llmnr_packet, m);
35908b98 254 if (r < 0)
3f548fff 255 return log_error_errno(r, "LLMNR-IPv6(UDP): Failed to create event source: %m");
5f402ae8 256
aa4a9deb
LP
257 (void) sd_event_source_set_description(m->llmnr_ipv6_udp_event_source, "llmnr-ipv6-udp");
258
3f548fff 259 return m->llmnr_ipv6_udp_fd = TAKE_FD(s);
5f402ae8
DM
260}
261
262static int on_llmnr_stream_packet(DnsStream *s) {
263 DnsScope *scope;
264
265 assert(s);
b30bf55d 266 assert(s->read_packet);
5f402ae8
DM
267
268 scope = manager_find_scope(s->manager, s->read_packet);
b30bf55d 269 if (!scope)
f1b1a5c4 270 log_debug("Got LLMNR TCP packet on unknown scope. Ignoring.");
b30bf55d
LP
271 else if (dns_packet_validate_query(s->read_packet) > 0) {
272 log_debug("Got LLMNR TCP query packet for id %u", DNS_PACKET_ID(s->read_packet));
5f402ae8
DM
273
274 dns_scope_process_query(scope, s, s->read_packet);
5f402ae8 275 } else
b30bf55d 276 log_debug("Invalid LLMNR TCP packet, ignoring.");
5f402ae8 277
b30bf55d 278 dns_stream_unref(s);
5f402ae8
DM
279 return 0;
280}
281
282static int on_llmnr_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
283 DnsStream *stream;
284 Manager *m = userdata;
285 int cfd, r;
286
287 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
288 if (cfd < 0) {
3742095b 289 if (IN_SET(errno, EAGAIN, EINTR))
5f402ae8
DM
290 return 0;
291
292 return -errno;
293 }
294
91ccab1e 295 r = dns_stream_new(m, &stream, DNS_PROTOCOL_LLMNR, cfd, NULL);
5f402ae8
DM
296 if (r < 0) {
297 safe_close(cfd);
298 return r;
299 }
300
301 stream->on_packet = on_llmnr_stream_packet;
302 return 0;
303}
304
305int manager_llmnr_ipv4_tcp_fd(Manager *m) {
306 union sockaddr_union sa = {
307 .in.sin_family = AF_INET,
22a37591 308 .in.sin_port = htobe16(LLMNR_PORT),
5f402ae8 309 };
3f548fff 310 _cleanup_close_ int s = -1;
5f402ae8
DM
311 int r;
312
313 assert(m);
314
315 if (m->llmnr_ipv4_tcp_fd >= 0)
316 return m->llmnr_ipv4_tcp_fd;
317
3f548fff
YW
318 s = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
319 if (s < 0)
007ef0a2 320 return log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to create socket: %m");
5f402ae8
DM
321
322 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
3f548fff
YW
323 r = setsockopt_int(s, IPPROTO_IP, IP_TTL, true);
324 if (r < 0)
325 return log_error_errno(r, "LLMNR-IPv4(TCP): Failed to set IP_TTL: %m");
5f402ae8 326
3f548fff
YW
327 r = setsockopt_int(s, IPPROTO_IP, IP_PKTINFO, true);
328 if (r < 0)
329 return log_error_errno(r, "LLMNR-IPv4(TCP): Failed to set IP_PKTINFO: %m");
5f402ae8 330
3f548fff
YW
331 r = setsockopt_int(s, IPPROTO_IP, IP_RECVTTL, true);
332 if (r < 0)
333 return log_error_errno(r, "LLMNR-IPv4(TCP): Failed to set IP_RECVTTL: %m");
5f402ae8
DM
334
335 /* Disable Don't-Fragment bit in the IP header */
3f548fff
YW
336 r = setsockopt_int(s, IPPROTO_IP, IP_MTU_DISCOVER, IP_PMTUDISC_DONT);
337 if (r < 0)
338 return log_error_errno(r, "LLMNR-IPv4(TCP): Failed to set IP_MTU_DISCOVER: %m");
5f402ae8 339
007ef0a2 340 /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
3f548fff 341 r = bind(s, &sa.sa, sizeof(sa.in));
5f402ae8 342 if (r < 0) {
3f548fff
YW
343 if (errno != EADDRINUSE)
344 return log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to bind socket: %m");
007ef0a2
YW
345
346 log_warning("LLMNR-IPv4(TCP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
347
348 /* try again with SO_REUSEADDR */
3f548fff
YW
349 r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
350 if (r < 0)
351 return log_error_errno(r, "LLMNR-IPv4(TCP): Failed to set SO_REUSEADDR: %m");
352
353 r = bind(s, &sa.sa, sizeof(sa.in));
354 if (r < 0)
355 return log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to bind socket: %m");
007ef0a2
YW
356 } else {
357 /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
3f548fff
YW
358 r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
359 if (r < 0)
360 return log_error_errno(r, "LLMNR-IPv4(TCP): Failed to set SO_REUSEADDR: %m");
5f402ae8
DM
361 }
362
3f548fff
YW
363 r = listen(s, SOMAXCONN);
364 if (r < 0)
365 return log_error_errno(errno, "LLMNR-IPv4(TCP): Failed to listen the stream: %m");
5f402ae8 366
3f548fff 367 r = sd_event_add_io(m->event, &m->llmnr_ipv4_tcp_event_source, s, EPOLLIN, on_llmnr_stream, m);
5f402ae8 368 if (r < 0)
3f548fff 369 return log_error_errno(r, "LLMNR-IPv4(TCP): Failed to create event source: %m");
5f402ae8 370
aa4a9deb
LP
371 (void) sd_event_source_set_description(m->llmnr_ipv4_tcp_event_source, "llmnr-ipv4-tcp");
372
3f548fff 373 return m->llmnr_ipv4_tcp_fd = TAKE_FD(s);
5f402ae8
DM
374}
375
376int manager_llmnr_ipv6_tcp_fd(Manager *m) {
377 union sockaddr_union sa = {
378 .in6.sin6_family = AF_INET6,
22a37591 379 .in6.sin6_port = htobe16(LLMNR_PORT),
5f402ae8 380 };
3f548fff 381 _cleanup_close_ int s = -1;
5f402ae8
DM
382 int r;
383
384 assert(m);
385
386 if (m->llmnr_ipv6_tcp_fd >= 0)
387 return m->llmnr_ipv6_tcp_fd;
388
3f548fff
YW
389 s = socket(AF_INET6, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
390 if (s < 0)
007ef0a2 391 return log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to create socket: %m");
5f402ae8
DM
392
393 /* RFC 4795, section 2.5. requires setting the TTL of TCP streams to 1 */
3f548fff
YW
394 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_UNICAST_HOPS, true);
395 if (r < 0)
396 return log_error_errno(r, "LLMNR-IPv6(TCP): Failed to set IPV6_UNICAST_HOPS: %m");
5f402ae8 397
3f548fff
YW
398 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_V6ONLY, true);
399 if (r < 0)
400 return log_error_errno(r, "LLMNR-IPv6(TCP): Failed to set IPV6_V6ONLY: %m");
5f402ae8 401
3f548fff
YW
402 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_RECVPKTINFO, true);
403 if (r < 0)
404 return log_error_errno(r, "LLMNR-IPv6(TCP): Failed to set IPV6_RECVPKTINFO: %m");
5f402ae8 405
3f548fff
YW
406 r = setsockopt_int(s, IPPROTO_IPV6, IPV6_RECVHOPLIMIT, true);
407 if (r < 0)
408 return log_error_errno(r, "LLMNR-IPv6(TCP): Failed to set IPV6_RECVHOPLIMIT: %m");
5f402ae8 409
007ef0a2 410 /* first try to bind without SO_REUSEADDR to detect another LLMNR responder */
3f548fff 411 r = bind(s, &sa.sa, sizeof(sa.in6));
5f402ae8 412 if (r < 0) {
3f548fff
YW
413 if (errno != EADDRINUSE)
414 return log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to bind socket: %m");
007ef0a2
YW
415
416 log_warning("LLMNR-IPv6(TCP): There appears to be another LLMNR responder running, or previously systemd-resolved crashed with some outstanding transfers.");
417
418 /* try again with SO_REUSEADDR */
3f548fff
YW
419 r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
420 if (r < 0)
421 return log_error_errno(r, "LLMNR-IPv6(TCP): Failed to set SO_REUSEADDR: %m");
422
423 r = bind(s, &sa.sa, sizeof(sa.in6));
424 if (r < 0)
425 return log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to bind socket: %m");
007ef0a2
YW
426 } else {
427 /* enable SO_REUSEADDR for the case that the user really wants multiple LLMNR responders */
3f548fff
YW
428 r = setsockopt_int(s, SOL_SOCKET, SO_REUSEADDR, true);
429 if (r < 0)
430 return log_error_errno(r, "LLMNR-IPv6(TCP): Failed to set SO_REUSEADDR: %m");
5f402ae8
DM
431 }
432
3f548fff
YW
433 r = listen(s, SOMAXCONN);
434 if (r < 0)
435 return log_error_errno(errno, "LLMNR-IPv6(TCP): Failed to listen the stream: %m");
5f402ae8 436
3f548fff 437 r = sd_event_add_io(m->event, &m->llmnr_ipv6_tcp_event_source, s, EPOLLIN, on_llmnr_stream, m);
ee8d9305 438 if (r < 0)
3f548fff 439 return log_error_errno(r, "LLMNR-IPv6(TCP): Failed to create event source: %m");
5f402ae8 440
aa4a9deb
LP
441 (void) sd_event_source_set_description(m->llmnr_ipv6_tcp_event_source, "llmnr-ipv6-tcp");
442
3f548fff 443 return m->llmnr_ipv6_tcp_fd = TAKE_FD(s);
5f402ae8 444}