resolved-bus.c revision 966c66e34940001a40806142ecebaae61b478444
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering This file is part of systemd.
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering Copyright 2014 Lennart Poettering
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering systemd is free software; you can redistribute it and/or modify it
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering under the terms of the GNU Lesser General Public License as published by
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering (at your option) any later version.
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering systemd is distributed in the hope that it will be useful, but
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering Lesser General Public License for more details.
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering You should have received a copy of the GNU Lesser General Public License
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poetteringstatic int reply_query_state(DnsQuery *q) {
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering r = in_addr_to_string(q->request_family, &q->request_address, &ip);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "Query timed out");
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering case DNS_TRANSACTION_ATTEMPTS_MAX_REACHED:
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return sd_bus_reply_method_errorf(q->request, SD_BUS_ERROR_TIMEOUT, "All attempts to contact name servers or networks failed");
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_INVALID_REPLY, "Received invalid reply");
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_RESOURCES, "Not enough resources");
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return sd_bus_reply_method_errorf(q->request, BUS_ERROR_ABORTED, "Query aborted");
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering if (q->answer_rcode == DNS_RCODE_NXDOMAIN)
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering sd_bus_error_setf(&error, _BUS_ERROR_DNS "NXDOMAIN", "'%s' not found", name);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering const char *rc, *n;
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering char p[3]; /* the rcode is 4 bits long */
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering rc = dns_rcode_to_string(q->answer_rcode);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering sd_bus_error_setf(&error, n, "Could not resolve '%s', server or network returned error %s", name, rc);
6bedfcbb2970e06a4d3280c8fb62083d252ede73Lennart Poettering return sd_bus_reply_method_error(q->request, &error);
return -EAFNOSUPPORT;
unsigned added = 0, i;
assert(q);
r = reply_query_state(q);
goto finish;
goto finish;
goto finish;
goto finish;
if (q->answer) {
goto finish;
goto finish;
goto finish;
if (!canonical)
added ++;
if (added == 0) {
if (!cname) {
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "'%s' does not have any RR of requested type", q->request_hostname);
goto finish;
if (r == -ELOOP)
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_CNAME_LOOP, "CNAME loop on '%s'", q->request_hostname);
goto finish;
goto finish;
goto finish;
if (!canonical)
added++;
if (added <= 0) {
r = dns_query_go(q);
if (r == -ESRCH) {
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
goto finish;
goto finish;
goto finish;
r = sd_bus_message_append(reply, "st", DNS_RESOURCE_KEY_NAME(canonical->key), SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
goto finish;
dns_query_free(q);
if (ifindex < 0)
if (*flags == 0)
static int bus_method_resolve_hostname(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *hostname;
DnsQuery *q;
assert(m);
if (!question)
return -ENOMEM;
if (!key)
return -ENOMEM;
if (!key)
return -ENOMEM;
r = dns_query_go(q);
dns_query_free(q);
if (r == -ESRCH)
sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
unsigned added = 0, i;
assert(q);
r = reply_query_state(q);
goto finish;
goto finish;
goto finish;
goto finish;
if (q->answer) {
goto finish;
goto finish;
added ++;
if (added == 0) {
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Address '%s' does not have any RR of requested type", ip);
goto finish;
goto finish;
r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
goto finish;
dns_query_free(q);
static int bus_method_resolve_address(sd_bus_message *message, void *userdata, sd_bus_error *error) {
DnsQuery *q;
assert(m);
if (!question)
return -ENOMEM;
if (!key)
return -ENOMEM;
r = dns_query_go(q);
dns_query_free(q);
if (r == -ESRCH)
sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
unsigned added = 0, i;
assert(q);
r = reply_query_state(q);
goto finish;
goto finish;
goto finish;
goto finish;
if (q->answer) {
goto finish;
goto finish;
goto finish;
goto finish;
goto finish;
goto finish;
goto finish;
added ++;
if (added <= 0) {
r = sd_bus_reply_method_errorf(q->request, BUS_ERROR_NO_SUCH_RR, "Name '%s' does not have any RR of the requested type", q->request_hostname);
goto finish;
goto finish;
r = sd_bus_message_append(reply, "t", SD_RESOLVED_FLAGS_MAKE(q->answer_protocol, q->answer_family));
goto finish;
dns_query_free(q);
static int bus_method_resolve_record(sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
int r, ifindex;
DnsQuery *q;
assert(m);
if (!question)
return -ENOMEM;
if (!key)
return -ENOMEM;
r = dns_query_go(q);
dns_query_free(q);
if (r == -ESRCH)
sd_bus_error_setf(error, BUS_ERROR_NO_NAME_SERVERS, "No appropriate name servers or networks for name found");
SD_BUS_METHOD("ResolveHostname", "isit", "ia(iay)st", bus_method_resolve_hostname, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResolveAddress", "iiayt", "iast", bus_method_resolve_address, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("ResolveRecord", "isqqt", "ia(qqay)t", bus_method_resolve_record, SD_BUS_VTABLE_UNPRIVILEGED),
assert(s);
assert(m);
static int match_prepare_for_sleep(sd_bus_message *message, void *userdata, sd_bus_error *ret_error) {
assert(m);
assert(m);
if (m->bus)
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);
r = sd_bus_add_object_vtable(m->bus, NULL, "/org/freedesktop/resolve1", "org.freedesktop.resolve1.Manager", resolve_vtable, m);
"path='/org/freedesktop/login1'",