resolved-bus.c revision 4afd3348c7506dd1d36305b7bcb9feb8952b9d6b
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/***
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2014 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering***/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
b5efdb8af40ea759a1ea584c1bc44ecc81dd00ceLennart Poettering#include "alloc-util.h"
96aad8d15a324d0e956a4e5653a11a67b209b41aLennart Poettering#include "bus-common-errors.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering#include "bus-util.h"
4ad7f2761da661853dcc29d542efb4727abb1101Nick Owens#include "dns-domain.h"
39d8db043b599a7382f94bfc904d5e108af438bdLennart Poettering#include "resolved-bus.h"
51323288fc628a5cac50914df915545d685b793eLennart Poettering#include "resolved-def.h"
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poetteringstatic int reply_query_state(DnsQuery *q) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering _cleanup_free_ char *ip = NULL;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering const char *name;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q->request_address_valid) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = in_addr_to_string(q->request_family, &q->request_address, &ip);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering name = ip;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering } else
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart Poettering name = dns_question_first_name(q->question);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering switch (q->state) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering case DNS_TRANSACTION_NO_SERVERS:
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering case DNS_TRANSACTION_TIMEOUT:
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering case DNS_TRANSACTION_INVALID_REPLY:
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering case DNS_TRANSACTION_RESOURCES:
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_RESOURCES, "Not enough resources");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering case DNS_TRANSACTION_ABORTED:
818f766b12e025683cf4fed12b3da2a025bb0b31Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "Query aborted");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering case DNS_TRANSACTION_FAILURE: {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", name);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering else {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *rc, *n;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering char p[3]; /* the rcode is 4 bits long */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering rc = dns_rcode_to_string(q->answer_rcode);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!rc) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering sprintf(p, "%i", q->answer_rcode);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering rc = p;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
63c372cb9df3bee01e3bf8cd7f96f336bddda846Lennart Poettering n = strjoina(_BUS_ERROR_DNS, rc);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", name, rc);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering return sd_bus_reply_method_error(q->request, &error);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering case DNS_TRANSACTION_NULL:
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering case DNS_TRANSACTION_PENDING:
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering case DNS_TRANSACTION_SUCCESS:
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering default:
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering assert_not_reached("Impossible state");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering }
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poetteringstatic int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex) {
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering int r;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering assert(reply);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering assert(rr);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_open_container(reply, 'r', "iiay");
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering if (r < 0)
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering return r;
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_append(reply, "i", ifindex);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r < 0)
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering return r;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (rr->key->type == DNS_TYPE_A) {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_append(reply, "i", AF_INET);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r < 0)
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering return r;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering } else if (rr->key->type == DNS_TYPE_AAAA) {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_append(reply, "i", AF_INET6);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r < 0)
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering return r;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr));
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering } else
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return -EAFNOSUPPORT;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r < 0)
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering return r;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering r = sd_bus_message_close_container(reply);
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r < 0)
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering return r;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering return 0;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering}
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poetteringstatic void bus_method_resolve_hostname_complete(DnsQuery *q) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unsigned added = 0;
51323288fc628a5cac50914df915545d685b793eLennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering assert(q);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = reply_query_state(q);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering goto finish;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_query_process_cname(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == -ELOOP) {
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart 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));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r > 0) /* This was a cname, and the query was restarted. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iiay)");
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering goto finish;
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering if (q->answer) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsResourceRecord *rr;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int ifindex;
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_question_matches_rr(q->question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = append_address(reply, rr, ifindex);
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering if (r < 0)
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering if (!canonical)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering canonical = dns_resource_record_ref(rr);
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering added ++;
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering }
8ba9fd9cee0eef572f7b3ed7a8c3ed31160e93d3Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (added <= 0) {
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart 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));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_message_close_container(reply);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering goto finish;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Return the precise spelling and uppercasing and CNAME target reported by the server */
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering assert(canonical);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append(
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering reply, "st",
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_RESOURCE_KEY_NAME(canonical->key),
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering if (r < 0)
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering goto finish;
309e9d86f0e7f9c5f0a2a09227bdfdb3174d4436Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringfinish:
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to send hostname reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dns_query_free(q);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int check_ifindex_flags(int ifindex, uint64_t *flags, uint64_t ok, sd_bus_error *error) {
51323288fc628a5cac50914df915545d685b793eLennart Poettering assert(flags);
51323288fc628a5cac50914df915545d685b793eLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (ifindex < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
51323288fc628a5cac50914df915545d685b793eLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_CNAME|ok))
51323288fc628a5cac50914df915545d685b793eLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
51323288fc628a5cac50914df915545d685b793eLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering *flags |= SD_RESOLVED_PROTOCOLS_ALL;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering return 0;
51323288fc628a5cac50914df915545d685b793eLennart Poettering}
51323288fc628a5cac50914df915545d685b793eLennart Poettering
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poetteringstatic int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Manager *m = userdata;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const char *hostname;
51323288fc628a5cac50914df915545d685b793eLennart Poettering int family, ifindex;
51323288fc628a5cac50914df915545d685b793eLennart Poettering uint64_t flags;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DnsQuery *q;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(message);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_read(message, "isit", &ifindex, &hostname, &family, &flags);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_name_is_valid(hostname);
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_SEARCH, error);
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering return r;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_question_new_address(&question, family, hostname);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = dns_query_new(m, &q, question, ifindex, flags);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->request = sd_bus_message_ref(message);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->request_family = family;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->complete = bus_method_resolve_hostname_complete;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
966c66e34940001a40806142ecebaae61b478444Lennart Poettering r = dns_query_bus_track(q, message);
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering r = dns_query_go(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringfail:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dns_query_free(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void bus_method_resolve_address_complete(DnsQuery *q) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsResourceRecord *rr;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unsigned added = 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int ifindex, r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(q);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = reply_query_state(q);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering goto finish;
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen r = dns_query_process_cname(q);
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen if (r == -ELOOP) {
039a8725fdff1d71e9efd28f27741601c5b4235cLennart 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));
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen goto finish;
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen }
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen if (r < 0)
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen goto finish;
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen if (r > 0) /* This was a cname, and the query was restarted. */
95d46fcaa4f27bc5e675e8de39ab3acc4732e39bTom Gundersen return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(is)");
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering if (q->answer) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto finish;
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering if (r == 0)
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering continue;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append(reply, "(is)", ifindex, rr->ptr.name);
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering if (r < 0)
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering added ++;
3339cb71d44c5198f9546f113674f06dc7b01a6fLennart Poettering }
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (added <= 0) {
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering _cleanup_free_ char *ip = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering in_addr_to_string(q->request_family, &q->request_address, &ip);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart 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));
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_message_close_container(reply);
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering if (r < 0)
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering goto finish;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering goto finish;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
ad867662936a4c7ab2c7116d804c272338801231Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringfinish:
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to send address reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering dns_query_free(q);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poetteringstatic int bus_method_resolve_address(sd_bus_message *message, void *userdata, sd_bus_error *error) {
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Manager *m = userdata;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering int family, ifindex;
51323288fc628a5cac50914df915545d685b793eLennart Poettering uint64_t flags;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering const void *d;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering DnsQuery *q;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering size_t sz;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(message);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_read(message, "ii", &ifindex, &family);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (!IN_SET(family, AF_INET, AF_INET6))
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_read_array(message, 'y', &d, &sz);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering if (sz != FAMILY_ADDRESS_SIZE(family))
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_read(message, "t", &flags);
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering return r;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = check_ifindex_flags(ifindex, &flags, 0, error);
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering if (r < 0)
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering return r;
faa133f3aa7a18f26563dc5d6b95898cb315c37aLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_question_new_reverse(&question, family, d);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_query_new(m, &q, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->request = sd_bus_message_ref(message);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->request_family = family;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering memcpy(&q->request_address, d, sz);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering q->complete = bus_method_resolve_address_complete;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
966c66e34940001a40806142ecebaae61b478444Lennart Poettering r = dns_query_bus_track(q, message);
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering
322345fdb9865ef2477fba8e4bdde0e1183ef505Lennart Poettering r = dns_query_go(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringfail:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dns_query_free(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int bus_message_append_rr(sd_bus_message *m, DnsResourceRecord *rr, int ifindex) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering size_t start;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(rr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(m, 'r', "iqqay");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append(m, "iqq",
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering ifindex,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering rr->key->class,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering rr->key->type);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering p->refuse_compression = true;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_packet_append_rr(p, rr, &start);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append_array(m, 'y', DNS_PACKET_DATA(p) + start, p->size - start);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return sd_bus_message_close_container(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringstatic void bus_method_resolve_record_complete(DnsQuery *q) {
4afd3348c7506dd1d36305b7bcb9feb8952b9d6bLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unsigned added = 0;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering int r;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering assert(q);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
ec2c5e4398f9d65e5dfe61530f2556224733d1e6Lennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = reply_query_state(q);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto finish;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_query_process_cname(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == -ELOOP) {
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart 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));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r > 0) /* Following a CNAME */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto finish;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iqqay)");
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto finish;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (q->answer) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsResourceRecord *rr;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int ifindex;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto finish;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r == 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering continue;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = bus_message_append_rr(reply, rr, ifindex);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto finish;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering added ++;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (added <= 0) {
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart 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));
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto finish;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = sd_bus_message_close_container(reply);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering goto finish;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering goto finish;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poetteringfinish:
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to send record reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering dns_query_free(q);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering}
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poetteringstatic int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd_bus_error *error) {
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering Manager *m = userdata;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering uint16_t class, type;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering const char *name;
51323288fc628a5cac50914df915545d685b793eLennart Poettering int r, ifindex;
51323288fc628a5cac50914df915545d685b793eLennart Poettering uint64_t flags;
51323288fc628a5cac50914df915545d685b793eLennart Poettering DnsQuery *q;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering assert(message);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering assert(m);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
51323288fc628a5cac50914df915545d685b793eLennart Poettering r = sd_bus_message_read(message, "isqqt", &ifindex, &name, &class, &type, &flags);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return r;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_name_is_valid(name);
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
7b9f7afcc04e80b77a2567b0750aa2cd03c1a1cdLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = check_ifindex_flags(ifindex, &flags, 0, error);
51323288fc628a5cac50914df915545d685b793eLennart Poettering if (r < 0)
51323288fc628a5cac50914df915545d685b793eLennart Poettering return r;
51323288fc628a5cac50914df915545d685b793eLennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering question = dns_question_new(1);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (!question)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return -ENOMEM;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering key = dns_resource_key_new(class, type, name);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (!key)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return -ENOMEM;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = dns_question_add(question, key);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return r;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_query_new(m, &q, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return r;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering q->request = sd_bus_message_ref(message);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering q->complete = bus_method_resolve_record_complete;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
966c66e34940001a40806142ecebaae61b478444Lennart Poettering r = dns_query_bus_track(q, message);
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
82bd6dddc4a363a9c3c6f41eb46eb171a80dca27Lennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering r = dns_query_go(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringfail:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dns_query_free(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsQuery *aux;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(rr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(rr->key);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (rr->key->type != DNS_TYPE_SRV)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* First, let's see if we could find an appropriate A or AAAA
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * record for the SRV record */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsResourceRecord *zz;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (aux->state != DNS_TRANSACTION_SUCCESS)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (aux->auxiliary_result != 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart Poettering r = dns_name_equal(dns_question_first_name(aux->question), rr->srv.name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_ANSWER_FOREACH(zz, aux->answer) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_question_matches_rr(aux->question, zz, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering canonical = dns_resource_record_ref(zz);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering break;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (canonical)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering break;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!canonical)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(reply, 'r', "qqqsa(iiay)s");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append(
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering reply,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering "qqqs",
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering rr->srv.priority, rr->srv.weight, rr->srv.port, rr->srv.name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iiay)");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsResourceRecord *zz;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int ifindex;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (aux->state != DNS_TRANSACTION_SUCCESS)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (aux->auxiliary_result != 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart Poettering r = dns_name_equal(dns_question_first_name(aux->question), rr->srv.name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(zz, ifindex, aux->answer) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_question_matches_rr(aux->question, zz, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = append_address(reply, zz, ifindex);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_close_container(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Note that above we appended the hostname as encoded in the
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * SRV, and here the canonical hostname this maps to. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append(reply, "s", canonical ? DNS_RESOURCE_KEY_NAME(canonical->key) : rr->srv.name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_close_container(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int append_txt(sd_bus_message *reply, DnsResourceRecord *rr) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsTxtItem *i;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(rr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(rr->key);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (rr->key->type != DNS_TYPE_TXT)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering LIST_FOREACH(items, i, rr->txt.items) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (i->length <= 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append_array(reply, 'y', i->data, i->length);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic void resolve_service_all_complete(DnsQuery *q) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsQuery *aux;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unsigned added = false;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q->block_all_complete > 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsQuery *bad = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering bool have_success = false;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering switch (aux->state) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering case DNS_TRANSACTION_PENDING:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* If an auxiliary query is still pending, let's wait */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering case DNS_TRANSACTION_SUCCESS:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (aux->auxiliary_result == 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering have_success = true;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering else
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering bad = aux;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering break;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering default:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering bad = aux;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering break;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!have_success) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* We can only return one error, hence pick the last error we encountered */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(bad);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (bad->state == DNS_TRANSACTION_SUCCESS) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(bad->auxiliary_result != 0);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (bad->auxiliary_result == -ELOOP) {
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart 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));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = bad->auxiliary_result;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = reply_query_state(bad);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_new_method_return(q->request, &reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(reply, 'a', "(qqqsa(iiay)s)");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q->answer) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsResourceRecord *rr;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_ANSWER_FOREACH(rr, q->answer) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = append_srv(q, reply, rr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0) /* not an SRV record */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!canonical)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering canonical = dns_resource_record_ref(rr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering added++;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (added <= 0) {
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart 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));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_close_container(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_open_container(reply, 'a', "ay");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q->answer) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsResourceRecord *rr;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_ANSWER_FOREACH(rr, q->answer) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = append_txt(reply, rr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_close_container(reply);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(canonical);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_service_split(DNS_RESOURCE_KEY_NAME(canonical->key), &name, &type, &domain);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_append(
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering reply,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering "ssst",
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering name, type, domain,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_send(q->manager->bus, reply, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringfinish:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_error_errno(r, "Failed to send service reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dns_query_free(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic void resolve_service_hostname_complete(DnsQuery *q) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(q->auxiliary_for);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering resolve_service_all_complete(q->auxiliary_for);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_query_process_cname(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r > 0) /* This was a cname, and the query was restarted. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q->auxiliary_result = r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering resolve_service_all_complete(q->auxiliary_for);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int resolve_service_hostname(DnsQuery *q, DnsResourceRecord *rr, int ifindex) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsQuery *aux;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(rr);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(rr->key);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(rr->key->type == DNS_TYPE_SRV);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* OK, we found an SRV record for the service. Let's resolve
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * the hostname included in it */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_question_new_address(&question, q->request_family, rr->srv.name);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_query_new(q->manager, &aux, question, ifindex, q->flags|SD_RESOLVED_NO_SEARCH);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering aux->request_family = q->request_family;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering aux->complete = resolve_service_hostname_complete;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_query_make_auxiliary(aux, q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == -EAGAIN) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Too many auxiliary lookups? If so, don't complain,
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * let's just not add this one, we already have more
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * than enough */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dns_query_free(aux);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Note that auxiliary queries do not track the original bus
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * client, only the primary request does that. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_query_go(aux);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return 1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringfail:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dns_query_free(aux);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic void bus_method_resolve_service_complete(DnsQuery *q) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering unsigned found = 0;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q->state != DNS_TRANSACTION_SUCCESS) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = reply_query_state(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_query_process_cname(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == -ELOOP) {
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart 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));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r > 0) /* This was a cname, and the query was restarted. */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (q->answer) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsResourceRecord *rr;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int ifindex;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_question_matches_rr(q->question, rr, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (rr->key->type != DNS_TYPE_SRV)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering continue;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q->block_all_complete ++;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = resolve_service_hostname(q, rr, ifindex);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q->block_all_complete --;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering found++;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (found <= 0) {
703e4f5e39c019da8c002ba10bd450ce378c0e91Lennart 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));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto finish;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* Maybe we are already finished? check now... */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering resolve_service_all_complete(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringfinish:
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering if (r < 0) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering log_error_errno(r, "Failed to send service reply: %m");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering sd_bus_reply_method_errno(q->request, r, NULL);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering }
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dns_query_free(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering}
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringstatic int bus_method_resolve_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering const char *name, *type, *domain, *joined;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering _cleanup_free_ char *n = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering Manager *m = userdata;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int family, ifindex;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering uint64_t flags;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering DnsQuery *q;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering int r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(message);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert(m);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = sd_bus_message_read(message, "isssit", &ifindex, &name, &type, &domain, &family, &flags);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (isempty(name))
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering name = NULL;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering else {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (!dns_service_name_is_valid(name))
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service name '%s'", name);
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering }
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (isempty(type))
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering type = NULL;
7e8131e9c6c150732503899a092206578fdc13deLennart Poettering else if (!dns_srv_type_is_valid(type))
7e8131e9c6c150732503899a092206578fdc13deLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SRV service type '%s'", type);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_name_is_valid(domain);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r == 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid domain '%s'", domain);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (name && !type)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type.");
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (type) {
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* If the type is specified, we generate the full domain name to look up ourselves */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_service_join(name, type, domain, &n);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering joined = n;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering } else
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering /* If no type is specified, we assume the domain
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering * contains the full domain name to lookup already */
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering joined = domain;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_question_new_service(&question, joined, !(flags & SD_RESOLVED_NO_TXT));
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
801ad6a6a9cd8fbd58b9f9c27f20dbb3c87d47ddLennart Poettering r = dns_query_new(m, &q, question, ifindex, flags|SD_RESOLVED_NO_SEARCH);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q->request = sd_bus_message_ref(message);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q->request_family = family;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering q->complete = bus_method_resolve_service_complete;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_query_bus_track(q, message);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering r = dns_query_go(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering if (r < 0)
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering goto fail;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering return 1;
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poetteringfail:
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering dns_query_free(q);
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering return r;
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering}
2d4c5cbc0ed3ccb09dc086a040088b454c22c644Lennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poetteringstatic int append_dns_server(sd_bus_message *reply, DnsServer *s) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering int r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(reply);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(s);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = sd_bus_message_open_container(reply, 'r', "iiay");
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = sd_bus_message_append(reply, "ii", s->link ? s->link->ifindex : 0, s->family);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = sd_bus_message_append_array(reply, 'y', &s->address, FAMILY_ADDRESS_SIZE(s->family));
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return sd_bus_message_close_container(reply);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering}
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poetteringstatic int bus_property_get_dns_servers(
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering sd_bus *bus,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering const char *path,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering const char *interface,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering const char *property,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering sd_bus_message *reply,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering void *userdata,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering sd_bus_error *error) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Manager *m = userdata;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering unsigned c = 0;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering DnsServer *s;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Iterator i;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Link *l;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering int r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(reply);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(m);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = sd_bus_message_open_container(reply, 'a', "(iiay)");
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(servers, s, m->dns_servers) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = append_dns_server(reply, s);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering c++;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering HASHMAP_FOREACH(l, m->links, i) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(servers, s, l->dns_servers) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = append_dns_server(reply, s);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering c++;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (c == 0) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(servers, s, m->fallback_dns_servers) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = append_dns_server(reply, s);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return sd_bus_message_close_container(reply);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering}
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poetteringstatic int bus_property_get_search_domains(
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering sd_bus *bus,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering const char *path,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering const char *interface,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering const char *property,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering sd_bus_message *reply,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering void *userdata,
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering sd_bus_error *error) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Manager *m = userdata;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering DnsSearchDomain *d;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Iterator i;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering Link *l;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering int r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(reply);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering assert(m);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = sd_bus_message_open_container(reply, 'a', "(is)");
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(domains, d, m->search_domains) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = sd_bus_message_append(reply, "(is)", 0, d->name);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering HASHMAP_FOREACH(l, m->links, i) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering LIST_FOREACH(domains, d, l->search_domains) {
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering r = sd_bus_message_append(reply, "is", l->ifindex, d->name);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering if (r < 0)
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return r;
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering }
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering return sd_bus_message_close_container(reply);
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering}
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic const sd_bus_vtable resolve_vtable[] = {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SD_BUS_VTABLE_START(0),
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering SD_BUS_PROPERTY("LLMNRHostname", "s", NULL, offsetof(Manager, llmnr_hostname), 0),
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering SD_BUS_PROPERTY("DNSServers", "a(iiay)", bus_property_get_dns_servers, 0, 0),
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering SD_BUS_PROPERTY("SearchDomains", "a(is)", bus_property_get_search_domains, 0, 0),
7f220d94a938a99c77400fa0ca30485e269bae7cLennart Poettering
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
78c6a153c47f8d597c827bdcaf8c4e42ac87f738Lennart Poettering SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
45ec7efb6c2560c80dfa752bc9d3733749dc52cbLennart Poettering SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED),
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering SD_BUS_VTABLE_END,
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering};
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Manager *m = userdata;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(s);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering manager_connect_bus(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poetteringstatic int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering Manager *m = userdata;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering int b, r;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering assert(message);
190700621f95160d364f8ec1d3e360246c41ce75Lennart Poettering assert(m);
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering r = sd_bus_message_read(message, "b", &b);
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering return 0;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering }
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering if (b)
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering return 0;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering log_debug("Coming back from suspend, verifying all RRs...");
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering manager_verify_all(m);
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering return 0;
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering}
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringint manager_connect_bus(Manager *m) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering int r;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering assert(m);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (m->bus)
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_default_system(&m->bus);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering if (r < 0) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* We failed to connect? Yuck, we must be in early
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * boot. Let's try in 5s again. As soon as we have
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering * kdbus we can stop doing this... */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_event_add_time(m->event, &m->bus_retry_event_source, CLOCK_MONOTONIC, now(CLOCK_MONOTONIC) + 5*USEC_PER_SEC, 0, on_bus_retry, m);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to install bus reconnect time event: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering }
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
4d1cf1e229c9bdbc44778c0863eaad918f5724e7Lennart Poettering r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to register object: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to register name: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_attach_event(m->bus, m->event, 0);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to attach bus to event loop: %m");
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering "type='signal',"
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering "sender='org.freedesktop.login1',"
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering "interface='org.freedesktop.login1.Manager',"
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering "member='PrepareForSleep',"
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering "path='/org/freedesktop/login1'",
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering match_prepare_for_sleep,
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering m);
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to add match for PrepareForSleep: %m");
902bb5d8abb2a7d258741828d212ca549ab16950Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering return 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering}