]> git.ipfire.org Git - thirdparty/systemd.git/blob - src/resolve/resolved-dns-rr.c
nss-myhostname: don't include assert.h twice
[thirdparty/systemd.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 }