]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-stub.c
Merge pull request #11827 from keszybz/pkgconfig-variables
[thirdparty/systemd.git] / src / resolve / resolved-dns-stub.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
b30bf55d
LP
2
3#include "fd-util.h"
ef118d00 4#include "missing_network.h"
b30bf55d
LP
5#include "resolved-dns-stub.h"
6#include "socket-util.h"
7
8/* The MTU of the loopback device is 64K on Linux, advertise that as maximum datagram size, but subtract the Ethernet,
9 * IP and UDP header sizes */
10#define ADVERTISE_DATAGRAM_SIZE_MAX (65536U-14U-20U-8U)
11
424e490b
ZJS
12static int manager_dns_stub_udp_fd(Manager *m);
13static int manager_dns_stub_tcp_fd(Manager *m);
14
b30bf55d 15static int dns_stub_make_reply_packet(
e8d23f92 16 DnsPacket **p,
51027656 17 size_t max_size,
b30bf55d 18 DnsQuestion *q,
51027656
LP
19 DnsAnswer *answer,
20 bool *ret_truncated) {
b30bf55d 21
51027656 22 bool truncated = false;
b30bf55d
LP
23 DnsResourceRecord *rr;
24 unsigned c = 0;
25 int r;
26
e8d23f92
LP
27 assert(p);
28
b30bf55d
LP
29 /* Note that we don't bother with any additional RRs, as this is stub is for local lookups only, and hence
30 * roundtrips aren't expensive. */
31
e8d23f92 32 if (!*p) {
51027656 33 r = dns_packet_new(p, DNS_PROTOCOL_DNS, 0, max_size);
e8d23f92
LP
34 if (r < 0)
35 return r;
b30bf55d 36
e8d23f92
LP
37 r = dns_packet_append_question(*p, q);
38 if (r < 0)
39 return r;
b30bf55d 40
e8d23f92
LP
41 DNS_PACKET_HEADER(*p)->qdcount = htobe16(dns_question_size(q));
42 }
b30bf55d
LP
43
44 DNS_ANSWER_FOREACH(rr, answer) {
e8d23f92 45
b30bf55d
LP
46 r = dns_question_matches_rr(q, rr, NULL);
47 if (r < 0)
48 return r;
49 if (r > 0)
50 goto add;
51
52 r = dns_question_matches_cname_or_dname(q, rr, NULL);
53 if (r < 0)
54 return r;
55 if (r > 0)
56 goto add;
57
58 continue;
59 add:
01c901e2 60 r = dns_packet_append_rr(*p, rr, 0, NULL, NULL);
51027656
LP
61 if (r == -EMSGSIZE) {
62 truncated = true;
63 break;
64 }
b30bf55d
LP
65 if (r < 0)
66 return r;
67
68 c++;
69 }
e8d23f92 70
51027656
LP
71 if (ret_truncated)
72 *ret_truncated = truncated;
73 else if (truncated)
74 return -EMSGSIZE;
75
e8d23f92
LP
76 DNS_PACKET_HEADER(*p)->ancount = htobe16(be16toh(DNS_PACKET_HEADER(*p)->ancount) + c);
77
78 return 0;
79}
80
81static int dns_stub_finish_reply_packet(
82 DnsPacket *p,
83 uint16_t id,
84 int rcode,
51027656 85 bool tc, /* set the Truncated bit? */
e8d23f92
LP
86 bool add_opt, /* add an OPT RR to this packet? */
87 bool edns0_do, /* set the EDNS0 DNSSEC OK bit? */
88 bool ad) { /* set the DNSSEC authenticated data bit? */
89
90 int r;
91
92 assert(p);
93
941dd294
LP
94 if (!add_opt) {
95 /* If the client can't to EDNS0, don't do DO either */
96 edns0_do = false;
97
98 /* If the client didn't do EDNS, clamp the rcode to 4 bit */
99 if (rcode > 0xF)
100 rcode = DNS_RCODE_SERVFAIL;
101 }
102
103 /* Don't set the AD bit unless DO is on, too */
104 if (!edns0_do)
105 ad = false;
e8d23f92
LP
106
107 DNS_PACKET_HEADER(p)->id = id;
108
109 DNS_PACKET_HEADER(p)->flags = htobe16(DNS_PACKET_MAKE_FLAGS(
51027656
LP
110 1 /* qr */,
111 0 /* opcode */,
112 0 /* aa */,
113 tc /* tc */,
114 1 /* rd */,
115 1 /* ra */,
e8d23f92 116 ad /* ad */,
51027656 117 0 /* cd */,
e8d23f92 118 rcode));
b30bf55d
LP
119
120 if (add_opt) {
121 r = dns_packet_append_opt(p, ADVERTISE_DATAGRAM_SIZE_MAX, edns0_do, rcode, NULL);
122 if (r < 0)
123 return r;
124 }
125
b30bf55d
LP
126 return 0;
127}
128
b30bf55d
LP
129static int dns_stub_send(Manager *m, DnsStream *s, DnsPacket *p, DnsPacket *reply) {
130 int r;
131
132 assert(m);
133 assert(p);
134 assert(reply);
135
136 if (s)
137 r = dns_stream_write_packet(s, reply);
138 else {
139 int fd;
140
b30bf55d
LP
141 fd = manager_dns_stub_udp_fd(m);
142 if (fd < 0)
143 return log_debug_errno(fd, "Failed to get reply socket: %m");
144
145 /* Note that it is essential here that we explicitly choose the source IP address for this packet. This
146 * is because otherwise the kernel will choose it automatically based on the routing table and will
147 * thus pick 127.0.0.1 rather than 127.0.0.53. */
148
149 r = manager_send(m, fd, LOOPBACK_IFINDEX, p->family, &p->sender, p->sender_port, &p->destination, reply);
150 }
151 if (r < 0)
152 return log_debug_errno(r, "Failed to send reply packet: %m");
153
154 return 0;
155}
156
2b2d98c1 157static int dns_stub_send_failure(Manager *m, DnsStream *s, DnsPacket *p, int rcode, bool authenticated) {
b30bf55d
LP
158 _cleanup_(dns_packet_unrefp) DnsPacket *reply = NULL;
159 int r;
160
161 assert(m);
162 assert(p);
163
51027656 164 r = dns_stub_make_reply_packet(&reply, DNS_PACKET_PAYLOAD_SIZE_MAX(p), p->question, NULL, NULL);
e8d23f92
LP
165 if (r < 0)
166 return log_debug_errno(r, "Failed to make failure packet: %m");
167
51027656 168 r = dns_stub_finish_reply_packet(reply, DNS_PACKET_ID(p), rcode, false, !!p->opt, DNS_PACKET_DO(p), authenticated);
b30bf55d
LP
169 if (r < 0)
170 return log_debug_errno(r, "Failed to build failure packet: %m");
171
172 return dns_stub_send(m, s, p, reply);
173}
174
175static void dns_stub_query_complete(DnsQuery *q) {
176 int r;
177
178 assert(q);
179 assert(q->request_dns_packet);
180
181 switch (q->state) {
182
51027656
LP
183 case DNS_TRANSACTION_SUCCESS: {
184 bool truncated;
e8d23f92 185
51027656 186 r = dns_stub_make_reply_packet(&q->reply_dns_packet, DNS_PACKET_PAYLOAD_SIZE_MAX(q->request_dns_packet), q->question_idna, q->answer, &truncated);
e8d23f92
LP
187 if (r < 0) {
188 log_debug_errno(r, "Failed to build reply packet: %m");
189 break;
190 }
b30bf55d 191
e8d23f92
LP
192 r = dns_query_process_cname(q);
193 if (r == -ELOOP) {
2b2d98c1 194 (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, DNS_RCODE_SERVFAIL, false);
e8d23f92
LP
195 break;
196 }
197 if (r < 0) {
198 log_debug_errno(r, "Failed to process CNAME: %m");
199 break;
200 }
201 if (r == DNS_QUERY_RESTARTED)
202 return;
203
204 r = dns_stub_finish_reply_packet(
205 q->reply_dns_packet,
b30bf55d
LP
206 DNS_PACKET_ID(q->request_dns_packet),
207 q->answer_rcode,
51027656 208 truncated,
b30bf55d
LP
209 !!q->request_dns_packet->opt,
210 DNS_PACKET_DO(q->request_dns_packet),
941dd294 211 dns_query_fully_authenticated(q));
b30bf55d 212 if (r < 0) {
e8d23f92 213 log_debug_errno(r, "Failed to finish reply packet: %m");
b30bf55d
LP
214 break;
215 }
216
e8d23f92 217 (void) dns_stub_send(q->manager, q->request_dns_stream, q->request_dns_packet, q->reply_dns_packet);
b30bf55d 218 break;
51027656 219 }
b30bf55d
LP
220
221 case DNS_TRANSACTION_RCODE_FAILURE:
2b2d98c1 222 (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, q->answer_rcode, dns_query_fully_authenticated(q));
b30bf55d
LP
223 break;
224
225 case DNS_TRANSACTION_NOT_FOUND:
2b2d98c1 226 (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, DNS_RCODE_NXDOMAIN, dns_query_fully_authenticated(q));
b30bf55d
LP
227 break;
228
229 case DNS_TRANSACTION_TIMEOUT:
230 case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
231 /* Propagate a timeout as a no packet, i.e. that the client also gets a timeout */
232 break;
233
234 case DNS_TRANSACTION_NO_SERVERS:
235 case DNS_TRANSACTION_INVALID_REPLY:
236 case DNS_TRANSACTION_ERRNO:
237 case DNS_TRANSACTION_ABORTED:
238 case DNS_TRANSACTION_DNSSEC_FAILED:
239 case DNS_TRANSACTION_NO_TRUST_ANCHOR:
240 case DNS_TRANSACTION_RR_TYPE_UNSUPPORTED:
241 case DNS_TRANSACTION_NETWORK_DOWN:
2b2d98c1 242 (void) dns_stub_send_failure(q->manager, q->request_dns_stream, q->request_dns_packet, DNS_RCODE_SERVFAIL, false);
b30bf55d
LP
243 break;
244
245 case DNS_TRANSACTION_NULL:
246 case DNS_TRANSACTION_PENDING:
247 case DNS_TRANSACTION_VALIDATING:
248 default:
249 assert_not_reached("Impossible state");
250 }
251
b30bf55d
LP
252 dns_query_free(q);
253}
254
255static int dns_stub_stream_complete(DnsStream *s, int error) {
256 assert(s);
257
b412af57
LP
258 log_debug_errno(error, "DNS TCP connection terminated, destroying queries: %m");
259
260 for (;;) {
261 DnsQuery *q;
262
263 q = set_first(s->queries);
264 if (!q)
265 break;
b30bf55d 266
b412af57
LP
267 dns_query_free(q);
268 }
b30bf55d 269
b412af57
LP
270 /* This drops the implicit ref we keep around since it was allocated, as incoming stub connections
271 * should be kept as long as the client wants to. */
272 dns_stream_unref(s);
b30bf55d
LP
273 return 0;
274}
275
276static void dns_stub_process_query(Manager *m, DnsStream *s, DnsPacket *p) {
277 DnsQuery *q = NULL;
278 int r;
279
280 assert(m);
281 assert(p);
282 assert(p->protocol == DNS_PROTOCOL_DNS);
283
b30bf55d
LP
284 if (in_addr_is_localhost(p->family, &p->sender) <= 0 ||
285 in_addr_is_localhost(p->family, &p->destination) <= 0) {
286 log_error("Got packet on unexpected IP range, refusing.");
2b2d98c1 287 dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
b30bf55d
LP
288 goto fail;
289 }
290
291 r = dns_packet_extract(p);
292 if (r < 0) {
293 log_debug_errno(r, "Failed to extract resources from incoming packet, ignoring packet: %m");
2b2d98c1 294 dns_stub_send_failure(m, s, p, DNS_RCODE_FORMERR, false);
b30bf55d
LP
295 goto fail;
296 }
297
298 if (!DNS_PACKET_VERSION_SUPPORTED(p)) {
299 log_debug("Got EDNS OPT field with unsupported version number.");
2b2d98c1 300 dns_stub_send_failure(m, s, p, DNS_RCODE_BADVERS, false);
b30bf55d
LP
301 goto fail;
302 }
303
304 if (dns_type_is_obsolete(p->question->keys[0]->type)) {
305 log_debug("Got message with obsolete key type, refusing.");
2b2d98c1 306 dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
b30bf55d
LP
307 goto fail;
308 }
309
310 if (dns_type_is_zone_transer(p->question->keys[0]->type)) {
311 log_debug("Got request for zone transfer, refusing.");
2b2d98c1 312 dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
b30bf55d
LP
313 goto fail;
314 }
315
316 if (!DNS_PACKET_RD(p)) {
317 /* If the "rd" bit is off (i.e. recursion was not requested), then refuse operation */
318 log_debug("Got request with recursion disabled, refusing.");
2b2d98c1 319 dns_stub_send_failure(m, s, p, DNS_RCODE_REFUSED, false);
b30bf55d
LP
320 goto fail;
321 }
322
323 if (DNS_PACKET_DO(p) && DNS_PACKET_CD(p)) {
324 log_debug("Got request with DNSSEC CD bit set, refusing.");
2b2d98c1 325 dns_stub_send_failure(m, s, p, DNS_RCODE_NOTIMP, false);
b30bf55d
LP
326 goto fail;
327 }
328
e8d23f92 329 r = dns_query_new(m, &q, p->question, p->question, 0, SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_SEARCH);
b30bf55d
LP
330 if (r < 0) {
331 log_error_errno(r, "Failed to generate query object: %m");
2b2d98c1 332 dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
b30bf55d
LP
333 goto fail;
334 }
335
336 /* Request that the TTL is corrected by the cached time for this lookup, so that we return vaguely useful TTLs */
337 q->clamp_ttl = true;
338
339 q->request_dns_packet = dns_packet_ref(p);
340 q->request_dns_stream = dns_stream_ref(s); /* make sure the stream stays around until we can send a reply through it */
341 q->complete = dns_stub_query_complete;
342
343 if (s) {
b412af57
LP
344 /* Remember which queries belong to this stream, so that we can cancel them when the stream
345 * is disconnected early */
346
347 r = set_ensure_allocated(&s->queries, &trivial_hash_ops);
348 if (r < 0) {
349 log_oom();
350 goto fail;
351 }
352
353 if (set_put(s->queries, q) < 0) {
354 log_oom();
355 goto fail;
356 }
b30bf55d
LP
357 }
358
359 r = dns_query_go(q);
360 if (r < 0) {
361 log_error_errno(r, "Failed to start query: %m");
2b2d98c1 362 dns_stub_send_failure(m, s, p, DNS_RCODE_SERVFAIL, false);
b30bf55d
LP
363 goto fail;
364 }
365
52e63427 366 log_debug("Processing query...");
b30bf55d
LP
367 return;
368
369fail:
b30bf55d
LP
370 dns_query_free(q);
371}
372
373static int on_dns_stub_packet(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
374 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
375 Manager *m = userdata;
376 int r;
377
378 r = manager_recv(m, fd, DNS_PROTOCOL_DNS, &p);
379 if (r <= 0)
380 return r;
381
382 if (dns_packet_validate_query(p) > 0) {
383 log_debug("Got DNS stub UDP query packet for id %u", DNS_PACKET_ID(p));
384
385 dns_stub_process_query(m, NULL, p);
386 } else
387 log_debug("Invalid DNS stub UDP packet, ignoring.");
388
389 return 0;
390}
391
424e490b 392static int manager_dns_stub_udp_fd(Manager *m) {
b30bf55d
LP
393 union sockaddr_union sa = {
394 .in.sin_family = AF_INET,
395 .in.sin_port = htobe16(53),
396 .in.sin_addr.s_addr = htobe32(INADDR_DNS_STUB),
397 };
424e490b 398 _cleanup_close_ int fd = -1;
b30bf55d
LP
399 int r;
400
401 if (m->dns_stub_udp_fd >= 0)
402 return m->dns_stub_udp_fd;
403
424e490b
ZJS
404 fd = socket(AF_INET, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
405 if (fd < 0)
b30bf55d
LP
406 return -errno;
407
2ff48e98
LP
408 r = setsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR, true);
409 if (r < 0)
410 return r;
b30bf55d 411
2ff48e98
LP
412 r = setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, true);
413 if (r < 0)
414 return r;
b30bf55d 415
2ff48e98
LP
416 r = setsockopt_int(fd, IPPROTO_IP, IP_RECVTTL, true);
417 if (r < 0)
418 return r;
b30bf55d
LP
419
420 /* Make sure no traffic from outside the local host can leak to onto this socket */
424e490b
ZJS
421 if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, "lo", 3) < 0)
422 return -errno;
b30bf55d 423
424e490b
ZJS
424 if (bind(fd, &sa.sa, sizeof(sa.in)) < 0)
425 return -errno;
b30bf55d 426
424e490b 427 r = sd_event_add_io(m->event, &m->dns_stub_udp_event_source, fd, EPOLLIN, on_dns_stub_packet, m);
b30bf55d 428 if (r < 0)
424e490b 429 return r;
b30bf55d
LP
430
431 (void) sd_event_source_set_description(m->dns_stub_udp_event_source, "dns-stub-udp");
432
c10d6bdb 433 return m->dns_stub_udp_fd = TAKE_FD(fd);
b30bf55d
LP
434}
435
436static int on_dns_stub_stream_packet(DnsStream *s) {
aa337a5e
LP
437 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
438
b30bf55d 439 assert(s);
b30bf55d 440
aa337a5e
LP
441 p = dns_stream_take_read_packet(s);
442 assert(p);
443
444 if (dns_packet_validate_query(p) > 0) {
445 log_debug("Got DNS stub TCP query packet for id %u", DNS_PACKET_ID(p));
b30bf55d 446
aa337a5e 447 dns_stub_process_query(s->manager, s, p);
b30bf55d
LP
448 } else
449 log_debug("Invalid DNS stub TCP packet, ignoring.");
450
b30bf55d
LP
451 return 0;
452}
453
454static int on_dns_stub_stream(sd_event_source *s, int fd, uint32_t revents, void *userdata) {
455 DnsStream *stream;
456 Manager *m = userdata;
457 int cfd, r;
458
459 cfd = accept4(fd, NULL, NULL, SOCK_NONBLOCK|SOCK_CLOEXEC);
460 if (cfd < 0) {
3742095b 461 if (IN_SET(errno, EAGAIN, EINTR))
b30bf55d
LP
462 return 0;
463
464 return -errno;
465 }
466
652ba568 467 r = dns_stream_new(m, &stream, DNS_STREAM_STUB, DNS_PROTOCOL_DNS, cfd, NULL);
b30bf55d
LP
468 if (r < 0) {
469 safe_close(cfd);
470 return r;
471 }
472
473 stream->on_packet = on_dns_stub_stream_packet;
b412af57 474 stream->complete = dns_stub_stream_complete;
b30bf55d 475
b412af57 476 /* We let the reference to the stream dangle here, it will be dropped later by the complete callback. */
b30bf55d
LP
477
478 return 0;
479}
480
424e490b 481static int manager_dns_stub_tcp_fd(Manager *m) {
b30bf55d
LP
482 union sockaddr_union sa = {
483 .in.sin_family = AF_INET,
484 .in.sin_addr.s_addr = htobe32(INADDR_DNS_STUB),
485 .in.sin_port = htobe16(53),
486 };
424e490b 487 _cleanup_close_ int fd = -1;
b30bf55d
LP
488 int r;
489
490 if (m->dns_stub_tcp_fd >= 0)
491 return m->dns_stub_tcp_fd;
492
424e490b
ZJS
493 fd = socket(AF_INET, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
494 if (fd < 0)
b30bf55d
LP
495 return -errno;
496
2ff48e98
LP
497 r = setsockopt_int(fd, IPPROTO_IP, IP_TTL, true);
498 if (r < 0)
499 return r;
b30bf55d 500
2ff48e98
LP
501 r = setsockopt_int(fd, SOL_SOCKET, SO_REUSEADDR, true);
502 if (r < 0)
503 return r;
b30bf55d 504
2ff48e98
LP
505 r = setsockopt_int(fd, IPPROTO_IP, IP_PKTINFO, true);
506 if (r < 0)
507 return r;
b30bf55d 508
2ff48e98
LP
509 r = setsockopt_int(fd, IPPROTO_IP, IP_RECVTTL, true);
510 if (r < 0)
511 return r;
b30bf55d
LP
512
513 /* Make sure no traffic from outside the local host can leak to onto this socket */
424e490b
ZJS
514 if (setsockopt(fd, SOL_SOCKET, SO_BINDTODEVICE, "lo", 3) < 0)
515 return -errno;
b30bf55d 516
424e490b
ZJS
517 if (bind(fd, &sa.sa, sizeof(sa.in)) < 0)
518 return -errno;
b30bf55d 519
424e490b
ZJS
520 if (listen(fd, SOMAXCONN) < 0)
521 return -errno;
b30bf55d 522
424e490b 523 r = sd_event_add_io(m->event, &m->dns_stub_tcp_event_source, fd, EPOLLIN, on_dns_stub_stream, m);
b30bf55d 524 if (r < 0)
424e490b 525 return r;
b30bf55d
LP
526
527 (void) sd_event_source_set_description(m->dns_stub_tcp_event_source, "dns-stub-tcp");
528
c10d6bdb 529 return m->dns_stub_tcp_fd = TAKE_FD(fd);
b30bf55d
LP
530}
531
532int manager_dns_stub_start(Manager *m) {
424e490b 533 const char *t = "UDP";
01b0669e 534 int r = 0;
b30bf55d
LP
535
536 assert(m);
537
d5da7707
ZJS
538 if (m->dns_stub_listener_mode == DNS_STUB_LISTENER_NO)
539 log_debug("Not creating stub listener.");
540 else
541 log_debug("Creating stub listener using %s.",
542 m->dns_stub_listener_mode == DNS_STUB_LISTENER_UDP ? "UDP" :
543 m->dns_stub_listener_mode == DNS_STUB_LISTENER_TCP ? "TCP" :
544 "UDP/TCP");
545
424e490b 546 if (IN_SET(m->dns_stub_listener_mode, DNS_STUB_LISTENER_YES, DNS_STUB_LISTENER_UDP))
1ae43295 547 r = manager_dns_stub_udp_fd(m);
b30bf55d 548
424e490b
ZJS
549 if (r >= 0 &&
550 IN_SET(m->dns_stub_listener_mode, DNS_STUB_LISTENER_YES, DNS_STUB_LISTENER_TCP)) {
551 t = "TCP";
1ae43295 552 r = manager_dns_stub_tcp_fd(m);
1ae43295 553 }
b30bf55d 554
0f4db364
ZJS
555 if (IN_SET(r, -EADDRINUSE, -EPERM)) {
556 if (r == -EADDRINUSE)
557 log_warning_errno(r,
558 "Another process is already listening on %s socket 127.0.0.53:53.\n"
559 "Turning off local DNS stub support.", t);
560 else
561 log_warning_errno(r,
562 "Failed to listen on %s socket 127.0.0.53:53: %m.\n"
563 "Turning off local DNS stub support.", t);
424e490b
ZJS
564 manager_dns_stub_stop(m);
565 } else if (r < 0)
566 return log_error_errno(r, "Failed to listen on %s socket 127.0.0.53:53: %m", t);
b30bf55d
LP
567
568 return 0;
569}
570
571void manager_dns_stub_stop(Manager *m) {
572 assert(m);
573
574 m->dns_stub_udp_event_source = sd_event_source_unref(m->dns_stub_udp_event_source);
575 m->dns_stub_tcp_event_source = sd_event_source_unref(m->dns_stub_tcp_event_source);
576
577 m->dns_stub_udp_fd = safe_close(m->dns_stub_udp_fd);
578 m->dns_stub_tcp_fd = safe_close(m->dns_stub_tcp_fd);
579}