resolved-bus.c revision 3339cb71d44c5198f9546f113674f06dc7b01a6f
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen/***
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen This file is part of systemd.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Copyright 2014 Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is free software; you can redistribute it and/or modify it
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen under the terms of the GNU Lesser General Public License as published by
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen (at your option) any later version.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen systemd is distributed in the hope that it will be useful, but
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Lesser General Public License for more details.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen You should have received a copy of the GNU Lesser General Public License
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen***/
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "bus-errors.h"
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen#include "bus-util.h"
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "resolved.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "resolved-dns-domain.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int reply_query_state(DnsQuery *q) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_free_ char *ip = NULL;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen const char *name;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen int r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen if (q->request_hostname)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering name = q->request_hostname;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering else {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = in_addr_to_string(q->request_family, &q->request_address, &ip);
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return r;
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering name = ip;
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering switch (q->state) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_QUERY_NO_SERVERS:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_QUERY_TIMEOUT:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_QUERY_ATTEMPTS_MAX:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_QUERY_RESOURCES:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_RESOURCES, "Not enough resources");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_QUERY_INVALID_REPLY:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering case DNS_QUERY_FAILURE: {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *rc, *n;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering char p[3]; /* the rcode is 4 bits long */
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rc = dns_rcode_to_string(q->answer_rcode);
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering if (!rc) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sprintf(p, "%i", q->answer_rcode);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rc = p;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering n = strappenda(_BUS_ERROR_DNS, rc);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", name, rc);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_reply_method_error(q->request, &error);
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering }
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering case DNS_QUERY_NULL:
21d73c87b09ec2b8642424bc714ce9af3da4fc40Lennart Poettering case DNS_QUERY_PENDING:
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering case DNS_QUERY_SUCCESS:
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering default:
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering assert_not_reached("Impossible state");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
a2a416f768e2aa7db5b975cd50eb19237cac9cceLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(rr);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_open_container(reply, 'r', "iayi");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (rr->key->type == DNS_TYPE_A) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_append(reply, "i", AF_INET);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else if (rr->key->type == DNS_TYPE_AAAA) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_append(reply, "i", AF_INET6);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering } else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -EAFNOSUPPORT;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_append(reply, "i", ifindex);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_close_container(reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void bus_method_resolve_hostname_complete(DnsQuery *q) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *cname = NULL, *canonical = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering unsigned added = 0, i;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r, ifindex;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(q);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (q->state != DNS_QUERY_SUCCESS) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = reply_query_state(q);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iayi)");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering ifindex = q->answer_ifindex;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (q->answer) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering answer = dns_answer_ref(q->answer);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (i = 0; i < answer->n_rrs; i++) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_question_matches_rr(q->question, answer->rrs[i]);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto parse_fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Hmm, if this is not an address record,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering maybe it's a cname? If so, remember this */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_question_matches_cname(q->question, answer->rrs[i]);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto parse_fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r > 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering cname = dns_resource_record_ref(answer->rrs[i]);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = append_address(reply, answer->rrs[i], ifindex);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!canonical)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering canonical = dns_resource_record_ref(answer->rrs[i]);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering added ++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (added <= 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!cname) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering 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);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* This has a cname? Then update the query with the
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * new cname. */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_query_cname_redirect(q, cname->cname.name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == -ELOOP)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop on '%s'", q->request_hostname);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_reply_method_errno(q->request, -r, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Before we restart the query, let's see if any of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * the RRs we already got already answers our query */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering for (i = 0; i < answer->n_rrs; i++) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_question_matches_rr(q->question, answer->rrs[i]);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto parse_fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = append_address(reply, answer->rrs[i], ifindex);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!canonical)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering canonical = dns_resource_record_ref(answer->rrs[i]);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen added++;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* If we didn't find anything, then let's restart the
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * query, this time with the cname */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (added <= 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_query_go(q);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r == -ESRCH) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_reply_method_errno(q->request, -r, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_close_container(reply);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Return the precise spelling and uppercasing reported by the server */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(canonical);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_append(reply, "s", DNS_RESOURCE_KEY_NAME(canonical->key));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringparse_fail:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringfinish:
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to send bus reply: %s", strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dns_query_free(q);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int bus_method_resolve_hostname(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Manager *m = userdata;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *hostname;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int family;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DnsQuery *q;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(bus);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(message);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_read(message, "si", &hostname, &family);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!hostname_is_valid(hostname))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering question = dns_question_new(family == AF_UNSPEC ? 2 : 1);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!question)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (family != AF_INET6) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_A, hostname);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!key)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_question_add(question, key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
0014a4ad505d119c7ac4346d9d774c3f17f663a5Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (family != AF_INET) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering key = dns_resource_key_new(DNS_CLASS_IN, DNS_TYPE_AAAA, hostname);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!key)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return -ENOMEM;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_question_add(question, key);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = dns_query_new(m, &q, question);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering q->request = sd_bus_message_ref(message);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering q->request_family = family;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering q->request_hostname = hostname;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering q->complete = bus_method_resolve_hostname_complete;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = dns_query_go(q);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering dns_query_free(q);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r == -ESRCH)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering return 1;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic void bus_method_resolve_address_complete(DnsQuery *q) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_(dns_answer_unrefp) DnsAnswer *answer = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering unsigned added = 0, i;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering assert(q);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (q->state != DNS_QUERY_SUCCESS) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = reply_query_state(q);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "s");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (q->answer) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering answer = dns_answer_ref(q->answer);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering for (i = 0; i < answer->n_rrs; i++) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = dns_question_matches_rr(q->question, answer->rrs[i]);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto parse_fail;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r == 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering continue;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = sd_bus_message_append(reply, "s", answer->rrs[i]->ptr.name);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering added ++;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (added <= 0) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_free_ char *ip = NULL;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering in_addr_to_string(q->request_family, &q->request_address, &ip);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", ip);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering }
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = sd_bus_message_close_container(reply);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering goto finish;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringparse_fail:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringfinish:
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering if (r < 0)
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering log_error("Failed to send bus reply: %s", strerror(-r));
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering dns_query_free(q);
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic int bus_method_resolve_address(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering _cleanup_free_ char *reverse = NULL;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering Manager *m = userdata;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering int family, ifindex;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering const void *d;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering DnsQuery *q;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering size_t sz;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering int r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering assert(bus);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering assert(message);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering assert(m);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = sd_bus_message_read(message, "i", &family);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (!IN_SET(family, AF_INET, AF_INET6))
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = sd_bus_message_read_array(message, 'y', &d, &sz);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (sz != FAMILY_ADDRESS_SIZE(family))
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = sd_bus_message_read(message, "i", &ifindex);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (ifindex < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = dns_name_reverse(family, d, &reverse);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering question = dns_question_new(1);
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering if (!question)
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering return -ENOMEM;
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, reverse);
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering if (!key)
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering return -ENOMEM;
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering reverse = NULL;
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering r = dns_question_add(question, key);
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = dns_query_new(m, &q, question);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0)
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering q->request = sd_bus_message_ref(message);
90ab504273a7f186ebb76e6acfb778b4e0d7c91bLennart Poettering q->request_family = family;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering memcpy(&q->request_address, d, sz);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering q->complete = bus_method_resolve_address_complete;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen r = dns_query_go(q);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen dns_query_free(q);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering if (r == -ESRCH)
c92e531c82a9815ec349aa1bf31236b86b2d5311Lennart Poettering sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering}
623a4c97b9175f95c4b1c6fc34e36c56f1e4ddbfLennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringstatic const sd_bus_vtable resolve_vtable[] = {
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering SD_BUS_VTABLE_START(0),
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering SD_BUS_METHOD("ResolveHostname", "si", "a(iayi)s", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
5cb36f41f01cf4b1f4395abfffd1b33116591e58Lennart Poettering SD_BUS_METHOD("ResolveAddress", "iayi", "as", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen SD_BUS_VTABLE_END,
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering};
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersenstatic int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen Manager *m = userdata;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(s);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen assert(m);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen manager_connect_bus(m);
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen}
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poetteringint manager_connect_bus(Manager *m) {
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering int r;
eb60f9cd4e93ff5016dc1b5486fd1b7e1565fd92Lennart Poettering
1716f6dcf54d4c181c2e2558e3d5414f54c8d9caLennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (m->bus)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_default_system(&m->bus);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* We failed to connect? Yuck, we must be in early
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * boot. Let's try in 5s again. As soon as we have
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * kdbus we can stop doing this... */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_debug("Failed to connect to bus, trying again in 5s: %s", strerror(-r));
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering 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);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Failed to install bus reconnect time event: %s", strerror(-r));
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return 0;
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen }
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering log_error("Failed to register object: %s", strerror(-r));
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering }
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering if (r < 0) {
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering log_error("Failed to register name: %s", strerror(-r));
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering return r;
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering }
edc501d4674dadc304d45a7e1c5b69e207eb8cd4Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_attach_event(m->bus, m->event, 0);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen log_error("Failed to attach bus to event loop: %s", strerror(-r));
091a364c802e34a58f3260c9cb5db9b75c62215cTom Gundersen return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
f0e1546763304aedc90e91d70dab9eeb7c966cf8Lennart Poettering