resolved-dns-answer.c revision 81f7fc5e841472b626698f386ed9445dac13944a
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering This file is part of systemd.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering Copyright 2014 Lennart Poettering
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering systemd is free software; you can redistribute it and/or modify it
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering under the terms of the GNU Lesser General Public License as published by
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering (at your option) any later version.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering systemd is distributed in the hope that it will be useful, but
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering Lesser General Public License for more details.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering You should have received a copy of the GNU Lesser General Public License
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering a = malloc0(offsetof(DnsAnswer, items) + sizeof(DnsAnswerItem) * n);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringstatic void dns_answer_flush(DnsAnswer *a) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart PoetteringDnsAnswer *dns_answer_unref(DnsAnswer *a) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringstatic int dns_answer_add_raw(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags) {
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersenstatic int dns_answer_add_raw_all(DnsAnswer *a, DnsAnswer *source) {
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, source) {
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidt r = dns_answer_add_raw(a, rr, ifindex, flags);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringint dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering for (i = 0; i < a->n_rrs; i++) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering r = dns_resource_record_equal(a->items[i].rr, rr);
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek /* Entry already exists, keep the entry with
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering * the higher RR, or the one with TTL 0 */
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering if (rr->ttl == 0 || (rr->ttl > a->items[i].rr->ttl && a->items[i].rr->ttl != 0)) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering dns_resource_record_unref(a->items[i].rr);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering return dns_answer_add_raw(a, rr, ifindex, flags);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringstatic int dns_answer_add_all(DnsAnswer *a, DnsAnswer *b) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering DNS_ANSWER_FOREACH_FULL(rr, ifindex, flags, b) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering r = dns_answer_add(a, rr, ifindex, flags);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringint dns_answer_add_extend(DnsAnswer **a, DnsResourceRecord *rr, int ifindex, DnsAnswerFlags flags) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering return dns_answer_add(*a, rr, ifindex, flags);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringint dns_answer_add_soa(DnsAnswer *a, const char *name, uint32_t ttl) {
if (!soa)
return -ENOMEM;
return -ENOMEM;
return -ENOMEM;
bool found = false;
if (!ret_flags)
if (found)
found = true;
if (ret_flags)
return found;
bool found = false;
if (!ret_flags)
if (found)
found = true;
if (ret_flags)
return found;
bool found = false;
if (!ret_flags)
if (found)
found = true;
if (ret_flags)
return found;
DNS_ANSWER_FOREACH(i, a) {
int dns_answer_find_soa(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret, DnsAnswerFlags *flags) {
if (soa) {
if (!soa)
if (ret)
if (flags)
int dns_answer_find_cname_or_dname(DnsAnswer *a, const DnsResourceKey *key, DnsResourceRecord **ret, DnsAnswerFlags *flags) {
if (ret)
if (flags)
if (dns_answer_size(a) <= 0) {
if (dns_answer_size(b) <= 0) {
return -ENOMEM;
r = dns_answer_add_raw_all(k, a);
r = dns_answer_add_all(k, b);
*ret = k;
k = NULL;
assert(a);
dns_answer_unref(*a);
*a = merged;
assert(a);
found = true;
other = true;
if (!found)
if (!other) {
int ifindex;
if (!copy)
return -ENOMEM;
dns_answer_unref(*a);
*a = copy;
if (i >= (*a)->n_rrs)
(*a)->n_rrs --;
int dns_answer_copy_by_key(DnsAnswer **a, DnsAnswer *source, const DnsResourceKey *key, DnsAnswerFlags or_flags) {
int ifindex_source, r;
assert(a);
int dns_answer_move_by_key(DnsAnswer **to, DnsAnswer **from, const DnsResourceKey *key, DnsAnswerFlags or_flags) {
start = 0;
for (i = 0; i < a->n_rrs; i++) {
((a->items[i].rr->key->type == DNS_TYPE_A && in_addr_is_link_local(AF_INET, (union in_addr_union*) &a->items[i].rr->a.in_addr) != prefer_link_local) ||
(a->items[i].rr->key->type == DNS_TYPE_AAAA && in_addr_is_link_local(AF_INET6, (union in_addr_union*) &a->items[i].rr->aaaa.in6_addr) != prefer_link_local)))
DnsAnswer *n;
assert(a);
if (n_free <= 0)
unsigned ns;
return -EBUSY;
return -ENOMEM;
return -ENOMEM;
assert(a);
if (r != -EBUSY)
assert(*a);
return -ENOMEM;
r = dns_answer_add_raw_all(n, *a);
dns_answer_unref(*a);
n = NULL;
int ifindex, r;
f = stdout;
log_oom();
fputs(t, f);
if (ifindex != 0 || flags & (DNS_ANSWER_AUTHENTICATED|DNS_ANSWER_CACHEABLE|DNS_ANSWER_SHARED_OWNER))
if (ifindex != 0)