• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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