resolved-dns-query.c revision a7bf2ada62db599efbb2fbabcc4dc45997b87415
340d89e06e503836de9c124d650845f4889f8c2cLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
along with systemd; If not, see <http://www.gnu.org/licenses/>.
#include "alloc-util.h"
#include "dns-domain.h"
#include "hostname-util.h"
#include "local-addresses.h"
#include "resolved-dns-query.h"
#include "resolved-dns-synthesize.h"
#include "resolved-etc-hosts.h"
#include "string-util.h"
assert(q);
assert(s);
return -ENOMEM;
c->query = q;
c->scope = s;
*ret = c;
DnsTransaction *t;
assert(c);
return NULL;
if (c->query)
if (c->scope)
free(c);
return NULL;
assert(c);
DnsTransaction *t;
assert(c);
goto gc;
goto gc;
goto gc;
goto gc;
gc:
DnsTransaction *t;
Iterator i;
assert(c);
r = dns_transaction_go(t);
DnsTransaction *t;
Iterator i;
assert(c);
if (c->error_code != 0)
return DNS_TRANSACTION_ERRNO;
switch (t->state) {
case DNS_TRANSACTION_NULL:
case DNS_TRANSACTION_PENDING:
return DNS_TRANSACTION_PENDING;
case DNS_TRANSACTION_SUCCESS:
return state;
assert(c);
if (c->search_domain) {
goto fail;
goto fail;
fail:
assert(c);
goto fail;
goto fail;
r = dns_query_candidate_go(c);
goto fail;
fail:
c->error_code = r;
assert(q);
assert(q);
while (q->candidates)
assert(q);
q->answer_rcode = 0;
q->answer_errno = 0;
q->answer_authenticated = false;
return NULL;
while (q->auxiliary_queries)
if (q->auxiliary_for) {
if (q->manager) {
free(q);
return NULL;
int dns_query_new(
Manager *m,
bool good = false;
assert(m);
return -EINVAL;
good = true;
return -EINVAL;
good = true;
return -EINVAL;
return -EBUSY;
return -ENOMEM;
/* And then dump the IDNA question, but only what hasn't been dumped already through the UTF8 question. */
m->n_dns_queries++;
q->manager = m;
if (ret)
*ret = q;
q = NULL;
assert(q);
return -EAGAIN;
assert(q);
dns_query_stop(q);
if (q->complete)
q->complete(q);
assert(s);
assert(q);
assert(q);
assert(s);
r = dns_query_candidate_new(&c, q, s);
goto fail;
goto fail;
goto fail;
fail:
assert(q);
/* Tries to synthesize localhost RR replies (and others) where appropriate. Note that this is done *after* the
q->manager,
q->question_utf8,
q->ifindex,
&answer);
q->answer_authenticated = true;
assert(q);
/* Looks in /etc/hosts for matching entries. Note that this is done *before* the normal lookup is done. The
q->manager,
q->question_utf8,
&answer);
q->answer_authenticated = true;
assert(q);
r = dns_query_try_etc_hosts(q);
const char *name;
if (!name)
if (match < 0)
return match;
first = s;
if (!first)
first = s;
goto fail;
const char *name;
if (!name)
if (match < 0)
goto fail;
r = dns_query_add_candidate(q, s);
goto fail;
q->answer_rcode = 0;
r = sd_event_add_time(
&q->timeout_event_source,
on_query_timeout, q);
goto fail;
q->block_ready++;
r = dns_query_candidate_go(c);
q->block_ready--;
goto fail;
q->block_ready--;
dns_query_ready(q);
fail:
dns_query_stop(q);
DnssecResult dnssec_result_authenticated = _DNSSEC_RESULT_INVALID, dnssec_result_non_authenticated = _DNSSEC_RESULT_INVALID;
DnsTransaction *t;
Iterator i;
assert(q);
goto fail;
if (c->error_code != 0) {
q->answer_rcode = 0;
switch (t->state) {
case DNS_TRANSACTION_SUCCESS: {
goto fail;
q->answer_errno = 0;
if (t->answer_authenticated) {
has_authenticated = true;
has_non_authenticated = true;
case DNS_TRANSACTION_NULL:
case DNS_TRANSACTION_PENDING:
case DNS_TRANSACTION_ABORTED:
q->answer_dnssec_result = q->answer_authenticated ? dnssec_result_authenticated : dnssec_result_non_authenticated;
goto fail;
fail:
q->answer_errno = -r;
bool pending = false;
assert(q);
if (q->block_ready > 0)
switch (state) {
case DNS_TRANSACTION_SUCCESS:
dns_query_accept(q, c);
case DNS_TRANSACTION_NULL:
case DNS_TRANSACTION_PENDING:
pending = true;
bad = c;
if (pending)
assert(q);
q->n_cname_redirects ++;
return -ELOOP;
log_debug("Following CNAME/DNAME %s → %s.", dns_question_first_name(q->question_idna), dns_question_first_name(nq_idna));
log_debug("Following UTF8 CNAME/DNAME %s → %s.", dns_question_first_name(q->question_utf8), dns_question_first_name(nq_utf8));
return -ELOOP;
assert(q);
return DNS_QUERY_NOMATCH;
r = dns_question_matches_cname_or_dname(question, rr, DNS_SEARCH_DOMAIN_NAME(q->answer_search_domain));
if (r > 0 && !cname)
if (!cname)
return -ELOOP;
r = dns_query_process_cname(q);
if (r != DNS_QUERY_NOMATCH)
r = dns_query_go(q);
assert(t);
assert(q);
assert(q);
assert(m);
if (!q->bus_track) {
assert(q);
switch (protocol) {
case DNS_PROTOCOL_DNS:
return q->question_idna;
case DNS_PROTOCOL_MDNS:
case DNS_PROTOCOL_LLMNR:
return q->question_utf8;
return NULL;
const char *name;
if (q->request_address_string)
return q->request_address_string;
if (q->request_address_valid) {
return q->request_address_string;
if (name)
return name;