chiark / gitweb /
c8f7cf4a4c03d4b7313e005ece4887593455bdd3
[elogind.git] / src / resolve / resolved-dns-rr.c
1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
2
3 /***
4   This file is part of systemd.
5
6   Copyright 2014 Lennart Poettering
7
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.
12
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.
17
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/>.
20 ***/
21
22 #include "resolved-dns-domain.h"
23 #include "resolved-dns-rr.h"
24
25 void dns_resource_key_free(DnsResourceKey *key) {
26         if (!key)
27                 return;
28
29         free(key->name);
30         zero(*key);
31 }
32
33 unsigned long dns_resource_key_hash_func(const void *i, const uint8_t hash_key[HASH_KEY_SIZE]) {
34         const DnsResourceKey *k = i;
35         unsigned long ul;
36
37         ul = dns_name_hash_func(k->name, hash_key);
38         ul = ul * hash_key[0] + ul + k->class;
39         ul = ul * hash_key[1] + ul + k->type;
40
41         return ul;
42 }
43
44 int dns_resource_key_compare_func(const void *a, const void *b) {
45         const DnsResourceKey *x = a, *y = b;
46         int ret;
47
48         ret = dns_name_compare_func(x->name, y->name);
49         if (ret != 0)
50                 return ret;
51
52         if (x->type < y->type)
53                 return -1;
54         if (x->type > y->type)
55                 return 1;
56
57         if (x->class < y->class)
58                 return -1;
59         if (x->class > y->class)
60                 return 1;
61
62         return 0;
63 }
64
65 DnsResourceRecord* dns_resource_record_new(void) {
66         DnsResourceRecord *rr;
67
68         rr = new0(DnsResourceRecord, 1);
69         if (!rr)
70                 return NULL;
71
72         rr->n_ref = 1;
73         return rr;
74 }
75
76 DnsResourceRecord* dns_resource_record_ref(DnsResourceRecord *rr) {
77         if (!rr)
78                 return NULL;
79
80         assert(rr->n_ref > 0);
81         rr->n_ref++;
82
83         return rr;
84 }
85
86 DnsResourceRecord* dns_resource_record_unref(DnsResourceRecord *rr) {
87         if (!rr)
88                 return NULL;
89
90         assert(rr->n_ref > 0);
91
92         if (rr->n_ref > 1) {
93                 rr->n_ref--;
94                 return NULL;
95         }
96
97         if (IN_SET(rr->key.type, DNS_TYPE_PTR, DNS_TYPE_NS, DNS_TYPE_CNAME))
98                 free(rr->ptr.name);
99         else if (rr->key.type == DNS_TYPE_HINFO) {
100                 free(rr->hinfo.cpu);
101                 free(rr->hinfo.os);
102         } else if (!IN_SET(rr->key.type, DNS_TYPE_A, DNS_TYPE_AAAA))
103                 free(rr->generic.data);
104
105         dns_resource_key_free(&rr->key);
106         free(rr);
107
108         return NULL;
109 }
110
111 DnsResourceRecord** dns_resource_record_freev(DnsResourceRecord **rrs, unsigned n) {
112         unsigned i;
113
114         assert(n == 0 || rrs);
115
116         for (i = 0; i < n; i++)
117                 dns_resource_record_unref(rrs[i]);
118
119         free(rrs);
120         return NULL;
121 }
122
123 int dns_resource_record_equal(const DnsResourceRecord *a, const DnsResourceRecord *b) {
124         int r;
125
126         assert(a);
127         assert(b);
128
129         r = dns_name_equal(a->key.name, b->key.name);
130         if (r <= 0)
131                 return r;
132
133         if (a->key.class != b->key.class)
134                 return 0;
135
136         if (a->key.type != b->key.type)
137                 return 0;
138
139         if (IN_SET(a->key.type, DNS_TYPE_PTR, DNS_TYPE_NS, DNS_TYPE_CNAME))
140                 return dns_name_equal(a->ptr.name, b->ptr.name);
141         else if (a->key.type == DNS_TYPE_HINFO)
142                 return strcasecmp(a->hinfo.cpu, b->hinfo.cpu) == 0 &&
143                        strcasecmp(a->hinfo.os, b->hinfo.os) == 0;
144         else if (a->key.type == DNS_TYPE_A)
145                 return memcmp(&a->a.in_addr, &b->a.in_addr, sizeof(struct in_addr)) == 0;
146         else if (a->key.type == DNS_TYPE_AAAA)
147                 return memcmp(&a->aaaa.in6_addr, &b->aaaa.in6_addr, sizeof(struct in6_addr)) == 0;
148         else
149                 return a->generic.size == b->generic.size &&
150                         memcmp(a->generic.data, b->generic.data, a->generic.size) == 0;
151 }
152
153 const char *dns_class_to_string(uint16_t class) {
154
155         switch (class) {
156
157         case DNS_CLASS_IN:
158                 return "IN";
159
160         case DNS_CLASS_ANY:
161                 return "ANY";
162         }
163
164         return NULL;
165 }
166
167 const char *dns_type_to_string(uint16_t type) {
168
169         switch (type) {
170
171         case DNS_TYPE_A:
172                 return "A";
173
174         case DNS_TYPE_NS:
175                 return "NS";
176
177         case DNS_TYPE_CNAME:
178                 return "CNAME";
179
180         case DNS_TYPE_SOA:
181                 return "SOA";
182
183         case DNS_TYPE_PTR:
184                 return "PTR";
185
186         case DNS_TYPE_HINFO:
187                 return "HINFO";
188
189         case DNS_TYPE_MX:
190                 return "MX";
191
192         case DNS_TYPE_TXT:
193                 return "TXT";
194
195         case DNS_TYPE_AAAA:
196                 return "AAAA";
197
198         case DNS_TYPE_SRV:
199                 return "SRV";
200
201         case DNS_TYPE_SSHFP:
202                 return "SSHFP";
203
204         case DNS_TYPE_DNAME:
205                 return "DNAME";
206
207         case DNS_TYPE_ANY:
208                 return "ANY";
209
210         case DNS_TYPE_OPT:
211                 return "OPT";
212
213         case DNS_TYPE_TKEY:
214                 return "TKEY";
215
216         case DNS_TYPE_TSIG:
217                 return "TSIG";
218
219         case DNS_TYPE_IXFR:
220                 return "IXFR";
221
222         case DNS_TYPE_AXFR:
223                 return "AXFR";
224         }
225
226         return NULL;
227 }