]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-bus.c
resolved: implement LLMNR uniqueness verification
[thirdparty/systemd.git] / src / resolve / resolved-bus.c
CommitLineData
74b2466e
LP
1/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3/***
4 This file is part of systemd.
5
6 Copyright 2014 Lennart Poettering
7
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
12
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
17
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
20***/
21
22#include "bus-errors.h"
23#include "bus-util.h"
24
25#include "resolved.h"
26#include "resolved-dns-domain.h"
27
ad867662
LP
28static int reply_query_state(DnsQuery *q) {
29 _cleanup_free_ char *ip = NULL;
30 const char *name;
74b2466e
LP
31 int r;
32
ad867662
LP
33 if (q->request_hostname)
34 name = q->request_hostname;
35 else {
36 r = in_addr_to_string(q->request_family, &q->request_address, &ip);
37 if (r < 0)
38 return r;
74b2466e 39
ad867662
LP
40 name = ip;
41 }
42
43 switch (q->state) {
74b2466e 44
ec2c5e43 45 case DNS_TRANSACTION_NO_SERVERS:
309e9d86 46 return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
74b2466e 47
ec2c5e43 48 case DNS_TRANSACTION_TIMEOUT:
ad867662 49 return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
74b2466e 50
ec2c5e43 51 case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
ad867662
LP
52 return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
53
ec2c5e43 54 case DNS_TRANSACTION_RESOURCES:
ad867662
LP
55 return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_RESOURCES, "Not enough resources");
56
ec2c5e43 57 case DNS_TRANSACTION_INVALID_REPLY:
ad867662 58 return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
74b2466e 59
ec2c5e43 60 case DNS_TRANSACTION_FAILURE: {
74b2466e
LP
61 _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
62
faa133f3 63 if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
ad867662 64 sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", name);
74b2466e
LP
65 else {
66 const char *rc, *n;
ad867662 67 char p[3]; /* the rcode is 4 bits long */
74b2466e 68
faa133f3 69 rc = dns_rcode_to_string(q->answer_rcode);
74b2466e 70 if (!rc) {
faa133f3 71 sprintf(p, "%i", q->answer_rcode);
74b2466e
LP
72 rc = p;
73 }
74
75 n = strappenda(_BUS_ERROR_DNS, rc);
ad867662 76 sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", name, rc);
74b2466e
LP
77 }
78
ad867662 79 return sd_bus_reply_method_error(q->request, &error);
74b2466e
LP
80 }
81
ec2c5e43
LP
82 case DNS_TRANSACTION_NULL:
83 case DNS_TRANSACTION_PENDING:
84 case DNS_TRANSACTION_SUCCESS:
8ba9fd9c 85 default:
ad867662
LP
86 assert_not_reached("Impossible state");
87 }
88}
74b2466e 89
8ba9fd9c
LP
90static int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex) {
91 int r;
92
93 assert(reply);
94 assert(rr);
95
0dd25fb9 96 r = sd_bus_message_open_container(reply, 'r', "iayi");
8ba9fd9c
LP
97 if (r < 0)
98 return r;
99
faa133f3 100 if (rr->key->type == DNS_TYPE_A) {
0dd25fb9 101 r = sd_bus_message_append(reply, "i", AF_INET);
8ba9fd9c
LP
102 if (r < 0)
103 return r;
104
105 r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr));
faa133f3
LP
106
107 } else if (rr->key->type == DNS_TYPE_AAAA) {
0dd25fb9 108 r = sd_bus_message_append(reply, "i", AF_INET6);
8ba9fd9c
LP
109 if (r < 0)
110 return r;
111
112 r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr));
faa133f3
LP
113 } else
114 return -EAFNOSUPPORT;
115
8ba9fd9c
LP
116 if (r < 0)
117 return r;
118
119 r = sd_bus_message_append(reply, "i", ifindex);
120 if (r < 0)
121 return r;
122
123 r = sd_bus_message_close_container(reply);
124 if (r < 0)
125 return r;
126
127 return 0;
128}
129
ad867662 130static void bus_method_resolve_hostname_complete(DnsQuery *q) {
309e9d86 131 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *canonical = NULL;
ad867662 132 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
faa133f3
LP
133 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
134 unsigned added = 0, i;
135 int r, ifindex;
74b2466e 136
ad867662 137 assert(q);
74b2466e 138
ec2c5e43 139 if (q->state != DNS_TRANSACTION_SUCCESS) {
ad867662
LP
140 r = reply_query_state(q);
141 goto finish;
142 }
74b2466e 143
ad867662
LP
144 r = sd_bus_message_new_method_return(q->request, &reply);
145 if (r < 0)
146 goto finish;
74b2466e 147
0dd25fb9 148 r = sd_bus_message_open_container(reply, 'a', "(iayi)");
ad867662
LP
149 if (r < 0)
150 goto finish;
74b2466e 151
faa133f3 152 ifindex = q->answer_ifindex;
8ba9fd9c 153
3339cb71
LP
154 if (q->answer) {
155 answer = dns_answer_ref(q->answer);
156
157 for (i = 0; i < answer->n_rrs; i++) {
158 r = dns_question_matches_rr(q->question, answer->rrs[i]);
8ba9fd9c 159 if (r < 0)
2d4c5cbc 160 goto finish;
3339cb71
LP
161 if (r == 0) {
162 /* Hmm, if this is not an address record,
163 maybe it's a cname? If so, remember this */
164 r = dns_question_matches_cname(q->question, answer->rrs[i]);
165 if (r < 0)
2d4c5cbc 166 goto finish;
3339cb71
LP
167 if (r > 0)
168 cname = dns_resource_record_ref(answer->rrs[i]);
74b2466e 169
3339cb71
LP
170 continue;
171 }
74b2466e 172
3339cb71
LP
173 r = append_address(reply, answer->rrs[i], ifindex);
174 if (r < 0)
175 goto finish;
74b2466e 176
3339cb71
LP
177 if (!canonical)
178 canonical = dns_resource_record_ref(answer->rrs[i]);
309e9d86 179
3339cb71
LP
180 added ++;
181 }
8ba9fd9c 182 }
74b2466e 183
8ba9fd9c
LP
184 if (added <= 0) {
185 if (!cname) {
309e9d86 186 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of requested type", q->request_hostname);
ad867662 187 goto finish;
8ba9fd9c 188 }
74b2466e 189
8ba9fd9c
LP
190 /* This has a cname? Then update the query with the
191 * new cname. */
322345fd 192 r = dns_query_cname_redirect(q, cname->cname.name);
8ba9fd9c
LP
193 if (r < 0) {
194 if (r == -ELOOP)
195 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop on '%s'", q->request_hostname);
196 else
197 r = sd_bus_reply_method_errno(q->request, -r, NULL);
74b2466e 198
74b2466e 199 goto finish;
8ba9fd9c 200 }
74b2466e 201
8ba9fd9c
LP
202 /* Before we restart the query, let's see if any of
203 * the RRs we already got already answers our query */
faa133f3
LP
204 for (i = 0; i < answer->n_rrs; i++) {
205 r = dns_question_matches_rr(q->question, answer->rrs[i]);
8ba9fd9c 206 if (r < 0)
2d4c5cbc 207 goto finish;
8ba9fd9c
LP
208 if (r == 0)
209 continue;
210
faa133f3 211 r = append_address(reply, answer->rrs[i], ifindex);
8ba9fd9c
LP
212 if (r < 0)
213 goto finish;
214
309e9d86 215 if (!canonical)
faa133f3 216 canonical = dns_resource_record_ref(answer->rrs[i]);
309e9d86 217
8ba9fd9c
LP
218 added++;
219 }
220
221 /* If we didn't find anything, then let's restart the
222 * query, this time with the cname */
223 if (added <= 0) {
322345fd 224 r = dns_query_go(q);
309e9d86
LP
225 if (r == -ESRCH) {
226 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
227 goto finish;
228 }
8ba9fd9c
LP
229 if (r < 0) {
230 r = sd_bus_reply_method_errno(q->request, -r, NULL);
231 goto finish;
232 }
2d4c5cbc 233
8ba9fd9c
LP
234 return;
235 }
74b2466e
LP
236 }
237
ad867662
LP
238 r = sd_bus_message_close_container(reply);
239 if (r < 0)
240 goto finish;
241
309e9d86
LP
242 /* Return the precise spelling and uppercasing reported by the server */
243 assert(canonical);
faa133f3 244 r = sd_bus_message_append(reply, "s", DNS_RESOURCE_KEY_NAME(canonical->key));
309e9d86
LP
245 if (r < 0)
246 goto finish;
247
ad867662 248 r = sd_bus_send(q->manager->bus, reply, NULL);
ad867662 249
74b2466e 250finish:
2d4c5cbc
LP
251 if (r < 0) {
252 log_error("Failed to send hostname reply: %s", strerror(-r));
253 sd_bus_reply_method_errno(q->request, -r, NULL);
254 }
74b2466e
LP
255
256 dns_query_free(q);
257}
258
259static int bus_method_resolve_hostname(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
faa133f3 260 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
74b2466e
LP
261 Manager *m = userdata;
262 const char *hostname;
0dd25fb9 263 int family;
74b2466e 264 DnsQuery *q;
74b2466e
LP
265 int r;
266
267 assert(bus);
268 assert(message);
269 assert(m);
270
0dd25fb9 271 r = sd_bus_message_read(message, "si", &hostname, &family);
74b2466e
LP
272 if (r < 0)
273 return r;
274
275 if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
0dd25fb9 276 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
74b2466e
LP
277
278 if (!hostname_is_valid(hostname))
279 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
280
faa133f3
LP
281 question = dns_question_new(family == AF_UNSPEC ? 2 : 1);
282 if (!question)
283 return -ENOMEM;
284
74b2466e 285 if (family != AF_INET6) {
faa133f3
LP
286 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
287
288 key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, hostname);
289 if (!key)
290 return -ENOMEM;
291
292 r = dns_question_add(question, key);
293 if (r < 0)
294 return r;
74b2466e
LP
295 }
296
297 if (family != AF_INET) {
faa133f3
LP
298 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
299
300 key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, hostname);
301 if (!key)
302 return -ENOMEM;
303
304 r = dns_question_add(question, key);
305 if (r < 0)
306 return r;
74b2466e
LP
307 }
308
faa133f3 309 r = dns_query_new(m, &q, question);
74b2466e
LP
310 if (r < 0)
311 return r;
312
313 q->request = sd_bus_message_ref(message);
314 q->request_family = family;
315 q->request_hostname = hostname;
316 q->complete = bus_method_resolve_hostname_complete;
317
322345fd 318 r = dns_query_go(q);
74b2466e
LP
319 if (r < 0) {
320 dns_query_free(q);
309e9d86
LP
321
322 if (r == -ESRCH)
323 sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
324
74b2466e
LP
325 return r;
326 }
327
328 return 1;
329}
330
331static void bus_method_resolve_address_complete(DnsQuery *q) {
ad867662 332 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
faa133f3
LP
333 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
334 unsigned added = 0, i;
335 int r;
74b2466e
LP
336
337 assert(q);
338
ec2c5e43 339 if (q->state != DNS_TRANSACTION_SUCCESS) {
ad867662
LP
340 r = reply_query_state(q);
341 goto finish;
342 }
74b2466e 343
ad867662
LP
344 r = sd_bus_message_new_method_return(q->request, &reply);
345 if (r < 0)
346 goto finish;
74b2466e 347
ad867662
LP
348 r = sd_bus_message_open_container(reply, 'a', "s");
349 if (r < 0)
350 goto finish;
74b2466e 351
3339cb71
LP
352 if (q->answer) {
353 answer = dns_answer_ref(q->answer);
faa133f3 354
3339cb71
LP
355 for (i = 0; i < answer->n_rrs; i++) {
356 r = dns_question_matches_rr(q->question, answer->rrs[i]);
357 if (r < 0)
2d4c5cbc 358 goto finish;
3339cb71
LP
359 if (r == 0)
360 continue;
74b2466e 361
3339cb71
LP
362 r = sd_bus_message_append(reply, "s", answer->rrs[i]->ptr.name);
363 if (r < 0)
364 goto finish;
74b2466e 365
3339cb71
LP
366 added ++;
367 }
ad867662 368 }
74b2466e 369
ad867662
LP
370 if (added <= 0) {
371 _cleanup_free_ char *ip = NULL;
74b2466e 372
ad867662 373 in_addr_to_string(q->request_family, &q->request_address, &ip);
74b2466e 374
309e9d86 375 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", ip);
ad867662 376 goto finish;
74b2466e
LP
377 }
378
ad867662
LP
379 r = sd_bus_message_close_container(reply);
380 if (r < 0)
381 goto finish;
74b2466e 382
ad867662 383 r = sd_bus_send(q->manager->bus, reply, NULL);
74b2466e
LP
384
385finish:
2d4c5cbc
LP
386 if (r < 0) {
387 log_error("Failed to send address reply: %s", strerror(-r));
388 sd_bus_reply_method_errno(q->request, -r, NULL);
389 }
74b2466e
LP
390
391 dns_query_free(q);
392}
393
394static int bus_method_resolve_address(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
faa133f3
LP
395 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
396 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
397 _cleanup_free_ char *reverse = NULL;
74b2466e 398 Manager *m = userdata;
faa133f3 399 int family, ifindex;
74b2466e 400 const void *d;
74b2466e
LP
401 DnsQuery *q;
402 size_t sz;
403 int r;
404
405 assert(bus);
406 assert(message);
407 assert(m);
408
0dd25fb9 409 r = sd_bus_message_read(message, "i", &family);
74b2466e
LP
410 if (r < 0)
411 return r;
412
413 if (!IN_SET(family, AF_INET, AF_INET6))
0dd25fb9 414 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
74b2466e
LP
415
416 r = sd_bus_message_read_array(message, 'y', &d, &sz);
417 if (r < 0)
418 return r;
419
0dd25fb9 420 if (sz != FAMILY_ADDRESS_SIZE(family))
74b2466e
LP
421 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
422
423 r = sd_bus_message_read(message, "i", &ifindex);
424 if (r < 0)
425 return r;
426 if (ifindex < 0)
427 return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
428
faa133f3
LP
429 r = dns_name_reverse(family, d, &reverse);
430 if (r < 0)
431 return r;
432
433 question = dns_question_new(1);
434 if (!question)
435 return -ENOMEM;
436
437 key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, reverse);
438 if (!key)
439 return -ENOMEM;
440
441 reverse = NULL;
442
443 r = dns_question_add(question, key);
74b2466e
LP
444 if (r < 0)
445 return r;
446
faa133f3 447 r = dns_query_new(m, &q, question);
74b2466e
LP
448 if (r < 0)
449 return r;
450
451 q->request = sd_bus_message_ref(message);
452 q->request_family = family;
453 memcpy(&q->request_address, d, sz);
454 q->complete = bus_method_resolve_address_complete;
455
322345fd 456 r = dns_query_go(q);
74b2466e
LP
457 if (r < 0) {
458 dns_query_free(q);
faa133f3
LP
459
460 if (r == -ESRCH)
461 sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
462
74b2466e
LP
463 return r;
464 }
465
466 return 1;
467}
468
2d4c5cbc
LP
469static void bus_method_resolve_record_complete(DnsQuery *q) {
470 _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
471 _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
472 unsigned added = 0, i;
473 int r;
474
475 assert(q);
476
ec2c5e43 477 if (q->state != DNS_TRANSACTION_SUCCESS) {
2d4c5cbc
LP
478 r = reply_query_state(q);
479 goto finish;
480 }
481
482 r = sd_bus_message_new_method_return(q->request, &reply);
483 if (r < 0)
484 goto finish;
485
486 r = sd_bus_message_open_container(reply, 'a', "(qqay)");
487 if (r < 0)
488 goto finish;
489
490 if (q->answer) {
491 answer = dns_answer_ref(q->answer);
492
493 for (i = 0; i < answer->n_rrs; i++) {
494 _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
495 size_t start;
496
497 r = dns_question_matches_rr(q->question, answer->rrs[i]);
498 if (r < 0)
499 goto finish;
500 if (r == 0)
501 continue;
502
503 r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
504 if (r < 0)
505 goto finish;
506
507 r = dns_packet_append_rr(p, answer->rrs[i], &start);
508 if (r < 0)
509 goto finish;
510
511 r = sd_bus_message_open_container(reply, 'r', "qqay");
512 if (r < 0)
513 goto finish;
514
515 r = sd_bus_message_append(reply, "qq", answer->rrs[i]->key->class, answer->rrs[i]->key->type);
516 if (r < 0)
517 goto finish;
518
519 r = sd_bus_message_append_array(reply, 'y', DNS_PACKET_DATA(p) + start, p->size - start);
520 if (r < 0)
521 goto finish;
522
523 r = sd_bus_message_close_container(reply);
524 if (r < 0)
525 goto finish;
526
527 added ++;
528 }
529 }
530
531 if (added <= 0) {
532 r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Name '%s' does not have any RR of the requested type", q->request_hostname);
533 goto finish;
534 }
535
536 r = sd_bus_message_close_container(reply);
537 if (r < 0)
538 goto finish;
539
540 r = sd_bus_send(q->manager->bus, reply, NULL);
541
542finish:
543 if (r < 0) {
544 log_error("Failed to send record reply: %s", strerror(-r));
545 sd_bus_reply_method_errno(q->request, -r, NULL);
546 }
547
548 dns_query_free(q);
549}
550
551static int bus_method_resolve_record(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
552 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
553 _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
554 _cleanup_free_ char *reverse = NULL;
555 Manager *m = userdata;
556 DnsQuery *q;
557 int r;
558 uint16_t class, type;
559 const char *name;
560
561 assert(bus);
562 assert(message);
563 assert(m);
564
565 r = sd_bus_message_read(message, "sqq", &name, &class, &type);
566 if (r < 0)
567 return r;
568
569 question = dns_question_new(1);
570 if (!question)
571 return -ENOMEM;
572
573 key = dns_resource_key_new(class, type, name);
574 if (!key)
575 return -ENOMEM;
576
577 r = dns_question_add(question, key);
578 if (r < 0)
579 return r;
580
581 r = dns_query_new(m, &q, question);
582 if (r < 0)
583 return r;
584
585 q->request = sd_bus_message_ref(message);
586 q->request_hostname = name;
587 q->complete = bus_method_resolve_record_complete;
588
589 r = dns_query_go(q);
590 if (r < 0) {
591 dns_query_free(q);
592
593 if (r == -ESRCH)
594 sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
595
596 return r;
597 }
598
599 return 1;
600}
601
74b2466e
LP
602static const sd_bus_vtable resolve_vtable[] = {
603 SD_BUS_VTABLE_START(0),
878cd63d
LP
604 SD_BUS_METHOD("ResolveHostname", "si", "a(iayi)s", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
605 SD_BUS_METHOD("ResolveAddress", "iayi", "as", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
2d4c5cbc 606 SD_BUS_METHOD("ResolveRecord", "sqq", "a(qqay)", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
74b2466e
LP
607 SD_BUS_VTABLE_END,
608};
609
610static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
611 Manager *m = userdata;
612
613 assert(s);
614 assert(m);
615
616 m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
617
618 manager_connect_bus(m);
619 return 0;
620}
621
622int manager_connect_bus(Manager *m) {
623 int r;
624
625 assert(m);
626
627 if (m->bus)
628 return 0;
629
630 r = sd_bus_default_system(&m->bus);
631 if (r < 0) {
632 /* We failed to connect? Yuck, we must be in early
633 * boot. Let's try in 5s again. As soon as we have
634 * kdbus we can stop doing this... */
635
636 log_debug("Failed to connect to bus, trying again in 5s: %s", strerror(-r));
637
638 r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m);
639 if (r < 0) {
640 log_error("Failed to install bus reconnect time event: %s", strerror(-r));
641 return r;
642 }
643
644 return 0;
645 }
646
4d1cf1e2 647 r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
74b2466e
LP
648 if (r < 0) {
649 log_error("Failed to register object: %s", strerror(-r));
650 return r;
651 }
652
653 r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
654 if (r < 0) {
655 log_error("Failed to register name: %s", strerror(-r));
656 return r;
657 }
658
659 r = sd_bus_attach_event(m->bus, m->event, 0);
660 if (r < 0) {
661 log_error("Failed to attach bus to event loop: %s", strerror(-r));
662 return r;
663 }
664
665 return 0;
666}