diff options
Diffstat (limited to 'src/resolve/resolved-dns-answer.c')
-rw-r--r-- | src/resolve/resolved-dns-answer.c | 64 |
1 files changed, 64 insertions, 0 deletions
diff --git a/src/resolve/resolved-dns-answer.c b/src/resolve/resolved-dns-answer.c index fbc282550e..34c854cb3a 100644 --- a/src/resolve/resolved-dns-answer.c +++ b/src/resolve/resolved-dns-answer.c @@ -20,6 +20,7 @@ ***/ #include "resolved-dns-answer.h" +#include "resolved-dns-domain.h" DnsAnswer *dns_answer_new(unsigned n) { DnsAnswer *a; @@ -65,12 +66,75 @@ DnsAnswer *dns_answer_unref(DnsAnswer *a) { } int dns_answer_add(DnsAnswer *a, DnsResourceRecord *rr) { + unsigned i; + int r; + assert(a); assert(rr); + for (i = 0; i < a->n_rrs; i++) { + r = dns_resource_record_equal(a->rrs[i], rr); + if (r < 0) + return r; + if (r > 0) { + /* Entry already exists, keep the entry with + * the higher RR, or the one with TTL 0 */ + + if (rr->ttl == 0 || (rr->ttl > a->rrs[i]->ttl && a->rrs[i]->ttl != 0)) { + dns_resource_record_ref(rr); + dns_resource_record_unref(a->rrs[i]); + a->rrs[i] = rr; + } + + return 0; + } + } + if (a->n_rrs >= a->n_allocated) return -ENOSPC; a->rrs[a->n_rrs++] = dns_resource_record_ref(rr); + return 1; +} + +int dns_answer_contains(DnsAnswer *a, DnsResourceKey *key) { + unsigned i; + int r; + + assert(a); + assert(key); + + for (i = 0; i < a->n_rrs; i++) { + r = dns_resource_key_match_rr(key, a->rrs[i]); + if (r < 0) + return r; + if (r > 0) + return 1; + } + + return 0; +} + +int dns_answer_find_soa(DnsAnswer *a, DnsResourceKey *key, DnsResourceRecord **ret) { + unsigned i; + + assert(a); + assert(key); + assert(ret); + + for (i = 0; i < a->n_rrs; i++) { + + if (a->rrs[i]->key->class != DNS_CLASS_IN) + continue; + + if (a->rrs[i]->key->type != DNS_TYPE_SOA) + continue; + + if (dns_name_endswith(DNS_RESOURCE_KEY_NAME(key), DNS_RESOURCE_KEY_NAME(a->rrs[i]->key))) { + *ret = a->rrs[i]; + return 1; + } + } + return 0; } |