1 /* MIT License
2 *
3 * Copyright (c) 2023 Brad House
4 *
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to deal
7 * in the Software without restriction, including without limitation the rights
8 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 * copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
11 *
12 * The above copyright notice and this permission notice (including the next
13 * paragraph) shall be included in all copies or substantial portions of the
14 * Software.
15 *
16 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 *
24 * SPDX-License-Identifier: MIT
25 */
26 #include "ares_private.h"
27
ares_dns_opcode_isvalid(ares_dns_opcode_t opcode)28 ares_bool_t ares_dns_opcode_isvalid(ares_dns_opcode_t opcode)
29 {
30 switch (opcode) {
31 case ARES_OPCODE_QUERY:
32 case ARES_OPCODE_IQUERY:
33 case ARES_OPCODE_STATUS:
34 case ARES_OPCODE_NOTIFY:
35 case ARES_OPCODE_UPDATE:
36 return ARES_TRUE;
37 }
38 return ARES_FALSE;
39 }
40
ares_dns_rcode_isvalid(ares_dns_rcode_t rcode)41 ares_bool_t ares_dns_rcode_isvalid(ares_dns_rcode_t rcode)
42 {
43 switch (rcode) {
44 case ARES_RCODE_NOERROR:
45 case ARES_RCODE_FORMERR:
46 case ARES_RCODE_SERVFAIL:
47 case ARES_RCODE_NXDOMAIN:
48 case ARES_RCODE_NOTIMP:
49 case ARES_RCODE_REFUSED:
50 case ARES_RCODE_YXDOMAIN:
51 case ARES_RCODE_YXRRSET:
52 case ARES_RCODE_NXRRSET:
53 case ARES_RCODE_NOTAUTH:
54 case ARES_RCODE_NOTZONE:
55 case ARES_RCODE_DSOTYPEI:
56 case ARES_RCODE_BADSIG:
57 case ARES_RCODE_BADKEY:
58 case ARES_RCODE_BADTIME:
59 case ARES_RCODE_BADMODE:
60 case ARES_RCODE_BADNAME:
61 case ARES_RCODE_BADALG:
62 case ARES_RCODE_BADTRUNC:
63 case ARES_RCODE_BADCOOKIE:
64 return ARES_TRUE;
65 }
66 return ARES_FALSE;
67 }
68
ares_dns_flags_arevalid(unsigned short flags)69 ares_bool_t ares_dns_flags_arevalid(unsigned short flags)
70 {
71 unsigned short allflags = ARES_FLAG_QR | ARES_FLAG_AA | ARES_FLAG_TC |
72 ARES_FLAG_RD | ARES_FLAG_RA | ARES_FLAG_AD |
73 ARES_FLAG_CD;
74
75 if (flags & ~allflags) {
76 return ARES_FALSE;
77 }
78
79 return ARES_TRUE;
80 }
81
ares_dns_rec_type_isvalid(ares_dns_rec_type_t type,ares_bool_t is_query)82 ares_bool_t ares_dns_rec_type_isvalid(ares_dns_rec_type_t type,
83 ares_bool_t is_query)
84 {
85 switch (type) {
86 case ARES_REC_TYPE_A:
87 case ARES_REC_TYPE_NS:
88 case ARES_REC_TYPE_CNAME:
89 case ARES_REC_TYPE_SOA:
90 case ARES_REC_TYPE_PTR:
91 case ARES_REC_TYPE_HINFO:
92 case ARES_REC_TYPE_MX:
93 case ARES_REC_TYPE_TXT:
94 case ARES_REC_TYPE_SIG:
95 case ARES_REC_TYPE_AAAA:
96 case ARES_REC_TYPE_SRV:
97 case ARES_REC_TYPE_NAPTR:
98 case ARES_REC_TYPE_OPT:
99 case ARES_REC_TYPE_TLSA:
100 case ARES_REC_TYPE_SVCB:
101 case ARES_REC_TYPE_HTTPS:
102 case ARES_REC_TYPE_ANY:
103 case ARES_REC_TYPE_URI:
104 case ARES_REC_TYPE_CAA:
105 return ARES_TRUE;
106 case ARES_REC_TYPE_RAW_RR:
107 return is_query ? ARES_FALSE : ARES_TRUE;
108 default:
109 break;
110 }
111 return is_query ? ARES_TRUE : ARES_FALSE;
112 }
113
ares_dns_rec_allow_name_comp(ares_dns_rec_type_t type)114 ares_bool_t ares_dns_rec_allow_name_comp(ares_dns_rec_type_t type)
115 {
116 /* Only record types defined in RFC1035 allow name compression within the
117 * RDATA. Otherwise nameservers that don't understand an RR may not be
118 * able to pass along the RR in a proper manner */
119 switch (type) {
120 case ARES_REC_TYPE_A:
121 case ARES_REC_TYPE_NS:
122 case ARES_REC_TYPE_CNAME:
123 case ARES_REC_TYPE_SOA:
124 case ARES_REC_TYPE_PTR:
125 case ARES_REC_TYPE_HINFO:
126 case ARES_REC_TYPE_MX:
127 case ARES_REC_TYPE_TXT:
128 return ARES_TRUE;
129 default:
130 break;
131 }
132 return ARES_FALSE;
133 }
134
ares_dns_class_isvalid(ares_dns_class_t qclass,ares_dns_rec_type_t type,ares_bool_t is_query)135 ares_bool_t ares_dns_class_isvalid(ares_dns_class_t qclass,
136 ares_dns_rec_type_t type,
137 ares_bool_t is_query)
138 {
139 /* If we don't understand the record type, we shouldn't validate the class
140 * as there are some instances like on RFC 2391 (SIG RR) the class is
141 * meaningless, but since we didn't support that record type, we didn't
142 * know it shouldn't be validated */
143 if (type == ARES_REC_TYPE_RAW_RR) {
144 return ARES_TRUE;
145 }
146
147 switch (qclass) {
148 case ARES_CLASS_IN:
149 case ARES_CLASS_CHAOS:
150 case ARES_CLASS_HESOID:
151 case ARES_CLASS_NONE:
152 return ARES_TRUE;
153 case ARES_CLASS_ANY:
154 if (type == ARES_REC_TYPE_SIG) {
155 return ARES_TRUE;
156 }
157 if (is_query) {
158 return ARES_TRUE;
159 }
160 return ARES_FALSE;
161 }
162 return ARES_FALSE;
163 }
164
ares_dns_section_isvalid(ares_dns_section_t sect)165 ares_bool_t ares_dns_section_isvalid(ares_dns_section_t sect)
166 {
167 switch (sect) {
168 case ARES_SECTION_ANSWER:
169 case ARES_SECTION_AUTHORITY:
170 case ARES_SECTION_ADDITIONAL:
171 return ARES_TRUE;
172 }
173 return ARES_FALSE;
174 }
175
ares_dns_rr_key_to_rec_type(ares_dns_rr_key_t key)176 ares_dns_rec_type_t ares_dns_rr_key_to_rec_type(ares_dns_rr_key_t key)
177 {
178 /* NOTE: due to the way we've numerated the keys, we can simply divide by
179 * 100 to get the type rather than having to do a huge switch
180 * statement. That said, we do then validate the type returned is
181 * valid in case something completely bogus is passed in */
182 ares_dns_rec_type_t type = key / 100;
183 if (!ares_dns_rec_type_isvalid(type, ARES_FALSE)) {
184 return 0;
185 }
186 return type;
187 }
188
ares_dns_rec_type_tostr(ares_dns_rec_type_t type)189 const char *ares_dns_rec_type_tostr(ares_dns_rec_type_t type)
190 {
191 switch (type) {
192 case ARES_REC_TYPE_A:
193 return "A";
194 case ARES_REC_TYPE_NS:
195 return "NS";
196 case ARES_REC_TYPE_CNAME:
197 return "CNAME";
198 case ARES_REC_TYPE_SOA:
199 return "SOA";
200 case ARES_REC_TYPE_PTR:
201 return "PTR";
202 case ARES_REC_TYPE_HINFO:
203 return "HINFO";
204 case ARES_REC_TYPE_MX:
205 return "MX";
206 case ARES_REC_TYPE_TXT:
207 return "TXT";
208 case ARES_REC_TYPE_SIG:
209 return "SIG";
210 case ARES_REC_TYPE_AAAA:
211 return "AAAA";
212 case ARES_REC_TYPE_SRV:
213 return "SRV";
214 case ARES_REC_TYPE_NAPTR:
215 return "NAPTR";
216 case ARES_REC_TYPE_OPT:
217 return "OPT";
218 case ARES_REC_TYPE_TLSA:
219 return "TLSA";
220 case ARES_REC_TYPE_SVCB:
221 return "SVCB";
222 case ARES_REC_TYPE_HTTPS:
223 return "HTTPS";
224 case ARES_REC_TYPE_ANY:
225 return "ANY";
226 case ARES_REC_TYPE_URI:
227 return "URI";
228 case ARES_REC_TYPE_CAA:
229 return "CAA";
230 case ARES_REC_TYPE_RAW_RR:
231 return "RAWRR";
232 }
233 return "UNKNOWN";
234 }
235
ares_dns_class_tostr(ares_dns_class_t qclass)236 const char *ares_dns_class_tostr(ares_dns_class_t qclass)
237 {
238 switch (qclass) {
239 case ARES_CLASS_IN:
240 return "IN";
241 case ARES_CLASS_CHAOS:
242 return "CH";
243 case ARES_CLASS_HESOID:
244 return "HS";
245 case ARES_CLASS_ANY:
246 return "ANY";
247 case ARES_CLASS_NONE:
248 return "NONE";
249 }
250 return "UNKNOWN";
251 }
252
ares_dns_opcode_tostr(ares_dns_opcode_t opcode)253 const char *ares_dns_opcode_tostr(ares_dns_opcode_t opcode)
254 {
255 switch (opcode) {
256 case ARES_OPCODE_QUERY:
257 return "QUERY";
258 case ARES_OPCODE_IQUERY:
259 return "IQUERY";
260 case ARES_OPCODE_STATUS:
261 return "STATUS";
262 case ARES_OPCODE_NOTIFY:
263 return "NOTIFY";
264 case ARES_OPCODE_UPDATE:
265 return "UPDATE";
266 }
267 return "UNKNOWN";
268 }
269
ares_dns_rr_key_tostr(ares_dns_rr_key_t key)270 const char *ares_dns_rr_key_tostr(ares_dns_rr_key_t key)
271 {
272 switch (key) {
273 case ARES_RR_A_ADDR:
274 return "ADDR";
275
276 case ARES_RR_NS_NSDNAME:
277 return "NSDNAME";
278
279 case ARES_RR_CNAME_CNAME:
280 return "CNAME";
281
282 case ARES_RR_SOA_MNAME:
283 return "MNAME";
284
285 case ARES_RR_SOA_RNAME:
286 return "RNAME";
287
288 case ARES_RR_SOA_SERIAL:
289 return "SERIAL";
290
291 case ARES_RR_SOA_REFRESH:
292 return "REFRESH";
293
294 case ARES_RR_SOA_RETRY:
295 return "RETRY";
296
297 case ARES_RR_SOA_EXPIRE:
298 return "EXPIRE";
299
300 case ARES_RR_SOA_MINIMUM:
301 return "MINIMUM";
302
303 case ARES_RR_PTR_DNAME:
304 return "DNAME";
305
306 case ARES_RR_AAAA_ADDR:
307 return "ADDR";
308
309 case ARES_RR_HINFO_CPU:
310 return "CPU";
311
312 case ARES_RR_HINFO_OS:
313 return "OS";
314
315 case ARES_RR_MX_PREFERENCE:
316 return "PREFERENCE";
317
318 case ARES_RR_MX_EXCHANGE:
319 return "EXCHANGE";
320
321 case ARES_RR_TXT_DATA:
322 return "DATA";
323
324 case ARES_RR_SIG_TYPE_COVERED:
325 return "TYPE_COVERED";
326
327 case ARES_RR_SIG_ALGORITHM:
328 return "ALGORITHM";
329
330 case ARES_RR_SIG_LABELS:
331 return "LABELS";
332
333 case ARES_RR_SIG_ORIGINAL_TTL:
334 return "ORIGINAL_TTL";
335
336 case ARES_RR_SIG_EXPIRATION:
337 return "EXPIRATION";
338
339 case ARES_RR_SIG_INCEPTION:
340 return "INCEPTION";
341
342 case ARES_RR_SIG_KEY_TAG:
343 return "KEY_TAG";
344
345 case ARES_RR_SIG_SIGNERS_NAME:
346 return "SIGNERS_NAME";
347
348 case ARES_RR_SIG_SIGNATURE:
349 return "SIGNATURE";
350
351 case ARES_RR_SRV_PRIORITY:
352 return "PRIORITY";
353
354 case ARES_RR_SRV_WEIGHT:
355 return "WEIGHT";
356
357 case ARES_RR_SRV_PORT:
358 return "PORT";
359
360 case ARES_RR_SRV_TARGET:
361 return "TARGET";
362
363 case ARES_RR_NAPTR_ORDER:
364 return "ORDER";
365
366 case ARES_RR_NAPTR_PREFERENCE:
367 return "PREFERENCE";
368
369 case ARES_RR_NAPTR_FLAGS:
370 return "FLAGS";
371
372 case ARES_RR_NAPTR_SERVICES:
373 return "SERVICES";
374
375 case ARES_RR_NAPTR_REGEXP:
376 return "REGEXP";
377
378 case ARES_RR_NAPTR_REPLACEMENT:
379 return "REPLACEMENT";
380
381 case ARES_RR_OPT_UDP_SIZE:
382 return "UDP_SIZE";
383
384 case ARES_RR_OPT_VERSION:
385 return "VERSION";
386
387 case ARES_RR_OPT_FLAGS:
388 return "FLAGS";
389
390 case ARES_RR_OPT_OPTIONS:
391 return "OPTIONS";
392
393 case ARES_RR_TLSA_CERT_USAGE:
394 return "CERT_USAGE";
395
396 case ARES_RR_TLSA_SELECTOR:
397 return "SELECTOR";
398
399 case ARES_RR_TLSA_MATCH:
400 return "MATCH";
401
402 case ARES_RR_TLSA_DATA:
403 return "DATA";
404
405 case ARES_RR_SVCB_PRIORITY:
406 return "PRIORITY";
407
408 case ARES_RR_SVCB_TARGET:
409 return "TARGET";
410
411 case ARES_RR_SVCB_PARAMS:
412 return "PARAMS";
413
414 case ARES_RR_HTTPS_PRIORITY:
415 return "PRIORITY";
416
417 case ARES_RR_HTTPS_TARGET:
418 return "TARGET";
419
420 case ARES_RR_HTTPS_PARAMS:
421 return "PARAMS";
422
423 case ARES_RR_URI_PRIORITY:
424 return "PRIORITY";
425
426 case ARES_RR_URI_WEIGHT:
427 return "WEIGHT";
428
429 case ARES_RR_URI_TARGET:
430 return "TARGET";
431
432 case ARES_RR_CAA_CRITICAL:
433 return "CRITICAL";
434
435 case ARES_RR_CAA_TAG:
436 return "TAG";
437
438 case ARES_RR_CAA_VALUE:
439 return "VALUE";
440
441 case ARES_RR_RAW_RR_TYPE:
442 return "TYPE";
443
444 case ARES_RR_RAW_RR_DATA:
445 return "DATA";
446 }
447
448 return "UNKNOWN";
449 }
450
ares_dns_rr_key_datatype(ares_dns_rr_key_t key)451 ares_dns_datatype_t ares_dns_rr_key_datatype(ares_dns_rr_key_t key)
452 {
453 switch (key) {
454 case ARES_RR_A_ADDR:
455 return ARES_DATATYPE_INADDR;
456
457 case ARES_RR_AAAA_ADDR:
458 return ARES_DATATYPE_INADDR6;
459
460 case ARES_RR_NS_NSDNAME:
461 case ARES_RR_CNAME_CNAME:
462 case ARES_RR_SOA_MNAME:
463 case ARES_RR_SOA_RNAME:
464 case ARES_RR_PTR_DNAME:
465 case ARES_RR_MX_EXCHANGE:
466 case ARES_RR_SIG_SIGNERS_NAME:
467 case ARES_RR_SRV_TARGET:
468 case ARES_RR_SVCB_TARGET:
469 case ARES_RR_HTTPS_TARGET:
470 case ARES_RR_NAPTR_REPLACEMENT:
471 case ARES_RR_URI_TARGET:
472 return ARES_DATATYPE_NAME;
473
474 case ARES_RR_HINFO_CPU:
475 case ARES_RR_HINFO_OS:
476 case ARES_RR_NAPTR_FLAGS:
477 case ARES_RR_NAPTR_SERVICES:
478 case ARES_RR_NAPTR_REGEXP:
479 case ARES_RR_CAA_TAG:
480 return ARES_DATATYPE_STR;
481
482 case ARES_RR_SOA_SERIAL:
483 case ARES_RR_SOA_REFRESH:
484 case ARES_RR_SOA_RETRY:
485 case ARES_RR_SOA_EXPIRE:
486 case ARES_RR_SOA_MINIMUM:
487 case ARES_RR_SIG_ORIGINAL_TTL:
488 case ARES_RR_SIG_EXPIRATION:
489 case ARES_RR_SIG_INCEPTION:
490 return ARES_DATATYPE_U32;
491
492 case ARES_RR_MX_PREFERENCE:
493 case ARES_RR_SIG_TYPE_COVERED:
494 case ARES_RR_SIG_KEY_TAG:
495 case ARES_RR_SRV_PRIORITY:
496 case ARES_RR_SRV_WEIGHT:
497 case ARES_RR_SRV_PORT:
498 case ARES_RR_NAPTR_ORDER:
499 case ARES_RR_NAPTR_PREFERENCE:
500 case ARES_RR_OPT_UDP_SIZE:
501 case ARES_RR_OPT_FLAGS:
502 case ARES_RR_SVCB_PRIORITY:
503 case ARES_RR_HTTPS_PRIORITY:
504 case ARES_RR_URI_PRIORITY:
505 case ARES_RR_URI_WEIGHT:
506 case ARES_RR_RAW_RR_TYPE:
507 return ARES_DATATYPE_U16;
508
509 case ARES_RR_SIG_ALGORITHM:
510 case ARES_RR_SIG_LABELS:
511 case ARES_RR_OPT_VERSION:
512 case ARES_RR_TLSA_CERT_USAGE:
513 case ARES_RR_TLSA_SELECTOR:
514 case ARES_RR_TLSA_MATCH:
515 case ARES_RR_CAA_CRITICAL:
516 return ARES_DATATYPE_U8;
517
518 case ARES_RR_CAA_VALUE:
519 return ARES_DATATYPE_BINP;
520
521 case ARES_RR_TXT_DATA:
522 return ARES_DATATYPE_ABINP;
523
524 case ARES_RR_SIG_SIGNATURE:
525 case ARES_RR_TLSA_DATA:
526 case ARES_RR_RAW_RR_DATA:
527 return ARES_DATATYPE_BIN;
528
529 case ARES_RR_OPT_OPTIONS:
530 case ARES_RR_SVCB_PARAMS:
531 case ARES_RR_HTTPS_PARAMS:
532 return ARES_DATATYPE_OPT;
533 }
534
535 return 0;
536 }
537
538 static const ares_dns_rr_key_t rr_a_keys[] = { ARES_RR_A_ADDR };
539 static const ares_dns_rr_key_t rr_ns_keys[] = { ARES_RR_NS_NSDNAME };
540 static const ares_dns_rr_key_t rr_cname_keys[] = { ARES_RR_CNAME_CNAME };
541 static const ares_dns_rr_key_t rr_soa_keys[] = {
542 ARES_RR_SOA_MNAME, ARES_RR_SOA_RNAME, ARES_RR_SOA_SERIAL,
543 ARES_RR_SOA_REFRESH, ARES_RR_SOA_RETRY, ARES_RR_SOA_EXPIRE,
544 ARES_RR_SOA_MINIMUM
545 };
546 static const ares_dns_rr_key_t rr_ptr_keys[] = { ARES_RR_PTR_DNAME };
547 static const ares_dns_rr_key_t rr_hinfo_keys[] = { ARES_RR_HINFO_CPU,
548 ARES_RR_HINFO_OS };
549 static const ares_dns_rr_key_t rr_mx_keys[] = { ARES_RR_MX_PREFERENCE,
550 ARES_RR_MX_EXCHANGE };
551 static const ares_dns_rr_key_t rr_sig_keys[] = {
552 ARES_RR_SIG_TYPE_COVERED, ARES_RR_SIG_ALGORITHM, ARES_RR_SIG_LABELS,
553 ARES_RR_SIG_ORIGINAL_TTL, ARES_RR_SIG_EXPIRATION, ARES_RR_SIG_INCEPTION,
554 ARES_RR_SIG_KEY_TAG, ARES_RR_SIG_SIGNERS_NAME, ARES_RR_SIG_SIGNATURE
555 };
556 static const ares_dns_rr_key_t rr_txt_keys[] = { ARES_RR_TXT_DATA };
557 static const ares_dns_rr_key_t rr_aaaa_keys[] = { ARES_RR_AAAA_ADDR };
558 static const ares_dns_rr_key_t rr_srv_keys[] = {
559 ARES_RR_SRV_PRIORITY, ARES_RR_SRV_WEIGHT, ARES_RR_SRV_PORT, ARES_RR_SRV_TARGET
560 };
561 static const ares_dns_rr_key_t rr_naptr_keys[] = {
562 ARES_RR_NAPTR_ORDER, ARES_RR_NAPTR_PREFERENCE, ARES_RR_NAPTR_FLAGS,
563 ARES_RR_NAPTR_SERVICES, ARES_RR_NAPTR_REGEXP, ARES_RR_NAPTR_REPLACEMENT
564 };
565 static const ares_dns_rr_key_t rr_opt_keys[] = { ARES_RR_OPT_UDP_SIZE,
566 ARES_RR_OPT_VERSION,
567 ARES_RR_OPT_FLAGS,
568 ARES_RR_OPT_OPTIONS };
569 static const ares_dns_rr_key_t rr_tlsa_keys[] = { ARES_RR_TLSA_CERT_USAGE,
570 ARES_RR_TLSA_SELECTOR,
571 ARES_RR_TLSA_MATCH,
572 ARES_RR_TLSA_DATA };
573 static const ares_dns_rr_key_t rr_svcb_keys[] = { ARES_RR_SVCB_PRIORITY,
574 ARES_RR_SVCB_TARGET,
575 ARES_RR_SVCB_PARAMS };
576 static const ares_dns_rr_key_t rr_https_keys[] = { ARES_RR_HTTPS_PRIORITY,
577 ARES_RR_HTTPS_TARGET,
578 ARES_RR_HTTPS_PARAMS };
579 static const ares_dns_rr_key_t rr_uri_keys[] = { ARES_RR_URI_PRIORITY,
580 ARES_RR_URI_WEIGHT,
581 ARES_RR_URI_TARGET };
582 static const ares_dns_rr_key_t rr_caa_keys[] = { ARES_RR_CAA_CRITICAL,
583 ARES_RR_CAA_TAG,
584 ARES_RR_CAA_VALUE };
585 static const ares_dns_rr_key_t rr_raw_rr_keys[] = { ARES_RR_RAW_RR_TYPE,
586 ARES_RR_RAW_RR_DATA };
587
ares_dns_rr_get_keys(ares_dns_rec_type_t type,size_t * cnt)588 const ares_dns_rr_key_t *ares_dns_rr_get_keys(ares_dns_rec_type_t type,
589 size_t *cnt)
590 {
591 if (cnt == NULL) {
592 return NULL;
593 }
594
595 *cnt = 0;
596
597 switch (type) {
598 case ARES_REC_TYPE_A:
599 *cnt = sizeof(rr_a_keys) / sizeof(*rr_a_keys);
600 return rr_a_keys;
601 case ARES_REC_TYPE_NS:
602 *cnt = sizeof(rr_ns_keys) / sizeof(*rr_ns_keys);
603 return rr_ns_keys;
604 case ARES_REC_TYPE_CNAME:
605 *cnt = sizeof(rr_cname_keys) / sizeof(*rr_cname_keys);
606 return rr_cname_keys;
607 case ARES_REC_TYPE_SOA:
608 *cnt = sizeof(rr_soa_keys) / sizeof(*rr_soa_keys);
609 return rr_soa_keys;
610 case ARES_REC_TYPE_PTR:
611 *cnt = sizeof(rr_ptr_keys) / sizeof(*rr_ptr_keys);
612 return rr_ptr_keys;
613 case ARES_REC_TYPE_HINFO:
614 *cnt = sizeof(rr_hinfo_keys) / sizeof(*rr_hinfo_keys);
615 return rr_hinfo_keys;
616 case ARES_REC_TYPE_MX:
617 *cnt = sizeof(rr_mx_keys) / sizeof(*rr_mx_keys);
618 return rr_mx_keys;
619 case ARES_REC_TYPE_TXT:
620 *cnt = sizeof(rr_txt_keys) / sizeof(*rr_txt_keys);
621 return rr_txt_keys;
622 case ARES_REC_TYPE_SIG:
623 *cnt = sizeof(rr_sig_keys) / sizeof(*rr_sig_keys);
624 return rr_sig_keys;
625 case ARES_REC_TYPE_AAAA:
626 *cnt = sizeof(rr_aaaa_keys) / sizeof(*rr_aaaa_keys);
627 return rr_aaaa_keys;
628 case ARES_REC_TYPE_SRV:
629 *cnt = sizeof(rr_srv_keys) / sizeof(*rr_srv_keys);
630 return rr_srv_keys;
631 case ARES_REC_TYPE_NAPTR:
632 *cnt = sizeof(rr_naptr_keys) / sizeof(*rr_naptr_keys);
633 return rr_naptr_keys;
634 case ARES_REC_TYPE_OPT:
635 *cnt = sizeof(rr_opt_keys) / sizeof(*rr_opt_keys);
636 return rr_opt_keys;
637 case ARES_REC_TYPE_TLSA:
638 *cnt = sizeof(rr_tlsa_keys) / sizeof(*rr_tlsa_keys);
639 return rr_tlsa_keys;
640 case ARES_REC_TYPE_SVCB:
641 *cnt = sizeof(rr_svcb_keys) / sizeof(*rr_svcb_keys);
642 return rr_svcb_keys;
643 case ARES_REC_TYPE_HTTPS:
644 *cnt = sizeof(rr_https_keys) / sizeof(*rr_https_keys);
645 return rr_https_keys;
646 case ARES_REC_TYPE_ANY:
647 /* Not real */
648 break;
649 case ARES_REC_TYPE_URI:
650 *cnt = sizeof(rr_uri_keys) / sizeof(*rr_uri_keys);
651 return rr_uri_keys;
652 case ARES_REC_TYPE_CAA:
653 *cnt = sizeof(rr_caa_keys) / sizeof(*rr_caa_keys);
654 return rr_caa_keys;
655 case ARES_REC_TYPE_RAW_RR:
656 *cnt = sizeof(rr_raw_rr_keys) / sizeof(*rr_raw_rr_keys);
657 return rr_raw_rr_keys;
658 }
659
660 return NULL;
661 }
662
ares_dns_class_fromstr(ares_dns_class_t * qclass,const char * str)663 ares_bool_t ares_dns_class_fromstr(ares_dns_class_t *qclass, const char *str)
664 {
665 size_t i;
666
667 static const struct {
668 const char *name;
669 ares_dns_class_t qclass;
670 } list[] = {
671 { "IN", ARES_CLASS_IN },
672 { "CH", ARES_CLASS_CHAOS },
673 { "HS", ARES_CLASS_HESOID },
674 { "NONE", ARES_CLASS_NONE },
675 { "ANY", ARES_CLASS_ANY },
676 { NULL, 0 }
677 };
678
679 if (qclass == NULL || str == NULL) {
680 return ARES_FALSE;
681 }
682
683 for (i = 0; list[i].name != NULL; i++) {
684 if (ares_strcaseeq(list[i].name, str)) {
685 *qclass = list[i].qclass;
686 return ARES_TRUE;
687 }
688 }
689 return ARES_FALSE;
690 }
691
ares_dns_rec_type_fromstr(ares_dns_rec_type_t * qtype,const char * str)692 ares_bool_t ares_dns_rec_type_fromstr(ares_dns_rec_type_t *qtype,
693 const char *str)
694 {
695 size_t i;
696
697 static const struct {
698 const char *name;
699 ares_dns_rec_type_t type;
700 } list[] = {
701 { "A", ARES_REC_TYPE_A },
702 { "NS", ARES_REC_TYPE_NS },
703 { "CNAME", ARES_REC_TYPE_CNAME },
704 { "SOA", ARES_REC_TYPE_SOA },
705 { "PTR", ARES_REC_TYPE_PTR },
706 { "HINFO", ARES_REC_TYPE_HINFO },
707 { "MX", ARES_REC_TYPE_MX },
708 { "TXT", ARES_REC_TYPE_TXT },
709 { "SIG", ARES_REC_TYPE_SIG },
710 { "AAAA", ARES_REC_TYPE_AAAA },
711 { "SRV", ARES_REC_TYPE_SRV },
712 { "NAPTR", ARES_REC_TYPE_NAPTR },
713 { "OPT", ARES_REC_TYPE_OPT },
714 { "TLSA", ARES_REC_TYPE_TLSA },
715 { "SVCB", ARES_REC_TYPE_SVCB },
716 { "HTTPS", ARES_REC_TYPE_HTTPS },
717 { "ANY", ARES_REC_TYPE_ANY },
718 { "URI", ARES_REC_TYPE_URI },
719 { "CAA", ARES_REC_TYPE_CAA },
720 { "RAW_RR", ARES_REC_TYPE_RAW_RR },
721 { NULL, 0 }
722 };
723
724 if (qtype == NULL || str == NULL) {
725 return ARES_FALSE;
726 }
727
728 for (i = 0; list[i].name != NULL; i++) {
729 if (ares_strcaseeq(list[i].name, str)) {
730 *qtype = list[i].type;
731 return ARES_TRUE;
732 }
733 }
734 return ARES_FALSE;
735 }
736
ares_dns_section_tostr(ares_dns_section_t section)737 const char *ares_dns_section_tostr(ares_dns_section_t section)
738 {
739 switch (section) {
740 case ARES_SECTION_ANSWER:
741 return "ANSWER";
742 case ARES_SECTION_AUTHORITY:
743 return "AUTHORITY";
744 case ARES_SECTION_ADDITIONAL:
745 return "ADDITIONAL";
746 }
747 return "UNKNOWN";
748 }
749
ares_dns_opt_get_type_opt(unsigned short opt)750 static ares_dns_opt_datatype_t ares_dns_opt_get_type_opt(unsigned short opt)
751 {
752 ares_opt_param_t param = (ares_opt_param_t)opt;
753 switch (param) {
754 case ARES_OPT_PARAM_LLQ:
755 /* Really it is u16 version, u16 opcode, u16 error, u64 id, u32 lease */
756 return ARES_OPT_DATATYPE_BIN;
757 case ARES_OPT_PARAM_UL:
758 return ARES_OPT_DATATYPE_U32;
759 case ARES_OPT_PARAM_NSID:
760 return ARES_OPT_DATATYPE_BIN;
761 case ARES_OPT_PARAM_DAU:
762 return ARES_OPT_DATATYPE_U8_LIST;
763 case ARES_OPT_PARAM_DHU:
764 return ARES_OPT_DATATYPE_U8_LIST;
765 case ARES_OPT_PARAM_N3U:
766 return ARES_OPT_DATATYPE_U8_LIST;
767 case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET:
768 /* Really it is a u16 address family, u8 source prefix length,
769 * u8 scope prefix length, address */
770 return ARES_OPT_DATATYPE_BIN;
771 case ARES_OPT_PARAM_EDNS_EXPIRE:
772 return ARES_OPT_DATATYPE_U32;
773 case ARES_OPT_PARAM_COOKIE:
774 /* 8 bytes for client, 16-40 bytes for server */
775 return ARES_OPT_DATATYPE_BIN;
776 case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE:
777 /* Timeout in 100ms intervals */
778 return ARES_OPT_DATATYPE_U16;
779 case ARES_OPT_PARAM_PADDING:
780 /* Arbitrary padding */
781 return ARES_OPT_DATATYPE_BIN;
782 case ARES_OPT_PARAM_CHAIN:
783 return ARES_OPT_DATATYPE_NAME;
784 case ARES_OPT_PARAM_EDNS_KEY_TAG:
785 return ARES_OPT_DATATYPE_U16_LIST;
786 case ARES_OPT_PARAM_EXTENDED_DNS_ERROR:
787 /* Really 16bit code followed by textual message */
788 return ARES_OPT_DATATYPE_BIN;
789 }
790 return ARES_OPT_DATATYPE_BIN;
791 }
792
ares_dns_opt_get_type_svcb(unsigned short opt)793 static ares_dns_opt_datatype_t ares_dns_opt_get_type_svcb(unsigned short opt)
794 {
795 ares_svcb_param_t param = (ares_svcb_param_t)opt;
796 switch (param) {
797 case ARES_SVCB_PARAM_NO_DEFAULT_ALPN:
798 return ARES_OPT_DATATYPE_NONE;
799 case ARES_SVCB_PARAM_ECH:
800 return ARES_OPT_DATATYPE_BIN;
801 case ARES_SVCB_PARAM_MANDATORY:
802 return ARES_OPT_DATATYPE_U16_LIST;
803 case ARES_SVCB_PARAM_ALPN:
804 return ARES_OPT_DATATYPE_STR_LIST;
805 case ARES_SVCB_PARAM_PORT:
806 return ARES_OPT_DATATYPE_U16;
807 case ARES_SVCB_PARAM_IPV4HINT:
808 return ARES_OPT_DATATYPE_INADDR4_LIST;
809 case ARES_SVCB_PARAM_IPV6HINT:
810 return ARES_OPT_DATATYPE_INADDR6_LIST;
811 }
812 return ARES_OPT_DATATYPE_BIN;
813 }
814
ares_dns_opt_get_datatype(ares_dns_rr_key_t key,unsigned short opt)815 ares_dns_opt_datatype_t ares_dns_opt_get_datatype(ares_dns_rr_key_t key,
816 unsigned short opt)
817 {
818 switch (key) {
819 case ARES_RR_OPT_OPTIONS:
820 return ares_dns_opt_get_type_opt(opt);
821 case ARES_RR_SVCB_PARAMS:
822 case ARES_RR_HTTPS_PARAMS:
823 return ares_dns_opt_get_type_svcb(opt);
824 default:
825 break;
826 }
827 return ARES_OPT_DATATYPE_BIN;
828 }
829
ares_dns_opt_get_name_opt(unsigned short opt)830 static const char *ares_dns_opt_get_name_opt(unsigned short opt)
831 {
832 ares_opt_param_t param = (ares_opt_param_t)opt;
833 switch (param) {
834 case ARES_OPT_PARAM_LLQ:
835 return "LLQ";
836 case ARES_OPT_PARAM_UL:
837 return "UL";
838 case ARES_OPT_PARAM_NSID:
839 return "NSID";
840 case ARES_OPT_PARAM_DAU:
841 return "DAU";
842 case ARES_OPT_PARAM_DHU:
843 return "DHU";
844 case ARES_OPT_PARAM_N3U:
845 return "N3U";
846 case ARES_OPT_PARAM_EDNS_CLIENT_SUBNET:
847 return "edns-client-subnet";
848 case ARES_OPT_PARAM_EDNS_EXPIRE:
849 return "edns-expire";
850 case ARES_OPT_PARAM_COOKIE:
851 return "COOKIE";
852 case ARES_OPT_PARAM_EDNS_TCP_KEEPALIVE:
853 return "edns-tcp-keepalive";
854 case ARES_OPT_PARAM_PADDING:
855 return "Padding";
856 case ARES_OPT_PARAM_CHAIN:
857 return "CHAIN";
858 case ARES_OPT_PARAM_EDNS_KEY_TAG:
859 return "edns-key-tag";
860 case ARES_OPT_PARAM_EXTENDED_DNS_ERROR:
861 return "extended-dns-error";
862 }
863 return NULL;
864 }
865
ares_dns_opt_get_name_svcb(unsigned short opt)866 static const char *ares_dns_opt_get_name_svcb(unsigned short opt)
867 {
868 ares_svcb_param_t param = (ares_svcb_param_t)opt;
869 switch (param) {
870 case ARES_SVCB_PARAM_NO_DEFAULT_ALPN:
871 return "no-default-alpn";
872 case ARES_SVCB_PARAM_ECH:
873 return "ech";
874 case ARES_SVCB_PARAM_MANDATORY:
875 return "mandatory";
876 case ARES_SVCB_PARAM_ALPN:
877 return "alpn";
878 case ARES_SVCB_PARAM_PORT:
879 return "port";
880 case ARES_SVCB_PARAM_IPV4HINT:
881 return "ipv4hint";
882 case ARES_SVCB_PARAM_IPV6HINT:
883 return "ipv6hint";
884 }
885 return NULL;
886 }
887
ares_dns_opt_get_name(ares_dns_rr_key_t key,unsigned short opt)888 const char *ares_dns_opt_get_name(ares_dns_rr_key_t key, unsigned short opt)
889 {
890 switch (key) {
891 case ARES_RR_OPT_OPTIONS:
892 return ares_dns_opt_get_name_opt(opt);
893 case ARES_RR_SVCB_PARAMS:
894 case ARES_RR_HTTPS_PARAMS:
895 return ares_dns_opt_get_name_svcb(opt);
896 default:
897 break;
898 }
899 return NULL;
900 }
901
ares_dns_rcode_tostr(ares_dns_rcode_t rcode)902 const char *ares_dns_rcode_tostr(ares_dns_rcode_t rcode)
903 {
904 switch (rcode) {
905 case ARES_RCODE_NOERROR:
906 return "NOERROR";
907 case ARES_RCODE_FORMERR:
908 return "FORMERR";
909 case ARES_RCODE_SERVFAIL:
910 return "SERVFAIL";
911 case ARES_RCODE_NXDOMAIN:
912 return "NXDOMAIN";
913 case ARES_RCODE_NOTIMP:
914 return "NOTIMP";
915 case ARES_RCODE_REFUSED:
916 return "REFUSED";
917 case ARES_RCODE_YXDOMAIN:
918 return "YXDOMAIN";
919 case ARES_RCODE_YXRRSET:
920 return "YXRRSET";
921 case ARES_RCODE_NXRRSET:
922 return "NXRRSET";
923 case ARES_RCODE_NOTAUTH:
924 return "NOTAUTH";
925 case ARES_RCODE_NOTZONE:
926 return "NOTZONE";
927 case ARES_RCODE_DSOTYPEI:
928 return "DSOTYPEI";
929 case ARES_RCODE_BADSIG:
930 return "BADSIG";
931 case ARES_RCODE_BADKEY:
932 return "BADKEY";
933 case ARES_RCODE_BADTIME:
934 return "BADTIME";
935 case ARES_RCODE_BADMODE:
936 return "BADMODE";
937 case ARES_RCODE_BADNAME:
938 return "BADNAME";
939 case ARES_RCODE_BADALG:
940 return "BADALG";
941 case ARES_RCODE_BADTRUNC:
942 return "BADTRUNC";
943 case ARES_RCODE_BADCOOKIE:
944 return "BADCOOKIE";
945 }
946
947 return "UNKNOWN";
948 }
949
950 /* Convert an rcode and ancount from a query reply into an ares_status_t
951 * value. Used internally by ares_search() and ares_query().
952 */
ares_dns_query_reply_tostatus(ares_dns_rcode_t rcode,size_t ancount)953 ares_status_t ares_dns_query_reply_tostatus(ares_dns_rcode_t rcode,
954 size_t ancount)
955 {
956 ares_status_t status = ARES_SUCCESS;
957
958 switch (rcode) {
959 case ARES_RCODE_NOERROR:
960 status = (ancount > 0) ? ARES_SUCCESS : ARES_ENODATA;
961 break;
962 case ARES_RCODE_FORMERR:
963 status = ARES_EFORMERR;
964 break;
965 case ARES_RCODE_SERVFAIL:
966 status = ARES_ESERVFAIL;
967 break;
968 case ARES_RCODE_NXDOMAIN:
969 status = ARES_ENOTFOUND;
970 break;
971 case ARES_RCODE_NOTIMP:
972 status = ARES_ENOTIMP;
973 break;
974 case ARES_RCODE_REFUSED:
975 status = ARES_EREFUSED;
976 break;
977 default:
978 break;
979 }
980
981 return status;
982 }
983