resolved-bus.c revision 019036a47fcd10fcf0286800d144c706f3773e2f
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering/***
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering This file is part of systemd.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Copyright 2014 Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is free software; you can redistribute it and/or modify it
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering under the terms of the GNU Lesser General Public License as published by
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering (at your option) any later version.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering systemd is distributed in the hope that it will be useful, but
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Lesser General Public License for more details.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering You should have received a copy of the GNU Lesser General Public License
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering***/
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include "alloc-util.h"
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering#include "bus-common-errors.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "bus-util.h"
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include "dns-domain.h"
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering#include "resolved-bus.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering#include "resolved-def.h"
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int reply_query_state(DnsQuery *q) {
3c70e3bb022f0de3317f3600c9366a2f4597339eLennart Poettering _cleanup_free_ char *ip = NULL;
3c70e3bb022f0de3317f3600c9366a2f4597339eLennart Poettering const char *name;
24882e06c135584f16f31ba8a00fecde8b7f6fadLennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (q->request_address_valid) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = in_addr_to_string(q->request_family, &q->request_address, &ip);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack name = ip;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering } else
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering name = dns_question_first_name(q->question);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering switch (q->state) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case DNS_TRANSACTION_NO_SERVERS:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case DNS_TRANSACTION_TIMEOUT:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case DNS_TRANSACTION_INVALID_REPLY:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering case DNS_TRANSACTION_RESOURCES:
4f10118016f9b2fd7e1d26c9ef7d91eb33fba694Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_RESOURCES, "Not enough resources");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case DNS_TRANSACTION_ABORTED:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "Query aborted");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case DNS_TRANSACTION_DNSSEC_FAILED:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "DNSSEC validation failed: %s",
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering dnssec_result_to_string(q->answer_dnssec_result));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case DNS_TRANSACTION_RCODE_FAILURE: {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering else {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *rc, *n;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering char p[3]; /* the rcode is 4 bits long */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering rc = dns_rcode_to_string(q->answer_rcode);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!rc) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sprintf(p, "%i", q->answer_rcode);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering rc = p;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering n = strjoina(_BUS_ERROR_DNS, rc);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", name, rc);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_reply_method_error(q->request, &error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case DNS_TRANSACTION_NULL:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering case DNS_TRANSACTION_PENDING:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering case DNS_TRANSACTION_SUCCESS:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering default:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert_not_reached("Impossible state");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex) {
a1e58e8ee1c84b633d6d6d651d5328d4dd4eba5bLennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(reply);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(rr);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_open_container(reply, 'r', "iiay");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_append(reply, "i", ifindex);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (rr->key->type == DNS_TYPE_A) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_append(reply, "i", AF_INET);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else if (rr->key->type == DNS_TYPE_AAAA) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_append(reply, "i", AF_INET6);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering } else
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return -EAFNOSUPPORT;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
920b52e4909d9dc812817fd8b82f83ca23a11c91Thomas Hindoe Paaboel Andersen if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_close_container(reply);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen return 0;
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen}
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersenstatic void bus_method_resolve_hostname_complete(DnsQuery *q) {
7dfbe2e3fc0215b49d8202a32beb6b1aae08c4e4Tom Gundersen _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unsigned added = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = reply_query_state(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering r = dns_query_process_cname(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == -ELOOP) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_first_name(q->question));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r > 0) /* This was a cname, and the query was restarted. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iiay)");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering goto finish;
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering
7410616cd9dbbec97cf98d75324da5cda2b2f7a2Lennart Poettering if (q->answer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DnsResourceRecord *rr;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int ifindex;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_question_matches_rr(q->question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack continue;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack r = append_address(reply, rr, ifindex);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack goto finish;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (!canonical)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack canonical = dns_resource_record_ref(rr);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack added ++;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack }
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (added <= 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_question_first_name(q->question));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_close_container(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Return the precise spelling and uppercasing and CNAME target reported by the server */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(canonical);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_append(
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering reply, "st",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DNS_RESOURCE_KEY_NAME(canonical->key),
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringfinish:
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering if (r < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error_errno(r, "Failed to send hostname reply: %m");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering dns_query_free(q);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int check_ifindex_flags(int ifindex, uint64_t *flags, uint64_t ok, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(flags);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (ifindex < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_CNAME|ok))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering *flags |= SD_RESOLVED_PROTOCOLS_ALL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *hostname;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int family, ifindex;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering uint64_t flags;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DnsQuery *q;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(message, "isit", &ifindex, &hostname, &family, &flags);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack r = dns_name_is_valid(hostname);
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
3f9da416457c4265b8f1179516a32ad1a987ff7dLennart Poettering r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_SEARCH, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_question_new_address(&question, family, hostname);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_query_new(m, &q, question, ifindex, flags);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering q->request = sd_bus_message_ref(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering q->request_family = family;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering q->complete = bus_method_resolve_hostname_complete;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_query_bus_track(q, message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_query_go(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringfail:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering dns_query_free(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poetteringstatic void bus_method_resolve_address_complete(DnsQuery *q) {
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering DnsResourceRecord *rr;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unsigned added = 0;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering int ifindex, r;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering
cfa9677bd164574600d29a9bf99f9d1f28a7a170Mantas MikulÄ—nas assert(q);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = reply_query_state(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering }
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering r = dns_query_process_cname(q);
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering if (r == -ELOOP) {
cbf60d0a7fda7bd6c0578a6cc151f798a0edfd02Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_first_name(q->question));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek goto finish;
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek if (r > 0) /* This was a cname, and the query was restarted. */
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek return;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
b2c23da8cea1987a1a329f5a964d3299b7ca7890Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(is)");
8f077bf94e129fa1b6f0159e3140c4326f1066cfZbigniew Jędrzejewski-Szmek if (r < 0)
23bbb0de4e3f85d9704a5c12a5afa2dfa0159e41Michal Schmidt goto finish;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (q->answer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_append(reply, "(is)", ifindex, rr->ptr.name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering added ++;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (added <= 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *ip = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering in_addr_to_string(q->request_family, &q->request_address, &ip);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", strna(ip));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_close_container(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
be847e82cf95bf8eb589778df2aa2b3d1d7ae99eLennart Poettering r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringfinish:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering log_error_errno(r, "Failed to send address reply: %m");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering dns_query_free(q);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int bus_method_resolve_address(sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int family, ifindex;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering uint64_t flags;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const void *d;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DnsQuery *q;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering size_t sz;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(message, "ii", &ifindex, &family);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!IN_SET(family, AF_INET, AF_INET6))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read_array(message, 'y', &d, &sz);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (sz != FAMILY_ADDRESS_SIZE(family))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "t", &flags);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = check_ifindex_flags(ifindex, &flags, 0, error);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_question_new_reverse(&question, family, d);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_query_new(m, &q, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering
ce30c8dcb41dfe9264f79f30c7f51c0e74576638Lennart Poettering q->request = sd_bus_message_ref(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering q->request_family = family;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering memcpy(&q->request_address, d, sz);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering q->complete = bus_method_resolve_address_complete;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_query_bus_track(q, message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto fail;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_query_go(q);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto fail;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt return 1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringfail:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering dns_query_free(q);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int bus_message_append_rr(sd_bus_message *m, DnsResourceRecord *rr, int ifindex) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(rr);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_open_container(m, 'r', "iqqay");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_append(m, "iqq",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering ifindex,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering rr->key->class,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering rr->key->type);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_resource_record_to_wire_format(rr, false);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_append_array(m, 'y', rr->wire_format, rr->wire_format_size);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_message_close_container(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void bus_method_resolve_record_complete(DnsQuery *q) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering unsigned added = 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
db2cb23b5b179707000d28a11efb3d888d06ee80Umut Tezduyar Lindskog
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(q);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = reply_query_state(q);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_query_process_cname(q);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r == -ELOOP) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_first_name(q->question));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r > 0) /* Following a CNAME */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iqqay)");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (q->answer) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DnsResourceRecord *rr;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int ifindex;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack goto finish;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (r == 0)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack continue;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack r = bus_message_append_rr(reply, rr, ifindex);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (r < 0)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack goto finish;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack added ++;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (added <= 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Name '%s' does not have any RR of the requested type", dns_question_first_name(q->question));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_close_container(reply);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardtfinish:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error_errno(r, "Failed to send record reply: %m");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering dns_query_free(q);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd_bus_error *error) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering Manager *m = userdata;
8d0e0ddda6501479eb69164687c83c1a7667b33aJan Engelhardt uint16_t class, type;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering const char *name;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r, ifindex;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering uint64_t flags;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DnsQuery *q;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(message);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(m);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_read(message, "isqqt", &ifindex, &name, &class, &type, &flags);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_name_is_valid(name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!dns_type_is_valid_query(type))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid RR type for query %" PRIu16, type);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = check_ifindex_flags(ifindex, &flags, 0, error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack question = dns_question_new(1);
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack if (!question)
05a08cb60f02970e8476306074c70ee4e6a57fb3Thomas Hindoe Paaboel Andersen return -ENOMEM;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering key = dns_resource_key_new(class, type, name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!key)
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering return -ENOMEM;
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering r = dns_question_add(question, key);
ff975efb2e88dcd5221a2f0d76c4c87e85b821a8Lennart Poettering if (r < 0)
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering return r;
16ac401407959cbc62312e61c2dd76dbc3a0793bLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_query_new(m, &q, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering q->request = sd_bus_message_ref(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering q->complete = bus_method_resolve_record_complete;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_query_bus_track(q, message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_query_go(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringfail:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering dns_query_free(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DnsQuery *aux;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(rr);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(rr->key);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (rr->key->type != DNS_TYPE_SRV)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* First, let's see if we could find an appropriate A or AAAA
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering * record for the SRV record */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack DnsResourceRecord *zz;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (aux->state != DNS_TRANSACTION_SUCCESS)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (aux->auxiliary_result != 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_name_equal(dns_question_first_name(aux->question), rr->srv.name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DNS_ANSWER_FOREACH(zz, aux->answer) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_question_matches_rr(aux->question, zz, NULL);
82a2b6bb5e4e5d294f09af778c48974a7857afb6Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering canonical = dns_resource_record_ref(zz);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (canonical)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering break;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!canonical)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 0;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_open_container(reply, 'r', "qqqsa(iiay)s");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_append(
82a2b6bb5e4e5d294f09af778c48974a7857afb6Lennart Poettering reply,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering "qqqs",
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering rr->srv.priority, rr->srv.weight, rr->srv.port, rr->srv.name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iiay)");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DnsResourceRecord *zz;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int ifindex;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (aux->state != DNS_TRANSACTION_SUCCESS)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (aux->auxiliary_result != 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_name_equal(dns_question_first_name(aux->question), rr->srv.name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DNS_ANSWER_FOREACH_IFINDEX(zz, ifindex, aux->answer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_question_matches_rr(aux->question, zz, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = append_address(reply, zz, ifindex);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = sd_bus_message_close_container(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Note that above we appended the hostname as encoded in the
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * SRV, and here the canonical hostname this maps to. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_append(reply, "s", canonical ? DNS_RESOURCE_KEY_NAME(canonical->key) : rr->srv.name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_close_container(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return 1;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poetteringstatic int append_txt(sd_bus_message *reply, DnsResourceRecord *rr) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DnsTxtItem *i;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(rr);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(rr->key);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (rr->key->type != DNS_TYPE_TXT)
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering LIST_FOREACH(items, i, rr->txt.items) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering if (i->length <= 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_append_array(reply, 'y', i->data, i->length);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void resolve_service_all_complete(DnsQuery *q) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DnsQuery *aux;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unsigned added = false;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering int r;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann assert(q);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (q->block_all_complete > 0)
e24e415e5f3af2fe86d2be9a1f1a2e8d5f8c96bfDaniel Mack return;
e24e415e5f3af2fe86d2be9a1f1a2e8d5f8c96bfDaniel Mack
e24e415e5f3af2fe86d2be9a1f1a2e8d5f8c96bfDaniel Mack if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering DnsQuery *bad = NULL;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering bool have_success = false;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering switch (aux->state) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering case DNS_TRANSACTION_PENDING:
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering /* If an auxiliary query is still pending, let's wait */
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering return;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering case DNS_TRANSACTION_SUCCESS:
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (aux->auxiliary_result == 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering have_success = true;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering else
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering bad = aux;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering break;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering default:
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering bad = aux;
94e15fdc4d9d96fa6607bfb4eaaea164a3aec417David Herrmann break;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (!have_success) {
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering /* We can only return one error, hence pick the last error we encountered */
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(bad);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (bad->state == DNS_TRANSACTION_SUCCESS) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering assert(bad->auxiliary_result != 0);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (bad->auxiliary_result == -ELOOP) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_first_name(bad->question));
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto finish;
a9c8343e83ec09f80a76930573b2592f97ae4283Daniel Mack }
a9c8343e83ec09f80a76930573b2592f97ae4283Daniel Mack
a9c8343e83ec09f80a76930573b2592f97ae4283Daniel Mack r = bad->auxiliary_result;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto finish;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = reply_query_state(bad);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto finish;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto finish;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(qqqsa(iiay)s)");
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto finish;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (q->answer) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering DnsResourceRecord *rr;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering DNS_ANSWER_FOREACH(rr, q->answer) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering goto finish;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r == 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering continue;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering r = append_srv(q, reply, rr);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r < 0)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering goto finish;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering if (r == 0) /* not an SRV record */
a9c8343e83ec09f80a76930573b2592f97ae4283Daniel Mack continue;
dcc2fc01fa850e9ee36c549dc2691e7e5c71bebfLennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering if (!canonical)
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering canonical = dns_resource_record_ref(rr);
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering added++;
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (added <= 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_question_first_name(q->question));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_close_container(reply);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "ay");
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (q->answer) {
bd5f920f1288c0d4d488629fadf067f709227030Lennart Poettering DnsResourceRecord *rr;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DNS_ANSWER_FOREACH(rr, q->answer) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering continue;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = append_txt(reply, rr);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_close_container(reply);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(canonical);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_service_split(DNS_RESOURCE_KEY_NAME(canonical->key), &name, &type, &domain);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_message_append(
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering reply,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering "ssst",
deffddf1df29a5ed047feff3a0f2b765006fb71bLukas Nykryn name, type, domain,
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family, q->answer_authenticated));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringfinish:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error_errno(r, "Failed to send service reply: %m");
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering dns_query_free(q);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic void resolve_service_hostname_complete(DnsQuery *q) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(q);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(q->auxiliary_for);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering resolve_service_all_complete(q->auxiliary_for);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_query_process_cname(q);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r > 0) /* This was a cname, and the query was restarted. */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering q->auxiliary_result = r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering resolve_service_all_complete(q->auxiliary_for);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering}
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringstatic int resolve_service_hostname(DnsQuery *q, DnsResourceRecord *rr, int ifindex) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DnsQuery *aux;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(q);
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering assert(rr);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(rr->key);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering assert(rr->key->type == DNS_TYPE_SRV);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* OK, we found an SRV record for the service. Let's resolve
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering * the hostname included in it */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_question_new_address(&question, q->request_family, rr->srv.name);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
f2341e0a87cab1558c84c933956e9181d5fb6c52Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_query_new(q->manager, &aux, question, ifindex, q->flags|SD_RESOLVED_NO_SEARCH);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return r;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering aux->request_family = q->request_family;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering aux->complete = resolve_service_hostname_complete;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_query_make_auxiliary(aux, q);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r == -EAGAIN) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering /* Too many auxiliary lookups? If so, don't complain,
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * let's just not add this one, we already have more
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * than enough */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering dns_query_free(aux);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Note that auxiliary queries do not track the original bus
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering * client, only the primary request does that. */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_query_go(aux);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto fail;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return 1;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringfail:
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering dns_query_free(aux);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic void bus_method_resolve_service_complete(DnsQuery *q) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering unsigned found = 0;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int r;
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering assert(q);
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering r = reply_query_state(q);
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering goto finish;
2f671520ebade4877cbf6aca3572a5f8c4e1871dLennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_query_process_cname(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == -ELOOP) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_first_name(q->question));
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r > 0) /* This was a cname, and the query was restarted. */
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (q->answer) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DnsResourceRecord *rr;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering int ifindex;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r == 0)
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering continue;
1c2e9646e4a1720fc8ad35c705c195ae1a2c5ce0Lennart Poettering
d69a7ceaed77992105342a056fe68769c2e6d3bdJohannes Hölzl if (rr->key->type != DNS_TYPE_SRV)
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering continue;
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering
d79acc309327f8c0863bd3da8b93d926a1c93ba1David Herrmann if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering q->block_all_complete ++;
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering r = resolve_service_hostname(q, rr, ifindex);
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering q->block_all_complete --;
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
5892a914d173e4b968d2a14fbf717373dee3999aDaniel Mack
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering found++;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering }
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (found <= 0) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of the requested type", dns_question_first_name(q->question));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering goto finish;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* Maybe we are already finished? check now... */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering resolve_service_all_complete(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poetteringfinish:
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (r < 0) {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering log_error_errno(r, "Failed to send service reply: %m");
700ff4d97311902a440109a2c081731ab6ae8a20Lennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering dns_query_free(q);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering}
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poetteringstatic int bus_method_resolve_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering const char *name, *type, *domain, *joined;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering _cleanup_free_ char *n = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering Manager *m = userdata;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering int family, ifindex;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering uint64_t flags;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering DnsQuery *q;
e05ad7bcc87f652cea321224f8eeb32e21d18e0cLennart Poettering int r;
e05ad7bcc87f652cea321224f8eeb32e21d18e0cLennart Poettering
e05ad7bcc87f652cea321224f8eeb32e21d18e0cLennart Poettering assert(message);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert(m);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = sd_bus_message_read(message, "isssit", &ifindex, &name, &type, &domain, &family, &flags);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (isempty(name))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering name = NULL;
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering else {
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering if (!dns_service_name_is_valid(name))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service name '%s'", name);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering }
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (isempty(type))
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering type = NULL;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering else if (!dns_srv_type_is_valid(type))
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SRV service type '%s'", type);
a4152e3fe28b53b8919cc404dd7eca7ead1bf9bdLennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_name_is_valid(domain);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r == 0)
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid domain '%s'", domain);
0faacd470dfbd24f4c6504da6f04213aa05f9d19Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (name && !type)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type.");
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (type) {
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering /* If the type is specified, we generate the full domain name to look up ourselves */
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering r = dns_service_join(name, type, domain, &n);
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering if (r < 0)
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering return r;
e821075a23fdfa3ca7738fc30bb2d4c430fe10c0Lennart Poettering
joined = n;
} else
/* If no type is specified, we assume the domain
* contains the full domain name to lookup already */
joined = domain;
r = dns_question_new_service(&question, joined, !(flags & SD_RESOLVED_NO_TXT));
if (r < 0)
return r;
r = dns_query_new(m, &q, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
if (r < 0)
return r;
q->request = sd_bus_message_ref(message);
q->request_family = family;
q->complete = bus_method_resolve_service_complete;
r = dns_query_bus_track(q, message);
if (r < 0)
goto fail;
r = dns_query_go(q);
if (r < 0)
goto fail;
return 1;
fail:
dns_query_free(q);
return r;
}
static int append_dns_server(sd_bus_message *reply, DnsServer *s) {
int r;
assert(reply);
assert(s);
r = sd_bus_message_open_container(reply, 'r', "iiay");
if (r < 0)
return r;
r = sd_bus_message_append(reply, "ii", s->link ? s->link->ifindex : 0, s->family);
if (r < 0)
return r;
r = sd_bus_message_append_array(reply, 'y', &s->address, FAMILY_ADDRESS_SIZE(s->family));
if (r < 0)
return r;
return sd_bus_message_close_container(reply);
}
static int bus_property_get_dns_servers(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
Manager *m = userdata;
unsigned c = 0;
DnsServer *s;
Iterator i;
Link *l;
int r;
assert(reply);
assert(m);
r = sd_bus_message_open_container(reply, 'a', "(iiay)");
if (r < 0)
return r;
LIST_FOREACH(servers, s, m->dns_servers) {
r = append_dns_server(reply, s);
if (r < 0)
return r;
c++;
}
HASHMAP_FOREACH(l, m->links, i) {
LIST_FOREACH(servers, s, l->dns_servers) {
r = append_dns_server(reply, s);
if (r < 0)
return r;
c++;
}
}
if (c == 0) {
LIST_FOREACH(servers, s, m->fallback_dns_servers) {
r = append_dns_server(reply, s);
if (r < 0)
return r;
}
}
return sd_bus_message_close_container(reply);
}
static int bus_property_get_search_domains(
sd_bus *bus,
const char *path,
const char *interface,
const char *property,
sd_bus_message *reply,
void *userdata,
sd_bus_error *error) {
Manager *m = userdata;
DnsSearchDomain *d;
Iterator i;
Link *l;
int r;
assert(reply);
assert(m);
r = sd_bus_message_open_container(reply, 'a', "(is)");
if (r < 0)
return r;
LIST_FOREACH(domains, d, m->search_domains) {
r = sd_bus_message_append(reply, "(is)", 0, d->name);
if (r < 0)
return r;
}
HASHMAP_FOREACH(l, m->links, i) {
LIST_FOREACH(domains, d, l->search_domains) {
r = sd_bus_message_append(reply, "is", l->ifindex, d->name);
if (r < 0)
return r;
}
}
return sd_bus_message_close_container(reply);
}
static const sd_bus_vtable resolve_vtable[] = {
SD_BUS_VTABLE_START(0),
SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), 0),
SD_BUS_PROPERTY("DNSServers", "a(iiay)", bus_property_get_dns_servers, 0, 0),
SD_BUS_PROPERTY("SearchDomains", "a(is)", bus_property_get_search_domains, 0, 0),
SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_VTABLE_END,
};
static int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
Manager *m = userdata;
assert(s);
assert(m);
m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
manager_connect_bus(m);
return 0;
}
static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
Manager *m = userdata;
int b, r;
assert(message);
assert(m);
r = sd_bus_message_read(message, "b", &b);
if (r < 0) {
log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
return 0;
}
if (b)
return 0;
log_debug("Coming back from suspend, verifying all RRs...");
manager_verify_all(m);
return 0;
}
int manager_connect_bus(Manager *m) {
int r;
assert(m);
if (m->bus)
return 0;
r = sd_bus_default_system(&m->bus);
if (r < 0) {
/* We failed to connect? Yuck, we must be in early
* boot. Let's try in 5s again. As soon as we have
* kdbus we can stop doing this... */
log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
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);
if (r < 0)
return log_error_errno(r, "Failed to install bus reconnect time event: %m");
return 0;
}
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
if (r < 0)
return log_error_errno(r, "Failed to register object: %m");
r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
if (r < 0)
return log_error_errno(r, "Failed to register name: %m");
r = sd_bus_attach_event(m->bus, m->event, 0);
if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m");
r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
"type='signal',"
"sender='org.freedesktop.login1',"
"interface='org.freedesktop.login1.Manager',"
"member='PrepareForSleep',"
"path='/org/freedesktop/login1'",
match_prepare_for_sleep,
m);
if (r < 0)
log_error_errno(r, "Failed to add match for PrepareForSleep: %m");
return 0;
}