resolved-bus.c revision 45ec7efb6c2560c80dfa752bc9d3733749dc52cb
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer/***
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer This file is part of systemd.
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer Copyright 2014 Lennart Poettering
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer systemd is free software; you can redistribute it and/or modify it
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer under the terms of the GNU Lesser General Public License as published by
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer the Free Software Foundation; either version 2.1 of the License, or
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt (at your option) any later version.
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt systemd is distributed in the hope that it will be useful, but
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt WITHOUT ANY WARRANTY; without even the implied warranty of
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1c36b4a73b876258fbe01fbe9bc9b750b7dcc9ceEvgeny Vereshchagin Lesser General Public License for more details.
c50a4525aa8151b180d5a325e88c5f3812e66c36Martin Pitt
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier You should have received a copy of the GNU Lesser General Public License
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier along with systemd; If not, see <http://www.gnu.org/licenses/>.
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier***/
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "alloc-util.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "bus-common-errors.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "bus-util.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "dns-domain.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "resolved-bus.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier#include "resolved-def.h"
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalierstatic int reply_query_state(DnsQuery *q) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier _cleanup_free_ char *ip = NULL;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *name;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier int r;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier if (q->request_address_valid) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier r = in_addr_to_string(q->request_family, &q->request_address, &ip);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier if (r < 0)
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier return r;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier name = ip;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier } else
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier name = dns_question_name(q->question);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier switch (q->state) {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier case DNS_TRANSACTION_NO_SERVERS:
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer case DNS_TRANSACTION_TIMEOUT:
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
b6f0c419e38a960873fe68bf8f89bbb0268eed02Harald Hoyer
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin case DNS_TRANSACTION_INVALID_REPLY:
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin case DNS_TRANSACTION_RESOURCES:
61fea35e14d84144e6e2122f5cd247f9c7e6245eEvgeny Vereshchagin return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_RESOURCES, "Not enough resources");
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier case DNS_TRANSACTION_ABORTED:
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "Query aborted");
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier case DNS_TRANSACTION_FAILURE: {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", name);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier else {
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier const char *rc, *n;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier char p[3]; /* the rcode is 4 bits long */
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier rc = dns_rcode_to_string(q->answer_rcode);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier if (!rc) {
dbf43a42b8bb66d53c7cbab05f104c28097f811eDaniel Mack sprintf(p, "%i", q->answer_rcode);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier rc = p;
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier }
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier n = strjoina(_BUS_ERROR_DNS, rc);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", name, rc);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier }
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier return sd_bus_reply_method_error(q->request, &error);
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier }
c6a77179a4097df355f0f04b8f3260c76b5e515cRonny Chevalier
dbf43a42b8bb66d53c7cbab05f104c28097f811eDaniel Mack case DNS_TRANSACTION_NULL:
dbf43a42b8bb66d53c7cbab05f104c28097f811eDaniel Mack case DNS_TRANSACTION_PENDING:
dbf43a42b8bb66d53c7cbab05f104c28097f811eDaniel Mack case DNS_TRANSACTION_SUCCESS:
dbf43a42b8bb66d53c7cbab05f104c28097f811eDaniel Mack default:
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek assert_not_reached("Impossible state");
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int append_address(sd_bus_message *reply, DnsResourceRecord *rr, int ifindex) {
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek int r;
24be78d72b931b0175f08cee12fd23d631c024bfEvgeny Vereshchagin
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(reply);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(rr);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_open_container(reply, 'r', "iiay");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_append(reply, "i", ifindex);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (rr->key->type == DNS_TYPE_A) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_append(reply, "i", AF_INET);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_append_array(reply, 'y', &rr->a.in_addr, sizeof(struct in_addr));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else if (rr->key->type == DNS_TYPE_AAAA) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_append(reply, "i", AF_INET6);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_append_array(reply, 'y', &rr->aaaa.in6_addr, sizeof(struct in6_addr));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier } else
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return -EAFNOSUPPORT;
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin if (r < 0)
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin return r;
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin r = sd_bus_message_close_container(reply);
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin if (r < 0)
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin return r;
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin return 0;
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin}
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchaginstatic void bus_method_resolve_hostname_complete(DnsQuery *q) {
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin unsigned added = 0;
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin int r;
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin assert(q);
a2fbff31c9c319da51528f85ae97d019f1e61a86Evgeny Vereshchagin
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin if (q->state != DNS_TRANSACTION_SUCCESS) {
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin r = reply_query_state(q);
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin goto finish;
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin }
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin r = dns_query_process_cname(q);
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin if (r == -ELOOP) {
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_name(q->question));
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin goto finish;
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin }
cb2f9d3f296bc80b55f09880d61dfdf47fc98212Evgeny Vereshchagin if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r > 0) /* This was a cname, and the query was restarted. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_new_method_return(q->request, &reply);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_open_container(reply, 'a', "(iiay)");
8a8332f77e61d41f3bb28b8f929ed41e0ffaf721Zbigniew Jędrzejewski-Szmek if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
2375607039517c88df51ef16ddbb624ec1c10654Kay Sievers
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (q->answer) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DnsResourceRecord *rr;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int ifindex;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = dns_question_matches_rr(q->question, rr);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r == 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier continue;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = append_address(reply, rr, ifindex);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
1b1eae69ce52ef6c89a1200e8d3758549b291991Daniel Mack if (!canonical)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier canonical = dns_resource_record_ref(rr);
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier added ++;
edbced8a151c1b7ded685e2ec644950d2adec5f5Harald Hoyer }
1b1eae69ce52ef6c89a1200e8d3758549b291991Daniel Mack }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (added <= 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier 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_name(q->question));
739d81ddd005fae2bb82edce5b8a6173c7c48b34Zbigniew Jędrzejewski-Szmek goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_close_container(reply);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier /* Return the precise spelling and uppercasing and CNAME target reported by the server */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(canonical);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_append(
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier reply, "st",
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DNS_RESOURCE_KEY_NAME(canonical->key),
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_send(q->manager->bus, reply, NULL);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierfinish:
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error_errno(r, "Failed to send hostname reply: %m");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier sd_bus_reply_method_errno(q->request, r, NULL);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dns_query_free(q);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int check_ifindex_flags(int ifindex, uint64_t *flags, uint64_t ok, sd_bus_error *error) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(flags);
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin if (ifindex < 0)
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid interface index");
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin if (*flags & ~(SD_RESOLVED_PROTOCOLS_ALL|SD_RESOLVED_NO_CNAME|ok))
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid flags parameter");
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin if ((*flags & SD_RESOLVED_PROTOCOLS_ALL) == 0) /* If no protocol is enabled, enable all */
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin *flags |= SD_RESOLVED_PROTOCOLS_ALL;
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin
c7eda0133b6bf13a182337cbe8a61bf2faf9b32eEvgeny Vereshchagin return 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier Manager *m = userdata;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const char *hostname;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int family, ifindex;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint64_t flags;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DnsQuery *q;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(message);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(m);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert_cc(sizeof(int) == sizeof(int32_t));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_read(message, "isit", &ifindex, &hostname, &family, &flags);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = dns_name_is_valid(hostname);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r == 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid hostname '%s'", hostname);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = check_ifindex_flags(ifindex, &flags, 0, error);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = dns_question_new_address(&question, family, hostname);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
bf3a947cb44f31359bba313e0252cbcc0dc95b03Evgeny Vereshchagin return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = dns_query_new(m, &q, question, ifindex, flags);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier q->request = sd_bus_message_ref(message);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier q->request_family = family;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier q->complete = bus_method_resolve_hostname_complete;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = dns_query_bus_track(q, message);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto fail;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = dns_query_go(q);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto fail;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return 1;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierfail:
4be4833ece2856e0cacc09f8f8b2c02b320751faMartin Pitt dns_query_free(q);
7d023341c765c205068e33d23d63a4000ec211dfMartin Pitt return r;
7d023341c765c205068e33d23d63a4000ec211dfMartin Pitt}
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierstatic void bus_method_resolve_address_complete(DnsQuery *q) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DnsResourceRecord *rr;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier unsigned added = 0;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int ifindex, r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(q);
cffae62bcb6912fbaf1b7b282d9d170c9d308897Martin Pitt
99877b7e3782a51b31bf191825f0335500f52fe5Harald Hoyer if (q->state != DNS_TRANSACTION_SUCCESS) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = reply_query_state(q);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt
3486cb6cfa3d32a95c0daf02c7510fdf372507bfMartin Pitt /* We don't process CNAME for PTR lookups. */
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_new_method_return(q->request, &reply);
e63b61be5350dbe92ea12e1eeb96dde251ed9292Evgeny Vereshchagin if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_open_container(reply, 'a', "(is)");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin if (q->answer) {
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = dns_question_matches_rr(q->question, rr);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r == 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier continue;
0fe15dc8ddddeb39a5cad1f4f4afa25fa074a5d1Evgeny Vereshchagin
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_append(reply, "(is)", ifindex, rr->ptr.name);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
417491f122b346a31cf8dc406c4f9195a5900cecEvgeny Vereshchagin goto finish;
417491f122b346a31cf8dc406c4f9195a5900cecEvgeny Vereshchagin
417491f122b346a31cf8dc406c4f9195a5900cecEvgeny Vereshchagin added ++;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (added <= 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _cleanup_free_ char *ip = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier in_addr_to_string(q->request_family, &q->request_address, &ip);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier 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));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_close_container(reply);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
25b47f96d9601ff566257b2a31bfb5f4bd25d661Marko Myllynen
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier goto finish;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_send(q->manager->bus, reply, NULL);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalierfinish:
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier log_error_errno(r, "Failed to send address reply: %m");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier sd_bus_reply_method_errno(q->request, r, NULL);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier }
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier dns_query_free(q);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier}
53d90f9582f96208b3674da823ad1a3d2c3b1aa4Martin Pitt
5c404f1ab8e96efedb983806443ca982a1b2a372Evgeny Vereshchaginstatic int bus_method_resolve_address(sd_bus_message *message, void *userdata, sd_bus_error *error) {
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier Manager *m = userdata;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int family, ifindex;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier uint64_t flags;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier const void *d;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier DnsQuery *q;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier size_t sz;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier int r;
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(message);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(m);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert_cc(sizeof(int) == sizeof(int32_t));
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_read(message, "ii", &ifindex, &family);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (!IN_SET(family, AF_INET, AF_INET6))
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_read_array(message, 'y', &d, &sz);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (sz != FAMILY_ADDRESS_SIZE(family))
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid address size");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_read(message, "t", &flags);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = check_ifindex_flags(ifindex, &flags, 0, error);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_question_new_reverse(&question, family, d);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_query_new(m, &q, question, ifindex, flags);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer q->request = sd_bus_message_ref(message);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer q->request_family = family;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer memcpy(&q->request_address, d, sz);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer q->complete = bus_method_resolve_address_complete;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_query_bus_track(q, message);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto fail;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_query_go(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto fail;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 1;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerfail:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dns_query_free(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int bus_message_append_rr(sd_bus_message *m, DnsResourceRecord *rr, int ifindex) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_(dns_packet_unrefp) DnsPacket *p = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer size_t start;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(m);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier assert(rr);
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier r = sd_bus_message_open_container(m, 'r', "iqqay");
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_append(m, "iqq",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer ifindex,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer rr->key->class,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer rr->key->type);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_packet_new(&p, DNS_PROTOCOL_DNS, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer p->refuse_compression = true;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_packet_append_rr(p, rr, &start);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_append_array(m, 'y', DNS_PACKET_DATA(p) + start, p->size - start);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return sd_bus_message_close_container(m);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void bus_method_resolve_record_complete(DnsQuery *q) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned added = 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (q->state != DNS_TRANSACTION_SUCCESS) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = reply_query_state(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_query_process_cname(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == -ELOOP) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_name(q->question));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r > 0) /* Following a CNAME */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_new_method_return(q->request, &reply);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_open_container(reply, 'a', "(iqqay)");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (q->answer) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsResourceRecord *rr;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int ifindex;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_question_matches_rr(q->question, rr);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = bus_message_append_rr(reply, rr, ifindex);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer added ++;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (added <= 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer 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_name(q->question));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_close_container(reply);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_send(q->manager->bus, reply, NULL);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerfinish:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error_errno(r, "Failed to send record reply: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer sd_bus_reply_method_errno(q->request, r, NULL);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer dns_query_free(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd_bus_error *error) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer Manager *m = userdata;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer uint16_t class, type;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer const char *name;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r, ifindex;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer uint64_t flags;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsQuery *q;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(message);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(m);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert_cc(sizeof(int) == sizeof(int32_t));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_read(message, "isqqt", &ifindex, &name, &class, &type, &flags);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_name_is_valid(name);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid name '%s'", name);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = check_ifindex_flags(ifindex, &flags, 0, error);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer question = dns_question_new(1);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!question)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -ENOMEM;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer key = dns_resource_key_new(class, type, name);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!key)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return -ENOMEM;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_question_add(question, key);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_query_new(m, &q, question, ifindex, flags);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer q->request = sd_bus_message_ref(message);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer q->complete = bus_method_resolve_record_complete;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_query_bus_track(q, message);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto fail;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_query_go(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto fail;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 1;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerfail:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dns_query_free(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int append_srv(DnsQuery *q, sd_bus_message *reply, DnsResourceRecord *rr) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsQuery *aux;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(reply);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rr);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rr->key);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (rr->key->type != DNS_TYPE_SRV)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* First, let's see if we could find an appropriate A or AAAA
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * record for the SRV record */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsResourceRecord *zz;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (aux->state != DNS_TRANSACTION_SUCCESS)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (aux->auxiliary_result != 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_name_equal(dns_question_name(aux->question), rr->srv.name);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DNS_ANSWER_FOREACH(zz, aux->answer) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_question_matches_rr(aux->question, zz);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer canonical = dns_resource_record_ref(zz);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (canonical)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Is there are successful A/AAAA lookup for this SRV RR? If not, don't add it */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!canonical)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_open_container(reply, 'r', "qqqsa(iiay)s");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_append(
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer reply,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "qqqs",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer rr->srv.priority, rr->srv.weight, rr->srv.port, rr->srv.name);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_open_container(reply, 'a', "(iiay)");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsResourceRecord *zz;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int ifindex;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (aux->state != DNS_TRANSACTION_SUCCESS)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (aux->auxiliary_result != 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_name_equal(dns_question_name(aux->question), rr->srv.name);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DNS_ANSWER_FOREACH_IFINDEX(zz, ifindex, aux->answer) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_question_matches_rr(aux->question, zz);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = append_address(reply, zz, ifindex);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_close_container(reply);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* Note that above we appended the hostname as encoded in the
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * SRV, and here the canonical hostname this maps to. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_append(reply, "s", canonical ? DNS_RESOURCE_KEY_NAME(canonical->key) : rr->srv.name);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_close_container(reply);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 1;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int append_txt(sd_bus_message *reply, DnsResourceRecord *rr) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsTxtItem *i;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(reply);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rr);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rr->key);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (rr->key->type != DNS_TYPE_TXT)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer LIST_FOREACH(items, i, rr->txt.items) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (i->length <= 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_append_array(reply, 'y', i->data, i->length);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 1;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void resolve_service_all_complete(DnsQuery *q) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *canonical = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_free_ char *name = NULL, *type = NULL, *domain = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsQuery *aux;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer unsigned added = false;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (q->block_all_complete > 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsQuery *bad = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bool have_success = false;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer LIST_FOREACH(auxiliary_queries, aux, q->auxiliary_queries) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer switch (aux->state) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case DNS_TRANSACTION_PENDING:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* If an auxiliary query is still pending, let's wait */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer case DNS_TRANSACTION_SUCCESS:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (aux->auxiliary_result == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer have_success = true;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer else
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bad = aux;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer default:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer bad = aux;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer break;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!have_success) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* We can only return one error, hence pick the last error we encountered */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(bad);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (bad->state == DNS_TRANSACTION_SUCCESS) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(bad->auxiliary_result != 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (bad->auxiliary_result == -ELOOP) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_name(bad->question));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = bad->auxiliary_result;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = reply_query_state(bad);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_new_method_return(q->request, &reply);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_open_container(reply, 'a', "(qqqsa(iiay)s)");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (q->answer) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsResourceRecord *rr;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DNS_ANSWER_FOREACH(rr, q->answer) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_question_matches_rr(q->question, rr);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = append_srv(q, reply, rr);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == 0) /* not an SRV record */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (!canonical)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer canonical = dns_resource_record_ref(rr);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer added++;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (added <= 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer 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_name(q->question));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_close_container(reply);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_open_container(reply, 'a', "ay");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (q->answer) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsResourceRecord *rr;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DNS_ANSWER_FOREACH(rr, q->answer) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_question_matches_rr(q->question, rr);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r == 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer continue;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = append_txt(reply, rr);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_close_container(reply);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(canonical);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_service_split(DNS_RESOURCE_KEY_NAME(canonical->key), &name, &type, &domain);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_message_append(
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer reply,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "ssst",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer name, type, domain,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer goto finish;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_send(q->manager->bus, reply, NULL);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerfinish:
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error_errno(r, "Failed to send service reply: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer sd_bus_reply_method_errno(q->request, r, NULL);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer dns_query_free(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic void resolve_service_hostname_complete(DnsQuery *q) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(q->auxiliary_for);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (q->state != DNS_TRANSACTION_SUCCESS) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer resolve_service_all_complete(q->auxiliary_for);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_query_process_cname(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r > 0) /* This was a cname, and the query was restarted. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* This auxiliary lookup is finished or failed, let's see if all are finished now. */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer q->auxiliary_result = r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer resolve_service_all_complete(q->auxiliary_for);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerstatic int resolve_service_hostname(DnsQuery *q, DnsResourceRecord *rr, int ifindex) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer DnsQuery *aux;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(q);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rr);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rr->key);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(rr->key->type == DNS_TYPE_SRV);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* OK, we found an SRV record for the service. Let's resolve
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * the hostname included in it */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_question_new_address(&question, q->request_family, rr->srv.name);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = dns_query_new(q->manager, &aux, question, ifindex, q->flags);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer aux->request_family = q->request_family;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer aux->complete = resolve_service_hostname_complete;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_query_make_auxiliary(aux, q);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r == -EAGAIN) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* Too many auxiliary lookups? If so, don't complain,
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * let's just not add this one, we already have more
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * than enough */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer dns_query_free(aux);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return 0;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto fail;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* Note that auxiliary queries do not track the original bus
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * client, only the primary request does that. */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_query_go(aux);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto fail;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return 1;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerfail:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer dns_query_free(aux);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer}
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic void bus_method_resolve_service_complete(DnsQuery *q) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer unsigned found = 0;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer int r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(q);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (q->state != DNS_TRANSACTION_SUCCESS) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = reply_query_state(q);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto finish;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_query_process_cname(q);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r == -ELOOP) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop detected, or CNAME resolving disabled on '%s'", dns_question_name(q->question));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto finish;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto finish;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r > 0) /* This was a cname, and the query was restarted. */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (q->answer) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer DnsResourceRecord *rr;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer int ifindex;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer DNS_ANSWER_FOREACH_IFINDEX(rr, ifindex, q->answer) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_question_matches_rr(q->question, rr);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto finish;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r == 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer continue;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (rr->key->type != DNS_TYPE_SRV)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer continue;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if ((q->flags & SD_RESOLVED_NO_ADDRESS) == 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer q->block_all_complete ++;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = resolve_service_hostname(q, rr, ifindex);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer q->block_all_complete --;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto finish;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer found++;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
c53158818d8cdaf46b3f1b5299b9bda118a1043fThomas Hindoe Paaboel Andersen
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (found <= 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer 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_name(q->question));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto finish;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* Maybe we are already finished? check now... */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer resolve_service_all_complete(q);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerfinish:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_error_errno(r, "Failed to send service reply: %m");
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer sd_bus_reply_method_errno(q->request, r, NULL);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer dns_query_free(q);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer}
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int bus_method_resolve_service(sd_bus_message *message, void *userdata, sd_bus_error *error) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer _cleanup_(dns_question_unrefp) DnsQuestion *question = NULL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer const char *name, *type, *domain, *joined;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer _cleanup_free_ char *n = NULL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer Manager *m = userdata;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer int family, ifindex;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer uint64_t flags;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer DnsQuery *q;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer int r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(message);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(m);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert_cc(sizeof(int) == sizeof(int32_t));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = sd_bus_message_read(message, "isssit", &ifindex, &name, &type, &domain, &family, &flags);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (!IN_SET(family, AF_INET, AF_INET6, AF_UNSPEC))
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown address family %i", family);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (isempty(name))
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer name = NULL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer else {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (!dns_service_name_is_valid(name))
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid service name '%s'", name);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (isempty(type))
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer type = NULL;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer else {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_srv_type_verify(type);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r == 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid SRV service type '%s'", type);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer }
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_name_is_valid(domain);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r == 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid domain '%s'", domain);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (name && !type)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Service name cannot be specified without service type.");
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = check_ifindex_flags(ifindex, &flags, SD_RESOLVED_NO_TXT|SD_RESOLVED_NO_ADDRESS, error);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (type) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* If the type is specified, we generate the full domain name to look up ourselves */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_service_join(name, type, domain, &n);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer joined = n;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer } else
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer /* If no type is specified, we assume the domain
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer * contains the full domain name to lookup already */
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer joined = domain;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_question_new_service(&question, joined, !(flags & SD_RESOLVED_NO_TXT));
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_query_new(m, &q, question, ifindex, flags);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer q->request = sd_bus_message_ref(message);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer q->request_family = family;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer q->complete = bus_method_resolve_service_complete;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_query_bus_track(q, message);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto fail;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = dns_query_go(q);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0)
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer goto fail;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return 1;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerfail:
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer dns_query_free(q);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer}
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic const sd_bus_vtable resolve_vtable[] = {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer SD_BUS_VTABLE_START(0),
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer SD_BUS_METHOD("ResolveHostname", "isit", "a(iiay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer SD_BUS_METHOD("ResolveAddress", "iiayt", "a(is)t", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer SD_BUS_METHOD("ResolveRecord", "isqqt", "a(iqqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer SD_BUS_METHOD("ResolveService", "isssit", "a(qqqsa(iiay)s)aayssst", bus_method_resolve_service, SD_BUS_VTABLE_UNPRIVILEGED),
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer SD_BUS_VTABLE_END,
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer};
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int on_bus_retry(sd_event_source *s, usec_t usec, void *userdata) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer Manager *m = userdata;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(s);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(m);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer m->bus_retry_event_source = sd_event_source_unref(m->bus_retry_event_source);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer manager_connect_bus(m);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return 0;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer}
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyerstatic int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer Manager *m = userdata;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer int b, r;
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(message);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer assert(m);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer r = sd_bus_message_read(message, "b", &b);
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer if (r < 0) {
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer log_debug_errno(r, "Failed to parse PrepareForSleep signal: %m");
0d6e798a784ef0ba6b95512e4453067b2f84a91aHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (b)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_debug("Coming back from suspend, verifying all RRs...");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer manager_verify_all(m);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyerint manager_connect_bus(Manager *m) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer int r;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer assert(m);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (m->bus)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_default_system(&m->bus);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0) {
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer /* We failed to connect? Yuck, we must be in early
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * boot. Let's try in 5s again. As soon as we have
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer * kdbus we can stop doing this... */
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_debug_errno(r, "Failed to connect to bus, trying again in 5s: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer 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);
2c393ed7611a586ef5665aa62453ec57c0f5fef6Evgeny Vereshchagin if (r < 0)
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer return log_error_errno(r, "Failed to install bus reconnect time event: %m");
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer
1ecf6a2b4960229ad1d06c591b4776ddf065e834Harald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer }
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer if (r < 0)
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer return log_error_errno(r, "Failed to register object: %m");
33a5e20ffaa2cbb2853f14265566bac66a7f9026Harald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_request_name(m->bus, "org.freedesktop.resolve1", 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_error_errno(r, "Failed to register name: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_attach_event(m->bus, m->event, 0);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return log_error_errno(r, "Failed to attach bus to event loop: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer r = sd_bus_add_match(m->bus, &m->prepare_for_sleep_slot,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "type='signal',"
889a90422dd47284dffa32b9234a6e58991b000cRonny Chevalier "sender='org.freedesktop.login1',"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "interface='org.freedesktop.login1.Manager',"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "member='PrepareForSleep',"
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer "path='/org/freedesktop/login1'",
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer match_prepare_for_sleep,
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer m);
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer if (r < 0)
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer log_error_errno(r, "Failed to add match for PrepareForSleep: %m");
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer return 0;
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer}
898720b7e9cf3bdf7a93e435cbed5dd6942ecf9bHarald Hoyer