1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2014 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU Lesser General Public License as published by
10 the Free Software Foundation; either version 2.1 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Lesser General Public License for more details.
18 You should have received a copy of the GNU Lesser General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
22 #include "resolved-dns-domain.h"
23 #include "resolved-dns-rr.h"
25 DnsResourceKey* dns_resource_key_new(uint16_t class, uint16_t type, const char *name) {
32 k = malloc0(sizeof(DnsResourceKey) + l + 1);
40 strcpy((char*) k + sizeof(DnsResourceKey), name);
45 DnsResourceKey* dns_resource_key_new_consume(uint16_t class, uint16_t type, char *name) {
50 k = new0(DnsResourceKey, 1);
62 DnsResourceKey* dns_resource_key_ref(DnsResourceKey *k) {
73 DnsResourceKey* dns_resource_key_unref(DnsResourceKey *k) {
88 int dns_resource_key_equal(const DnsResourceKey *a, const DnsResourceKey *b) {
91 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
95 if (a->class != b->class)
98 if (a->type != b->type)
104 int dns_resource_key_match_rr(const DnsResourceKey *key, const DnsResourceRecord *rr) {
108 if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
111 if (rr->key->type != key->type && key->type != DNS_TYPE_ANY)
114 return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
117 int dns_resource_key_match_cname(const DnsResourceKey *key, const DnsResourceRecord *rr) {
121 if (rr->key->class != key->class && key->class != DNS_CLASS_ANY)
124 if (rr->key->type != DNS_TYPE_CNAME)
127 return dns_name_equal(DNS_RESOURCE_KEY_NAME(rr->key), DNS_RESOURCE_KEY_NAME(key));
130 unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
131 const DnsResourceKey *k = i;
134 ul = dns_name_hash_func(DNS_RESOURCE_KEY_NAME(k), hash_key);
135 ul = ul * hash_key[0] + ul + k->class;
136 ul = ul * hash_key[1] + ul + k->type;
141 int dns_resource_key_compare_func(const void *a, const void *b) {
142 const DnsResourceKey *x = a, *y = b;
145 ret = dns_name_compare_func(DNS_RESOURCE_KEY_NAME(x), DNS_RESOURCE_KEY_NAME(y));
149 if (x->type < y->type)
151 if (x->type > y->type)
154 if (x->class < y->class)
156 if (x->class > y->class)
162 DnsResourceRecord* dns_resource_record_new(DnsResourceKey *key) {
163 DnsResourceRecord *rr;
165 rr = new0(DnsResourceRecord, 1);
170 rr->key = dns_resource_key_ref(key);
175 DnsResourceRecord* dns_resource_record_new_full(uint16_t class, uint16_t type, const char *name) {
176 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
178 key = dns_resource_key_new(class, type, name);
182 return dns_resource_record_new(key);
185 DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
189 assert(rr->n_ref > 0);
195 DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
199 assert(rr->n_ref > 0);
207 if (IN_SET(rr->key->type, DNS_TYPE_PTR, DNS_TYPE_NS, DNS_TYPE_CNAME))
209 else if (rr->key->type == DNS_TYPE_HINFO) {
212 } else if (rr->key->type == DNS_TYPE_SOA) {
215 } else if (!IN_SET(rr->key->type, DNS_TYPE_A, DNS_TYPE_AAAA))
216 free(rr->generic.data);
218 dns_resource_key_unref(rr->key);
226 int dns_resource_record_new_reverse(DnsResourceRecord **ret, int family, const union in_addr_union *address, const char *hostname) {
227 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *key = NULL;
228 _cleanup_(dns_resource_record_unrefp) DnsResourceRecord *rr = NULL;
229 _cleanup_free_ char *ptr = NULL;
236 r = dns_name_reverse(family, address, &ptr);
240 key = dns_resource_key_new_consume(DNS_CLASS_IN, DNS_TYPE_PTR, ptr);
246 rr = dns_resource_record_new(key);
250 rr->ptr.name = strdup(hostname);
260 int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
266 r = dns_resource_key_equal(a->key, b->key);
270 if (IN_SET(a->key->type, DNS_TYPE_PTR, DNS_TYPE_NS, DNS_TYPE_CNAME))
271 return dns_name_equal(a->ptr.name, b->ptr.name);
272 else if (a->key->type == DNS_TYPE_HINFO)
273 return strcasecmp(a->hinfo.cpu, b->hinfo.cpu) == 0 &&
274 strcasecmp(a->hinfo.os, b->hinfo.os) == 0;
275 else if (a->key->type == DNS_TYPE_A)
276 return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0;
277 else if (a->key->type == DNS_TYPE_AAAA)
278 return memcmp(&a->aaaa.in6_addr, &b->aaaa.in6_addr, sizeof(struct in6_addr)) == 0;
279 else if (a->key->type == DNS_TYPE_SOA) {
280 r = dns_name_equal(a->soa.mname, b->soa.mname);
283 r = dns_name_equal(a->soa.rname, b->soa.rname);
287 return a->soa.serial == b->soa.serial &&
288 a->soa.refresh == b->soa.refresh &&
289 a->soa.retry == b->soa.retry &&
290 a->soa.expire == b->soa.expire &&
291 a->soa.minimum == b->soa.minimum;
293 return a->generic.size == b->generic.size &&
294 memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
297 const char *dns_class_to_string(uint16_t class) {
311 const char *dns_type_to_string(uint16_t type) {