]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/resolve/resolved-dns-question.c
resolved: minor typo comment fix
[thirdparty/systemd.git] / src / resolve / resolved-dns-question.c
CommitLineData
faa133f3
LP
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-question.h"
4ad7f276 23#include "dns-domain.h"
faa133f3
LP
24
25DnsQuestion *dns_question_new(unsigned n) {
26 DnsQuestion *q;
27
28 assert(n > 0);
29
30 q = malloc0(offsetof(DnsQuestion, keys) + sizeof(DnsResourceKey*) * n);
31 if (!q)
32 return NULL;
33
34 q->n_ref = 1;
35 q->n_allocated = n;
36
37 return q;
38}
39
40DnsQuestion *dns_question_ref(DnsQuestion *q) {
41 if (!q)
42 return NULL;
43
44 assert(q->n_ref > 0);
45 q->n_ref++;
46 return q;
47}
48
49DnsQuestion *dns_question_unref(DnsQuestion *q) {
50 if (!q)
51 return NULL;
52
53 assert(q->n_ref > 0);
54
55 if (q->n_ref == 1) {
56 unsigned i;
57
58 for (i = 0; i < q->n_keys; i++)
59 dns_resource_key_unref(q->keys[i]);
60 free(q);
61 } else
62 q->n_ref--;
63
64 return NULL;
65}
66
67int dns_question_add(DnsQuestion *q, DnsResourceKey *key) {
7e8e0422
LP
68 unsigned i;
69 int r;
70
faa133f3
LP
71 assert(q);
72 assert(key);
73
7e8e0422
LP
74 for (i = 0; i < q->n_keys; i++) {
75 r = dns_resource_key_equal(q->keys[i], key);
76 if (r < 0)
77 return r;
78 if (r > 0)
79 return 0;
80 }
81
faa133f3
LP
82 if (q->n_keys >= q->n_allocated)
83 return -ENOSPC;
84
85 q->keys[q->n_keys++] = dns_resource_key_ref(key);
86 return 0;
87}
88
89int dns_question_matches_rr(DnsQuestion *q, DnsResourceRecord *rr) {
90 unsigned i;
91 int r;
92
93 assert(q);
94 assert(rr);
95
96 for (i = 0; i < q->n_keys; i++) {
97 r = dns_resource_key_match_rr(q->keys[i], rr);
98 if (r != 0)
99 return r;
100 }
101
102 return 0;
103}
104
105int dns_question_matches_cname(DnsQuestion *q, DnsResourceRecord *rr) {
106 unsigned i;
107 int r;
108
109 assert(q);
110 assert(rr);
111
112 for (i = 0; i < q->n_keys; i++) {
113 r = dns_resource_key_match_cname(q->keys[i], rr);
114 if (r != 0)
115 return r;
116 }
117
34b9656f 118 return 0;
faa133f3
LP
119}
120
121int dns_question_is_valid(DnsQuestion *q) {
122 const char *name;
123 unsigned i;
124 int r;
125
126 assert(q);
127
128 if (q->n_keys <= 0)
129 return 0;
130
131 if (q->n_keys > 65535)
132 return 0;
133
134 name = DNS_RESOURCE_KEY_NAME(q->keys[0]);
135 if (!name)
136 return 0;
137
138 /* Check that all keys in this question bear the same name */
139 for (i = 1; i < q->n_keys; i++) {
34b9656f
LP
140 assert(q->keys[i]);
141
faa133f3
LP
142 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), name);
143 if (r <= 0)
144 return r;
145 }
146
147 return 1;
148}
149
150int dns_question_is_superset(DnsQuestion *q, DnsQuestion *other) {
151 unsigned j;
152 int r;
153
154 assert(q);
155 assert(other);
156
157 /* Checks if all keys in "other" are also contained in "q" */
158
159 for (j = 0; j < other->n_keys; j++) {
160 DnsResourceKey *b = other->keys[j];
161 bool found = false;
162 unsigned i;
163
164 for (i = 0; i < q->n_keys; i++) {
165 DnsResourceKey *a = q->keys[i];
166
167 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(a), DNS_RESOURCE_KEY_NAME(b));
168 if (r < 0)
169 return r;
170
171 if (r == 0)
172 continue;
173
174 if (a->class != b->class && a->class != DNS_CLASS_ANY)
175 continue;
176
177 if (a->type != b->type && a->type != DNS_TYPE_ANY)
178 continue;
179
180 found = true;
181 break;
182 }
183
184 if (!found)
185 return 0;
186 }
187
188 return 1;
189}
190
1086182d
LP
191int dns_question_contains(DnsQuestion *a, DnsResourceKey *k) {
192 unsigned j;
193 int r;
194
195 assert(a);
196 assert(k);
197
198 for (j = 0; j < a->n_keys; j++) {
199 r = dns_resource_key_equal(a->keys[j], k);
200 if (r != 0)
201 return r;
202 }
203
204 return 0;
205}
206
207int dns_question_is_equal(DnsQuestion *a, DnsQuestion *b) {
208 unsigned j;
209 int r;
210
211 assert(a);
212 assert(b);
213
214 /* Checks if all keys in a are also contained b, and vice versa */
215
216 for (j = 0; j < a->n_keys; j++) {
217 r = dns_question_contains(b, a->keys[j]);
218 if (r <= 0)
219 return r;
220 }
221
222 for (j = 0; j < b->n_keys; j++) {
223 r = dns_question_contains(a, b->keys[j]);
224 if (r <= 0)
225 return r;
226 }
227
228 return 1;
229}
230
faa133f3
LP
231int dns_question_cname_redirect(DnsQuestion *q, const char *name, DnsQuestion **ret) {
232 _cleanup_(dns_question_unrefp) DnsQuestion *n = NULL;
233 bool same = true;
234 unsigned i;
235 int r;
236
237 assert(q);
238 assert(name);
239 assert(ret);
240
241 for (i = 0; i < q->n_keys; i++) {
242 r = dns_name_equal(DNS_RESOURCE_KEY_NAME(q->keys[i]), name);
243 if (r < 0)
244 return r;
245
246 if (r == 0) {
247 same = false;
248 break;
249 }
250 }
251
252 if (same) {
253 /* Shortcut, the names are already right */
254 *ret = dns_question_ref(q);
255 return 0;
256 }
257
258 n = dns_question_new(q->n_keys);
259 if (!n)
260 return -ENOMEM;
261
262 /* Create a new question, and patch in the new name */
34b9656f 263 for (i = 0; i < q->n_keys; i++) {
faa133f3
LP
264 _cleanup_(dns_resource_key_unrefp) DnsResourceKey *k = NULL;
265
266 k = dns_resource_key_new(q->keys[i]->class, q->keys[i]->type, name);
267 if (!k)
268 return -ENOMEM;
269
270 r = dns_question_add(n, k);
271 if (r < 0)
272 return r;
273 }
274
275 *ret = n;
276 n = NULL;
277
278 return 1;
279}
b914e211
LP
280
281int dns_question_endswith(DnsQuestion *q, const char *suffix) {
282 unsigned i;
283
284 assert(q);
285 assert(suffix);
286
287 for (i = 0; i < q->n_keys; i++) {
288 int k;
289
290 k = dns_name_endswith(DNS_RESOURCE_KEY_NAME(q->keys[i]), suffix);
291 if (k <= 0)
292 return k;
293 }
294
295 return 1;
296}
297
298int dns_question_extract_reverse_address(DnsQuestion *q, int *family, union in_addr_union *address) {
299 unsigned i;
300
301 assert(q);
302 assert(family);
303 assert(address);
304
305 for (i = 0; i < q->n_keys; i++) {
306 int k;
307
308 k = dns_name_address(DNS_RESOURCE_KEY_NAME(q->keys[i]), family, address);
309 if (k != 0)
310 return k;
311 }
312
313 return 0;
314}