1 /**
2 *
3 * \file util-internal.c
4 * @brief private library routines
5 *
6 * These routines are not intended to be used by applications calling into
7 * the library.
8 *
9 */
10
11 /*
12 * Copyright (c) 2013, NLnet Labs, Verisign, Inc.
13 * All rights reserved.
14 *
15 * Redistribution and use in source and binary forms, with or without
16 * modification, are permitted provided that the following conditions are met:
17 * * Redistributions of source code must retain the above copyright
18 * notice, this list of conditions and the following disclaimer.
19 * * Redistributions in binary form must reproduce the above copyright
20 * notice, this list of conditions and the following disclaimer in the
21 * documentation and/or other materials provided with the distribution.
22 * * Neither the names of the copyright holders nor the
23 * names of its contributors may be used to endorse or promote products
24 * derived from this software without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
28 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
29 * DISCLAIMED. IN NO EVENT SHALL Verisign, Inc. BE LIABLE FOR ANY
30 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
31 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
32 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
33 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
35 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36 */
37
38 #include <stdint.h>
39 #include <stdlib.h>
40 #include "config.h"
41 #include "getdns/getdns.h"
42 #include "dict.h"
43 #include "list.h"
44 #include "util-internal.h"
45 #include "types-internal.h"
46 #include "rr-dict.h"
47 #if defined(WIRE_DEBUG) && WIRE_DEBUG
48 #include "gldns/wire2str.h"
49 #endif
50 #include "gldns/str2wire.h"
51 #include "gldns/gbuffer.h"
52 #include "gldns/pkthdr.h"
53 #include "dnssec.h"
54
55
56 getdns_return_t
getdns_dict_util_get_string(const getdns_dict * dict,const char * name,char ** result)57 getdns_dict_util_get_string(const getdns_dict *dict,
58 const char *name, char **result)
59 {
60 struct getdns_bindata *bindata = NULL;
61 if (!result) {
62 return GETDNS_RETURN_GENERIC_ERROR;
63 }
64 *result = NULL;
65 getdns_dict_get_bindata(dict, name, &bindata);
66 if (!bindata) {
67 return GETDNS_RETURN_GENERIC_ERROR;
68 }
69 *result = (char *) bindata->data;
70 return GETDNS_RETURN_GOOD;
71 }
72
73 getdns_return_t
_getdns_dict_to_sockaddr(struct getdns_dict * ns,struct sockaddr_storage * output)74 _getdns_dict_to_sockaddr(struct getdns_dict * ns, struct sockaddr_storage * output)
75 {
76 char *address_type = NULL;
77 struct getdns_bindata *address_data = NULL;
78 uint32_t port = 53;
79 memset(output, 0, sizeof(struct sockaddr_storage));
80 output->ss_family = AF_UNSPEC;
81
82 uint32_t prt = 0;
83 if (getdns_dict_get_int(ns, GETDNS_STR_PORT,
84 &prt) == GETDNS_RETURN_GOOD) {
85 port = prt;
86 }
87
88 getdns_dict_util_get_string(ns, GETDNS_STR_ADDRESS_TYPE,
89 &address_type);
90 getdns_dict_get_bindata(ns, GETDNS_STR_ADDRESS_DATA, &address_data);
91 if (!address_type || !address_data) {
92 return GETDNS_RETURN_GENERIC_ERROR;
93 }
94 if (strncmp(GETDNS_STR_IPV4, address_type,
95 strlen(GETDNS_STR_IPV4)) == 0) {
96 /* data is an in_addr_t */
97 struct sockaddr_in *addr = (struct sockaddr_in *) output;
98 addr->sin_family = AF_INET;
99 addr->sin_port = htons((uint16_t) port);
100 memcpy(&(addr->sin_addr), address_data->data,
101 address_data->size);
102 } else {
103 /* data is a v6 addr in host order */
104 struct sockaddr_in6 *addr = (struct sockaddr_in6 *) output;
105 addr->sin6_family = AF_INET6;
106 addr->sin6_port = htons((uint16_t) port);
107 memcpy(&(addr->sin6_addr), address_data->data,
108 address_data->size);
109 }
110 return GETDNS_RETURN_GOOD;
111 }
112
113 getdns_return_t
_getdns_sockaddr_to_dict(struct getdns_context * context,struct sockaddr_storage * address,struct getdns_dict ** output)114 _getdns_sockaddr_to_dict(struct getdns_context *context, struct sockaddr_storage *address,
115 struct getdns_dict ** output)
116 {
117 if (!output || !address) {
118 return GETDNS_RETURN_GENERIC_ERROR;
119 }
120 struct getdns_bindata addr_data;
121 *output = NULL;
122 struct getdns_dict *result = getdns_dict_create_with_context(context);
123 if (address->ss_family == AF_INET) {
124 struct sockaddr_in *addr = (struct sockaddr_in *) address;
125 getdns_dict_util_set_string(result, GETDNS_STR_ADDRESS_TYPE,
126 GETDNS_STR_IPV4);
127 addr_data.size = sizeof(addr->sin_addr);
128 addr_data.data = (uint8_t *) & (addr->sin_addr);
129 getdns_dict_set_bindata(result, GETDNS_STR_ADDRESS_DATA,
130 &addr_data);
131 } else if (address->ss_family == AF_INET6) {
132 struct sockaddr_in6 *addr = (struct sockaddr_in6 *) address;
133 getdns_dict_util_set_string(result, GETDNS_STR_ADDRESS_TYPE,
134 GETDNS_STR_IPV6);
135 addr_data.size = sizeof(addr->sin6_addr);
136 addr_data.data = (uint8_t *) & (addr->sin6_addr);
137 getdns_dict_set_bindata(result, GETDNS_STR_ADDRESS_DATA,
138 &addr_data);
139 } else {
140 // invalid
141 getdns_dict_destroy(result);
142 return GETDNS_RETURN_GENERIC_ERROR;
143 }
144 *output = result;
145 return GETDNS_RETURN_GOOD;
146 }
147
148 getdns_dict *
_getdns_rr_iter2rr_dict_canonical(struct mem_funcs * mf,_getdns_rr_iter * i,uint32_t * orig_ttl)149 _getdns_rr_iter2rr_dict_canonical(
150 struct mem_funcs *mf, _getdns_rr_iter *i, uint32_t *orig_ttl)
151 {
152 getdns_dict *rr_dict, *rdata_dict;
153 const uint8_t *bin_data;
154 size_t bin_size, owner_len = 0, rdata_sz;
155 uint32_t int_val = 0;
156 enum wf_data_type { wf_int, wf_bindata, wf_special } val_type;
157 _getdns_rdf_iter rdf_storage, *rdf;
158 getdns_list *repeat_list = NULL;
159 getdns_dict *repeat_dict = NULL;
160 uint8_t ff_bytes[256];
161 uint16_t rr_type;
162 int canonicalize;
163 gldns_buffer gbuf;
164 getdns_bindata *bindata;
165 uint8_t *data;
166
167 assert(i);
168 if (!(rr_dict = _getdns_dict_create_with_mf(mf)))
169 return NULL;
170
171 bin_data = _getdns_owner_if_or_as_decompressed(
172 i, ff_bytes, &bin_size);
173
174 if (orig_ttl) {
175 if (bin_data != ff_bytes)
176 bin_data = memcpy(ff_bytes, bin_data, bin_size);
177 _dname_canonicalize2(ff_bytes);
178 owner_len = bin_size;
179 }
180 /* question */
181 if (_getdns_rr_iter_section(i) == SECTION_QUESTION) {
182
183 if (getdns_dict_set_int(rr_dict, "qtype",
184 (uint32_t) gldns_read_uint16(i->rr_type)) ||
185
186 getdns_dict_set_int(rr_dict, "qclass",
187 (uint32_t) gldns_read_uint16(i->rr_type + 2)) ||
188
189 _getdns_dict_set_const_bindata(
190 rr_dict, "qname", bin_size, bin_data)) {
191
192 goto error;
193 }
194 return rr_dict;
195 }
196 if (getdns_dict_set_int(rr_dict, "type",
197 (uint32_t)(rr_type = gldns_read_uint16(i->rr_type)))) {
198
199 goto error;
200 }
201 canonicalize = orig_ttl && _dnssec_rdata_to_canonicalize(rr_type)
202 && (i->rr_type + 12 <= i->nxt) /* To estimate rdata size */;
203
204 if (rr_type == GETDNS_RRTYPE_OPT) {
205 int_val = gldns_read_uint16(i->rr_type + 6);
206
207 if (getdns_dict_set_int(rr_dict, "udp_payload_size",
208 (uint32_t) gldns_read_uint16(i->rr_type + 2)) ||
209
210 getdns_dict_set_int(rr_dict, "extended_rcode",
211 (uint32_t) *(i->rr_type + 4)) ||
212
213 getdns_dict_set_int(rr_dict, "version",
214 (uint32_t) *(i->rr_type + 5)) ||
215
216 getdns_dict_set_int(rr_dict, "do",
217 (uint32_t) ((int_val & 0x8000) >> 15)) ||
218
219 getdns_dict_set_int(rr_dict, "z",
220 (uint32_t) (int_val & 0x7FF))) {
221
222 goto error;
223 }
224 } else if (getdns_dict_set_int(rr_dict, "class",
225 (uint32_t) gldns_read_uint16(i->rr_type + 2)) ||
226
227 getdns_dict_set_int(rr_dict, "ttl",
228 ( orig_ttl && rr_type != GETDNS_RRTYPE_RRSIG
229 ? *orig_ttl : (uint32_t) gldns_read_uint32(i->rr_type + 4))) ||
230
231 _getdns_dict_set_const_bindata(
232 rr_dict, "name", bin_size, bin_data)) {
233
234 goto error;
235 }
236 if (!(rdata_dict = _getdns_dict_create_with_mf(mf)))
237 return NULL;
238
239 if (i->rr_type + 10 <= i->nxt && !canonicalize) {
240 bin_size = i->nxt - (i->rr_type + 10);
241 bin_data = i->rr_type + 10;
242 if (_getdns_dict_set_const_bindata(
243 rdata_dict, "rdata_raw", bin_size, bin_data))
244 goto rdata_error;
245 }
246 if (canonicalize)
247 rdata_sz = 0;
248
249 for ( rdf = _getdns_rdf_iter_init(&rdf_storage, i)
250 ; rdf; rdf = _getdns_rdf_iter_next(rdf)) {
251 if (canonicalize && !(rdf->rdd_pos->type & GETDNS_RDF_DNAME)) {
252 rdata_sz += rdf->nxt - rdf->pos;
253 }
254 if (rdf->rdd_pos->type & GETDNS_RDF_INTEGER) {
255 val_type = wf_int;
256 switch (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) {
257 case 1: int_val = *rdf->pos;
258 break;
259 case 2: int_val = gldns_read_uint16(rdf->pos);
260 break;
261 case 4: int_val = gldns_read_uint32(rdf->pos);
262 break;
263 default:
264 goto rdata_error;
265 }
266 } else if (rdf->rdd_pos->type & GETDNS_RDF_DNAME) {
267 val_type = wf_bindata;
268
269 bin_data = _getdns_rdf_if_or_as_decompressed(
270 rdf, ff_bytes, &bin_size);
271
272 if (canonicalize) {
273 if (bin_data != ff_bytes)
274 bin_data = memcpy(ff_bytes, bin_data, bin_size);
275 _dname_canonicalize2(ff_bytes);
276 rdata_sz += bin_size;
277 }
278 } else if (rdf->rdd_pos->type & GETDNS_RDF_BINDATA) {
279 val_type = wf_bindata;
280 if (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) {
281 bin_size = rdf->rdd_pos->type
282 & GETDNS_RDF_FIXEDSZ;
283 bin_data = rdf->pos;
284
285 } else switch(rdf->rdd_pos->type & GETDNS_RDF_LEN_VAL){
286 case 0x100:
287 bin_size = *rdf->pos;
288 bin_data = rdf->pos + 1;
289 break;
290 case 0x200:
291 bin_size = gldns_read_uint16(rdf->pos);
292 bin_data = rdf->pos + 2;
293 break;
294 default:
295 bin_size = rdf->nxt - rdf->pos;
296 bin_data = rdf->pos;
297 break;
298 }
299 } else if (rdf->rdd_pos->type == GETDNS_RDF_SPECIAL)
300 val_type = wf_special;
301 else
302 assert(((val_type = wf_int), 0));
303
304 if (! rdf->rdd_repeat) {
305 switch (val_type) {
306 case wf_int:
307 if (getdns_dict_set_int(rdata_dict,
308 rdf->rdd_pos->name, int_val))
309 goto rdata_error;
310 break;
311 case wf_bindata:
312 if (_getdns_dict_set_const_bindata(rdata_dict,
313 rdf->rdd_pos->name, bin_size, bin_data))
314 goto rdata_error;
315 break;
316 case wf_special:
317 if (rdf->rdd_pos->special->wire2dict(
318 rdata_dict, rdf->pos))
319 goto rdata_error;
320 default:
321 break;
322 }
323 continue;
324 }
325 if (rdf->rdd_pos == rdf->rdd_repeat) {
326 /* list with rdf values */
327
328 if (! repeat_list && !(repeat_list =
329 _getdns_list_create_with_mf(mf)))
330
331 goto rdata_error;
332
333 switch (val_type) {
334 case wf_int:
335 if (_getdns_list_append_int(repeat_list,
336 int_val))
337 goto rdata_error;
338 break;
339 case wf_bindata:
340 if (_getdns_list_append_const_bindata(
341 repeat_list, bin_size, bin_data))
342 goto rdata_error;
343 break;
344
345 /* Repetitive special types do not exist (yet)
346 *
347 * LCOV_EXCL_START
348 */
349 case wf_special:
350 /* Repetitive special types
351 * must have this function
352 */
353 assert(rdf->rdd_pos->special->wire2list);
354
355 if (rdf->rdd_pos->special->wire2list(
356 repeat_list, rdf->pos))
357 goto rdata_error;
358 /* LCOV_EXCL_STOP */
359
360 default:
361 break;
362 }
363 continue;
364 }
365 if (rdf->rdd_pos == rdf->rdd_repeat + 1) {
366
367 if (repeat_dict) {
368 if (! repeat_list && !(repeat_list =
369 _getdns_list_create_with_mf(mf)))
370 goto rdata_error;
371
372 if (_getdns_list_append_this_dict(
373 repeat_list, repeat_dict))
374 goto rdata_error;
375
376 repeat_dict = NULL;
377 }
378 if (!(repeat_dict =
379 _getdns_dict_create_with_mf(mf)))
380 goto rdata_error;
381 }
382 assert(repeat_dict);
383 switch (val_type) {
384 case wf_int:
385 if (getdns_dict_set_int(repeat_dict,
386 rdf->rdd_pos->name, int_val))
387 goto rdata_error;
388 break;
389 case wf_bindata:
390 if (_getdns_dict_set_const_bindata(repeat_dict,
391 rdf->rdd_pos->name, bin_size, bin_data))
392 goto rdata_error;
393 break;
394 case wf_special:
395 if (rdf->rdd_pos->special->wire2dict(
396 repeat_dict, rdf->pos))
397 goto rdata_error;
398 default:
399 break;
400 }
401 }
402 if (repeat_dict) {
403 if (!repeat_list && !(repeat_list =
404 _getdns_list_create_with_mf(mf)))
405 goto rdata_error;
406 if (_getdns_list_append_this_dict(repeat_list, repeat_dict))
407 goto rdata_error;
408 repeat_dict = NULL;
409 }
410 if (repeat_list) {
411 if (_getdns_dict_set_this_list(rdata_dict,
412 rdf_storage.rdd_repeat->name, repeat_list))
413 goto rdata_error;
414 repeat_list = NULL;
415 }
416 if (_getdns_dict_set_this_dict(rr_dict, "rdata", rdata_dict))
417 goto rdata_error;
418
419 if (canonicalize && rdata_sz) {
420 if (!(data = GETDNS_XMALLOC(
421 *mf, uint8_t, owner_len + 10 + rdata_sz)))
422 return rr_dict;
423
424 gldns_buffer_init_frm_data(&gbuf, data, owner_len+10+rdata_sz);
425 if (_getdns_rr_dict2wire(rr_dict, &gbuf) ||
426 gldns_buffer_position(&gbuf) != owner_len + 10 + rdata_sz ||
427 !(bindata = GETDNS_MALLOC(*mf, struct getdns_bindata))) {
428 GETDNS_FREE(*mf, data);
429 return rr_dict;
430 }
431 bindata->size = rdata_sz;
432 bindata->data = memmove(data, data + owner_len + 10, rdata_sz);
433 (void) _getdns_dict_set_this_bindata(rr_dict,
434 "/rdata/rdata_raw", bindata);
435 }
436 return rr_dict;
437
438 rdata_error:
439 getdns_list_destroy(repeat_list);
440 getdns_dict_destroy(repeat_dict);
441 getdns_dict_destroy(rdata_dict);
442 error:
443 getdns_dict_destroy(rr_dict);
444 return NULL;
445 }
446
447 getdns_dict *
_getdns_rr_iter2rr_dict(struct mem_funcs * mf,_getdns_rr_iter * i)448 _getdns_rr_iter2rr_dict(struct mem_funcs *mf, _getdns_rr_iter *i)
449 {
450 return _getdns_rr_iter2rr_dict_canonical(mf, i, NULL);
451 }
452
453
454 static inline getdns_dict *
set_dict(getdns_dict ** var,getdns_dict * value)455 set_dict(getdns_dict **var, getdns_dict *value)
456 {
457 if (*var)
458 getdns_dict_destroy(*var);
459 return *var = value;
460 }
461
has_all_numeric_label(const uint8_t * dname)462 static inline int has_all_numeric_label(const uint8_t *dname)
463 {
464 size_t i;
465
466 while (*dname && !(*dname & 0xc0)) {
467 for (i = 1; i <= *dname; i++) {
468 if (!isdigit(dname[i]))
469 break;
470 }
471 if (i > *dname)
472 return 1;
473 dname += *dname + 1;
474 }
475 return 0;
476 }
477
478 typedef struct _srv_rr {
479 _getdns_rr_iter i;
480 unsigned running_sum;
481 } _srv_rr;
482
483 typedef struct _srvs {
484 size_t capacity;
485 size_t count;
486 _srv_rr *rrs;
487 } _srvs;
488
_grow_srvs(struct mem_funcs * mf,_srvs * srvs)489 static int _grow_srvs(struct mem_funcs *mf, _srvs *srvs)
490 {
491 _srv_rr *new_rrs;
492
493 if (!(new_rrs = GETDNS_XREALLOC(
494 *mf, srvs->rrs, _srv_rr, srvs->capacity * 2)))
495 return 0; /* Memory error */
496
497 srvs->capacity *= 2;
498 srvs->rrs = new_rrs;
499 return 1; /* Success */
500 }
501
502 #define SET_WIRE_INT(X,Y) if (getdns_dict_set_int(header, #X , (int) \
503 GLDNS_ ## Y ## _WIRE(req->response))) goto error
504 #define SET_WIRE_BIT(X,Y) if (getdns_dict_set_int(header, #X , \
505 GLDNS_ ## Y ## _WIRE(req->response) ? 1 : 0)) goto error
506 #define SET_WIRE_CNT(X,Y) if (getdns_dict_set_int(header, #X , (int) \
507 GLDNS_ ## Y (req->response))) goto error
508
509 static getdns_dict *
_getdns_create_reply_dict(getdns_context * context,getdns_network_req * req,getdns_list * just_addrs,int * rrsigs_in_answer,_srvs * srvs)510 _getdns_create_reply_dict(getdns_context *context, getdns_network_req *req,
511 getdns_list *just_addrs, int *rrsigs_in_answer, _srvs *srvs)
512 {
513 /* turn a packet into this glorious structure
514 *
515 * { # This is the first reply
516 * "header": { "id": 23456, "qr": 1, "opcode": 0, ... },
517 * "question": { "qname": <bindata for "www.example.com">, "qtype": 1, "qclass": 1 },
518 * "answer":
519 * [
520 * {
521 * "name": <bindata for "www.example.com">,
522 * "type": 1,
523 * "class": 1,
524 * "ttl": 33000,
525 * "rdata":
526 * {
527 * "ipv4_address": <bindata of 0x0a0b0c01>
528 * "rdata_raw": <bindata of 0x0a0b0c01>
529 * }
530 * }
531 * ],
532 * "authority":
533 * [
534 * {
535 * "name": <bindata for "ns1.example.com">,
536 * "type": 1,
537 * "class": 1,
538 * "ttl": 600,
539 * "rdata":
540 * {
541 * "ipv4_address": <bindata of 0x65439876>
542 * "rdata_raw": <bindata of 0x65439876>
543 * }
544 * }
545 * ]
546 * "additional": [],
547 * "canonical_name": <bindata for "www.example.com">,
548 * "answer_type": GETDNS_NAMETYPE_DNS
549 * }
550 *
551 */
552 getdns_return_t r = GETDNS_RETURN_GOOD;
553 getdns_dict *result = getdns_dict_create_with_context(context);
554 getdns_dict *question = NULL;
555 getdns_list *sections[16] = { NULL, NULL
556 , getdns_list_create_with_context(context)
557 , NULL
558 , getdns_list_create_with_context(context)
559 , NULL, NULL, NULL
560 , getdns_list_create_with_context(context)
561 , NULL, NULL, NULL, NULL, NULL, NULL, NULL
562 };
563 getdns_dict *rr_dict = NULL;
564 _getdns_rr_iter rr_iter_storage, *rr_iter;
565 _getdns_rdf_iter rdf_iter_storage, *rdf_iter;
566 size_t bin_size;
567 const uint8_t *bin_data;
568 _getdns_section section;
569 uint8_t owner_name_space[256], query_name_space[256];
570 const uint8_t *owner_name, *query_name;
571 size_t owner_name_len = sizeof(owner_name_space),
572 query_name_len = sizeof(query_name_space);
573 int all_numeric_label;
574 uint16_t rr_type;
575 getdns_dict *header = NULL;
576 getdns_list *bad_dns = NULL;
577 _getdns_rrset_spc answer_spc;
578 _getdns_rrset *answer;
579
580 if (!result)
581 goto error;
582
583 if (!(header = getdns_dict_create_with_context(context)))
584 goto error;
585
586 SET_WIRE_INT(id, ID);
587 SET_WIRE_BIT(qr, QR);
588 SET_WIRE_BIT(aa, AA);
589 SET_WIRE_BIT(tc, TC);
590 SET_WIRE_BIT(rd, RD);
591 SET_WIRE_BIT(cd, CD);
592 SET_WIRE_BIT(ra, RA);
593 SET_WIRE_BIT(ad, AD);
594 SET_WIRE_INT(opcode, OPCODE);
595 SET_WIRE_INT(rcode, RCODE);
596 SET_WIRE_BIT(z, Z);
597
598 SET_WIRE_CNT(qdcount, QDCOUNT);
599 SET_WIRE_CNT(ancount, ANCOUNT);
600 SET_WIRE_CNT(nscount, NSCOUNT);
601 SET_WIRE_CNT(arcount, ARCOUNT);
602
603 /* header */
604 if ((r = _getdns_dict_set_this_dict(result, "header", header)))
605 goto error;
606 header = NULL;
607
608 if (req->query &&
609 (rr_iter = _getdns_rr_iter_init(&rr_iter_storage, req->query
610 , req->response - req->query)))
611
612 query_name = _getdns_owner_if_or_as_decompressed(
613 rr_iter, query_name_space, &query_name_len);
614 else
615 query_name = NULL;
616
617 for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage
618 , req->response
619 , req->response_len)
620 ; rr_iter
621 ; rr_iter = _getdns_rr_iter_next(rr_iter)) {
622
623 if (!set_dict(&rr_dict,
624 _getdns_rr_iter2rr_dict(&context->mf, rr_iter)))
625 continue;
626
627 section = _getdns_rr_iter_section(rr_iter);
628 if (section == SECTION_QUESTION) {
629 if (!query_name)
630 query_name
631 = _getdns_owner_if_or_as_decompressed(
632 rr_iter, query_name_space, &query_name_len);
633
634 if (_getdns_dict_set_this_dict(result, "question", rr_dict))
635 goto error;
636 else rr_dict = NULL;
637 continue;
638 }
639 rr_type = gldns_read_uint16(rr_iter->rr_type);
640 if (section > SECTION_QUESTION &&
641 rr_type == GETDNS_RRTYPE_RRSIG && rrsigs_in_answer)
642 *rrsigs_in_answer = 1;
643
644 if (section != SECTION_ANSWER) {
645 if (_getdns_list_append_this_dict(
646 sections[section], rr_dict))
647 goto error;
648 else rr_dict = NULL;
649 continue;
650 }
651 if (req->follow_redirects == GETDNS_REDIRECTS_DO_NOT_FOLLOW) {
652 owner_name_len = sizeof(owner_name_space);
653 owner_name = _getdns_owner_if_or_as_decompressed(
654 rr_iter, owner_name_space, &owner_name_len);
655
656 if (!_getdns_dname_equal(query_name, owner_name))
657 continue;
658 }
659 if (_getdns_list_append_this_dict(
660 sections[SECTION_ANSWER], rr_dict))
661 goto error;
662 else rr_dict = NULL;
663
664 if (srvs->capacity && rr_type == GETDNS_RRTYPE_SRV) {
665 if (srvs->count >= srvs->capacity &&
666 !_grow_srvs(&context->mf, srvs))
667 goto error;
668
669 srvs->rrs[srvs->count++].i = *rr_iter;
670 continue;
671 }
672 if (rr_type != GETDNS_RRTYPE_A && rr_type != GETDNS_RRTYPE_AAAA)
673 continue;
674
675 if (!just_addrs)
676 continue;
677
678 if (!(rdf_iter = _getdns_rdf_iter_init(
679 &rdf_iter_storage, rr_iter)))
680 continue;
681
682 bin_size = rdf_iter->nxt - rdf_iter->pos;
683 bin_data = rdf_iter->pos;
684 if (!set_dict(&rr_dict, getdns_dict_create_with_context(context)) ||
685
686 getdns_dict_util_set_string(rr_dict, "address_type",
687 rr_type == GETDNS_RRTYPE_A ? "IPv4" : "IPv6" ) ||
688
689 _getdns_dict_set_const_bindata(
690 rr_dict, "address_data", bin_size, bin_data) ||
691
692 _getdns_list_append_this_dict(just_addrs, rr_dict)) {
693
694 goto error;
695 }
696 rr_dict = NULL;
697 }
698 if (!_getdns_dict_set_this_list(result, "answer",
699 sections[SECTION_ANSWER]))
700 sections[SECTION_ANSWER] = NULL;
701 else goto error;
702
703 if (!_getdns_dict_set_this_list(result, "authority",
704 sections[SECTION_AUTHORITY]))
705 sections[SECTION_AUTHORITY] = NULL;
706 else goto error;
707
708 if (!_getdns_dict_set_this_list(result, "additional",
709 sections[SECTION_ADDITIONAL]))
710 sections[SECTION_ADDITIONAL] = NULL;
711 else goto error;
712
713 /* other stuff
714 * Note that spec doesn't explicitly mention these.
715 * They are only showcased in the response dict example */
716 if (getdns_dict_set_int(result, "answer_type", GETDNS_NAMETYPE_DNS))
717 goto error;
718
719 answer = _getdns_rrset_answer(&answer_spc, req->response
720 , req->response_len);
721
722 if (answer_spc.rrset.name &&
723 _getdns_dict_set_const_bindata(result, "canonical_name"
724 , answer_spc.name_len
725 , answer_spc.rrset.name))
726 goto error;
727
728 if (!req->owner->add_warning_for_bad_dns)
729 goto success;
730
731 if (!(bad_dns = getdns_list_create_with_context(context)))
732 goto error;
733
734 if ( !answer
735 && req->request_type != GETDNS_RRTYPE_CNAME
736 && query_name
737 && answer_spc.rrset.name
738 && !_getdns_dname_equal(query_name, answer_spc.rrset.name)
739 && _getdns_list_append_int(bad_dns
740 , GETDNS_BAD_DNS_CNAME_RETURNED_FOR_OTHER_TYPE))
741 goto error;
742
743 all_numeric_label = 0;
744 for ( rr_iter = _getdns_rr_iter_init(&rr_iter_storage
745 , req->response
746 , req->response_len)
747 ; rr_iter && !all_numeric_label
748 ; rr_iter = _getdns_rr_iter_next(rr_iter)) {
749
750 owner_name = _getdns_owner_if_or_as_decompressed(
751 rr_iter, owner_name_space, &owner_name_len);
752
753 if (has_all_numeric_label(owner_name)) {
754 all_numeric_label = 1;
755 break;
756 }
757 if (_getdns_rr_iter_section(rr_iter) ==
758 SECTION_QUESTION)
759 continue;
760
761 for ( rdf_iter = _getdns_rdf_iter_init(&rdf_iter_storage, rr_iter)
762 ; rdf_iter; rdf_iter = _getdns_rdf_iter_next(rdf_iter)) {
763
764 if (!(rdf_iter->rdd_pos->type & GETDNS_RDF_DNAME))
765 continue;
766
767 owner_name = _getdns_rdf_if_or_as_decompressed(
768 rdf_iter, owner_name_space, &owner_name_len);
769
770 if (has_all_numeric_label(owner_name)) {
771 all_numeric_label = 1;
772 break;
773 }
774 }
775 }
776 if (all_numeric_label &&
777 _getdns_list_append_int(bad_dns, GETDNS_BAD_DNS_ALL_NUMERIC_LABEL))
778 goto error;
779
780 if (_getdns_dict_set_this_list(result, "bad_dns", bad_dns))
781 goto error;
782 else bad_dns = NULL;
783
784 goto success;
785 error:
786 getdns_dict_destroy(result);
787 result = NULL;
788 success:
789 getdns_dict_destroy(header);
790 getdns_dict_destroy(rr_dict);
791 getdns_list_destroy(sections[SECTION_ADDITIONAL]);
792 getdns_list_destroy(sections[SECTION_AUTHORITY]);
793 getdns_list_destroy(sections[SECTION_ANSWER]);
794 getdns_dict_destroy(question);
795 getdns_list_destroy(bad_dns);
796 return result;
797 }
798
799 static getdns_dict *
_getdns_create_call_reporting_dict(getdns_context * context,getdns_network_req * netreq)800 _getdns_create_call_reporting_dict(
801 getdns_context *context, getdns_network_req *netreq)
802 {
803 getdns_bindata qname;
804 getdns_dict *netreq_debug;
805 getdns_dict *address_debug = NULL;
806
807 assert(netreq);
808
809 /* It is the responsibility of the caller to free this */
810 if (!(netreq_debug = getdns_dict_create_with_context(context)))
811 return NULL;
812
813 qname.data = netreq->owner->name;
814 qname.size = netreq->owner->name_len;
815
816 if (getdns_dict_set_bindata(netreq_debug, "query_name", &qname) ||
817 getdns_dict_set_int( netreq_debug, "query_type"
818 , netreq->request_type ) ||
819
820 /* Safe, because uint32_t facilitates RRT's of almost 50 days*/
821 getdns_dict_set_int(netreq_debug, "run_time/ms",
822 (uint32_t)(( netreq->debug_end_time
823 - netreq->debug_start_time)/1000))) {
824
825 getdns_dict_destroy(netreq_debug);
826 return NULL;
827
828 } else if (!netreq->upstream) {
829 if (getdns_dict_set_int( netreq_debug, "resolution_type", GETDNS_RESOLUTION_RECURSING)) {
830 getdns_dict_destroy(netreq_debug);
831 return NULL;
832 }
833 /* Nothing more for full recursion */
834 return netreq_debug;
835 }
836
837 if (getdns_dict_set_int( netreq_debug, "resolution_type", GETDNS_RESOLUTION_STUB)) {
838 getdns_dict_destroy(netreq_debug);
839 return NULL;
840 }
841 /* Stub resolver debug data */
842 _getdns_sockaddr_to_dict(
843 context, &netreq->upstream->addr, &address_debug);
844
845 if (_getdns_dict_set_this_dict(netreq_debug,"query_to",address_debug)){
846 getdns_dict_destroy(address_debug);
847 return NULL;
848 }
849 getdns_transport_list_t transport = netreq->upstream->transport;
850 /* Same upstream is used for UDP and TCP, so netreq keeps track of what
851 was actually used for the last successful query.*/
852 if (transport == GETDNS_TRANSPORT_TCP && netreq->debug_udp == 1) {
853 transport = GETDNS_TRANSPORT_UDP;
854 if (getdns_dict_set_int( netreq_debug, "udp_responses_for_this_upstream",
855 netreq->upstream->udp_responses)) {
856 getdns_dict_destroy(netreq_debug);
857 return NULL;
858 }
859 if (getdns_dict_set_int( netreq_debug, "udp_timeouts_for_this_upstream",
860 netreq->upstream->udp_timeouts)) {
861 getdns_dict_destroy(netreq_debug);
862 return NULL;
863 }
864 }
865 if (getdns_dict_set_int( netreq_debug, "transport", transport)) {
866 getdns_dict_destroy(netreq_debug);
867 return NULL;
868 }
869 if (transport != GETDNS_TRANSPORT_UDP) {
870 /* Report the idle timeout actually used on the connection. Must trim,
871 maximum used in practice is 6553500ms, but this is stored in a uint64_t.*/
872 if (netreq->upstream->keepalive_timeout > UINT32_MAX) {
873 if (getdns_dict_set_int( netreq_debug, "idle timeout in ms (overflow)", UINT32_MAX)) {
874 getdns_dict_destroy(netreq_debug);
875 return NULL;
876 }
877 } else{
878 uint32_t idle_timeout = (uint32_t) netreq->upstream->keepalive_timeout;
879 if (getdns_dict_set_int( netreq_debug, "idle timeout in ms", idle_timeout)) {
880 getdns_dict_destroy(netreq_debug);
881 return NULL;
882 }
883 }
884 if (getdns_dict_set_int( netreq_debug, "server_keepalive_received", netreq->upstream->server_keepalive_received)) {
885 getdns_dict_destroy(netreq_debug);
886 return NULL;
887 }
888 /* The running totals are only updated when a connection is closed.
889 Since it is open as we have just used it, calcualte the value on the fly */
890 if (getdns_dict_set_int( netreq_debug, "responses_on_this_connection",
891 netreq->upstream->responses_received)) {
892 getdns_dict_destroy(netreq_debug);
893 return NULL;
894 }
895 if (getdns_dict_set_int( netreq_debug, "timeouts_on_this_connection",
896 netreq->upstream->responses_timeouts)) {
897 getdns_dict_destroy(netreq_debug);
898 return NULL;
899 }
900 if (getdns_dict_set_int( netreq_debug, "responses_for_this_upstream",
901 netreq->upstream->responses_received +
902 netreq->upstream->total_responses)) {
903 getdns_dict_destroy(netreq_debug);
904 return NULL;
905 }
906 if (getdns_dict_set_int( netreq_debug, "timeouts_for_this_upstream",
907 netreq->upstream->responses_timeouts +
908 netreq->upstream->total_timeouts)) {
909 getdns_dict_destroy(netreq_debug);
910 return NULL;
911 }
912 }
913
914 if (netreq->upstream->transport != GETDNS_TRANSPORT_TLS)
915 return netreq_debug;
916
917 /* Only include the auth status if TLS was used */
918 if (getdns_dict_util_set_string(netreq_debug, "tls_auth_status",
919 _getdns_auth_str(netreq->debug_tls_auth_status))){
920
921 getdns_dict_destroy(netreq_debug);
922 return NULL;
923 }
924 if (getdns_dict_util_set_string(netreq_debug, "tls_version",
925 netreq->debug_tls_version)){
926
927 getdns_dict_destroy(netreq_debug);
928 return NULL;
929 }
930 if (getdns_dict_set_bindata(netreq_debug, "tls_peer_cert",
931 &netreq->debug_tls_peer_cert)) {
932
933 getdns_dict_destroy(netreq_debug);
934 return NULL;
935 }
936 netreq->debug_tls_peer_cert.size = 0;
937 GETDNS_FREE(context->my_mf, netreq->debug_tls_peer_cert.data);
938 netreq->debug_tls_peer_cert.data = NULL;
939 return netreq_debug;
940 }
941
_srv_prio(_getdns_rr_iter * x)942 static inline int _srv_prio(_getdns_rr_iter *x)
943 { return x->nxt < x->rr_type+12
944 ? 65536 : (int)gldns_read_uint16(x->rr_type+10); }
945
_srv_weight(_getdns_rr_iter * x)946 static inline int _srv_weight(_getdns_rr_iter *x)
947 { return x->nxt < x->rr_type+14 ? 0 : (int)gldns_read_uint16(x->rr_type+12); }
948
949
_srv_cmp(const void * a,const void * b)950 static int _srv_cmp(const void *a, const void *b)
951 {
952 return _srv_prio((_getdns_rr_iter *)a)
953 - _srv_prio((_getdns_rr_iter *)b);
954 }
955
_rfc2782_sort(_srv_rr * start,_srv_rr * end)956 static void _rfc2782_sort(_srv_rr *start, _srv_rr *end)
957 {
958 uint32_t running_sum, n;
959 _srv_rr *i, *j, swap;
960
961 /* First move all SRVs with weight 0 to the beginning of the list */
962
963 for (i = start; i < end && _srv_weight(&i->i) == 0; i++)
964 ; /* pass */
965
966 for (j = i + 1; j < end; j++) {
967 if (_srv_weight(&j->i) == 0) {
968 swap = *i;
969 *i = *j;
970 *j = swap;
971 i++;
972 }
973 }
974 /* Now all SRVs are at the beginning, calculate running_sum */
975 running_sum = 0;
976 for (i = start; i < end; i++) {
977 running_sum += _srv_weight(&i->i);
978 i->running_sum = running_sum;
979 }
980 n = arc4random_uniform(running_sum);
981 for (i = start; i < end; i++) {
982 if (i->running_sum >= n)
983 break;
984 }
985 if (i > start && i < end) {
986 swap = *start;
987 *start = *i;
988 *i = swap;
989 _rfc2782_sort(start + 1, end);
990 }
991 }
992
993 static getdns_list *
_create_srv_addrs(getdns_context * context,_srvs * srvs)994 _create_srv_addrs(getdns_context *context, _srvs *srvs)
995 {
996 getdns_list *srv_addrs;
997 size_t i, j;
998
999 qsort(srvs->rrs, srvs->count, sizeof(_srv_rr), _srv_cmp);
1000 /* The SRVs are now sorted by priority (lowest first). Now determine
1001 * server selection order for the SRVs with the same priority with
1002 * the algorithm described in RFC2782:
1003 *
1004 * To select a target to be contacted next, arrange all SRV RRs
1005 * (that have not been ordered yet) in any order, except that all
1006 * those with weight 0 are placed at the beginning of the list.
1007 *
1008 * Compute the sum of the weights of those RRs, and with each RR
1009 * associate the running sum in the selected order. Then choose a
1010 * uniform random number between 0 and the sum computed
1011 * (inclusive), and select the RR whose running sum value is the
1012 * first in the selected order which is greater than or equal to
1013 * the random number selected. The target host specified in the
1014 * selected SRV RR is the next one to be contacted by the client.
1015 * Remove this SRV RR from the set of the unordered SRV RRs and
1016 * apply the described algorithm to the unordered SRV RRs to select
1017 * the next target host. Continue the ordering process until there
1018 * are no unordered SRV RRs. This process is repeated for each
1019 * Priority.
1020 */
1021 for (i = 0; i < srvs->count; i = j) {
1022 /* Determine range of SRVs with same priority */
1023 for ( j = i + 1
1024 ; j < srvs->count && _srv_prio(&srvs->rrs[i].i)
1025 == _srv_prio(&srvs->rrs[j].i)
1026 ; j++)
1027 ; /* pass */
1028
1029 if (j == i + 1)
1030 continue;
1031
1032 /* SRVs with same prio range from i till j (exclusive). */
1033 _rfc2782_sort(srvs->rrs + i, srvs->rrs + j);
1034 }
1035 if (!(srv_addrs = getdns_list_create_with_context(context)))
1036 return NULL;
1037
1038 for (i = 0; i < srvs->count; i++) {
1039 _getdns_rr_iter *rr = &srvs->rrs[i].i;
1040 getdns_dict *d;
1041 _getdns_rdf_iter rdf_storage, *rdf;
1042
1043 const uint8_t *dname;
1044 uint8_t dname_spc[256];
1045 size_t dname_sz = sizeof(dname_spc);
1046
1047 _getdns_rrset a;
1048 _getdns_rrtype_iter a_rr_spc, *a_rr;
1049 int addresses_found = 0;
1050
1051 if ( !(d = getdns_dict_create_with_context(context))
1052 || !(rdf = _getdns_rdf_iter_init_at(&rdf_storage, rr, 2))
1053 || !(rdf->rdd_pos->type & GETDNS_RDF_INTEGER)
1054 || (rdf->rdd_pos->type & GETDNS_RDF_FIXEDSZ) != 2
1055 || getdns_dict_set_int(d, "port", (uint32_t)
1056 gldns_read_uint16(rdf->pos))
1057
1058 || !(rdf = _getdns_rdf_iter_init_at(&rdf_storage, rr, 3))
1059 || !(rdf->rdd_pos->type & GETDNS_RDF_DNAME)
1060 || !(dname = _getdns_rdf_if_or_as_decompressed(
1061 rdf, dname_spc, &dname_sz))
1062 || _getdns_dict_set_const_bindata(
1063 d, "domain_name", dname_sz, dname)) {
1064
1065 /* error */
1066 getdns_dict_destroy(d);
1067 continue;
1068 }
1069
1070 a.name = dname;
1071 a.rr_class = rr_iter_class(rr);
1072 a.rr_type = GETDNS_RRTYPE_AAAA;
1073 a.pkt = rr->pkt;
1074 a.pkt_len = rr->pkt_end - rr->pkt;
1075 a.sections = SECTION_ADDITIONAL;
1076
1077 for ( a_rr = _getdns_rrtype_iter_init(&a_rr_spc, &a)
1078 ; a_rr ; a_rr = _getdns_rrtype_iter_next(a_rr)) {
1079
1080 if ( a_rr->rr_i.nxt - (a_rr->rr_i.rr_type + 10) == 16
1081 && !getdns_dict_util_set_string(
1082 d, "address_type", "IPv6")
1083 && !_getdns_dict_set_const_bindata(
1084 d, "address_data", 16,
1085 a_rr->rr_i.rr_type + 10)
1086 && !_getdns_list_append_dict(srv_addrs, d))
1087 addresses_found++;
1088 }
1089 a.rr_type = GETDNS_RRTYPE_A;
1090
1091 for ( a_rr = _getdns_rrtype_iter_init(&a_rr_spc, &a)
1092 ; a_rr ; a_rr = _getdns_rrtype_iter_next(a_rr)) {
1093
1094 if ( a_rr->rr_i.nxt - (a_rr->rr_i.rr_type + 10) ==4
1095 && !getdns_dict_util_set_string(
1096 d, "address_type", "IPv4")
1097 && !_getdns_dict_set_const_bindata(
1098 d, "address_data", 4,
1099 a_rr->rr_i.rr_type + 10)
1100 && !_getdns_list_append_dict(srv_addrs, d))
1101 addresses_found++;
1102 }
1103 if ( addresses_found
1104 || _getdns_list_append_this_dict(srv_addrs, d))
1105 getdns_dict_destroy(d);
1106 }
1107 return srv_addrs;
1108 }
1109
1110 getdns_dict *
_getdns_create_getdns_response(getdns_dns_req * completed_request)1111 _getdns_create_getdns_response(getdns_dns_req *completed_request)
1112 {
1113 getdns_dict *result;
1114 getdns_list *just_addrs = NULL;
1115 getdns_list *srv_addrs = NULL;
1116 getdns_list *replies_full;
1117 getdns_list *replies_tree;
1118 getdns_list *call_reporting = NULL;
1119 getdns_network_req *netreq, **netreq_p;
1120 int rrsigs_in_answer = 0;
1121 getdns_dict *reply;
1122 getdns_bindata *canonical_name = NULL;
1123 int nreplies = 0, nanswers = 0;
1124 int nsecure = 0, ninsecure = 0, nindeterminate = 0, nbogus = 0;
1125 getdns_dict *netreq_debug;
1126 _srvs srvs = { 0, 0, NULL };
1127 _getdns_rrset_spc answer_spc;
1128
1129 /* info (bools) about dns_req */
1130 int dnssec_return_status;
1131 getdns_context *context;
1132
1133 assert(completed_request);
1134
1135 context = completed_request->context;
1136 if (!(result = getdns_dict_create_with_context(context)))
1137 return NULL;
1138
1139 dnssec_return_status = completed_request->dnssec ||
1140 completed_request->dnssec_return_status ||
1141 completed_request->dnssec_return_only_secure ||
1142 completed_request->dnssec_return_all_statuses
1143 #ifdef DNSSEC_ROADBLOCK_AVOIDANCE
1144 || completed_request->dnssec_roadblock_avoidance
1145 #endif
1146 ;
1147
1148 if (completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_A ||
1149 completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_AAAA)
1150 just_addrs = getdns_list_create_with_context(
1151 completed_request->context);
1152
1153 else if (
1154 completed_request->netreqs[0]->request_type == GETDNS_RRTYPE_SRV) {
1155
1156 srvs.capacity = 100;
1157 if (!(srvs.rrs = GETDNS_XMALLOC(
1158 context->mf, _srv_rr, srvs.capacity))) {
1159 srvs.capacity = 0;
1160 goto error_free_result;
1161 }
1162 }
1163 if (getdns_dict_set_int(result, GETDNS_STR_KEY_ANSWER_TYPE,
1164 GETDNS_NAMETYPE_DNS))
1165 goto error_free_result;
1166
1167 if (!(replies_full = getdns_list_create_with_context(context)))
1168 goto error_free_result;
1169
1170 if (!(replies_tree = getdns_list_create_with_context(context)))
1171 goto error_free_replies_full;
1172
1173 if (completed_request->return_call_reporting &&
1174 !(call_reporting = getdns_list_create_with_context(context)))
1175 goto error_free_replies_full;
1176
1177 for ( netreq_p = completed_request->netreqs
1178 ; (netreq = *netreq_p) ; netreq_p++) {
1179
1180 if (call_reporting && ( netreq->response_len
1181 || netreq->state == NET_REQ_TIMED_OUT)) {
1182 if (!(netreq_debug =
1183 _getdns_create_call_reporting_dict(context,netreq)))
1184 goto error;
1185
1186 if (_getdns_list_append_this_dict(
1187 call_reporting, netreq_debug))
1188 goto error;
1189
1190 netreq_debug = NULL;
1191 }
1192 if (! netreq->response_len)
1193 continue;
1194
1195 if (netreq->tsig_status == GETDNS_DNSSEC_INSECURE)
1196 _getdns_network_validate_tsig(netreq);
1197
1198 nreplies++;
1199 switch (netreq->dnssec_status) {
1200 case GETDNS_DNSSEC_SECURE : nsecure++;
1201 break;
1202 case GETDNS_DNSSEC_INSECURE : ninsecure++;
1203 break;
1204 case GETDNS_DNSSEC_INDETERMINATE: nindeterminate++;
1205 ninsecure++;
1206 break;
1207 case GETDNS_DNSSEC_BOGUS : if (dnssec_return_status)
1208 nbogus++;
1209 break;
1210 }
1211 if (! completed_request->dnssec_return_all_statuses &&
1212 ! completed_request->dnssec_return_validation_chain) {
1213 if (dnssec_return_status &&
1214 netreq->dnssec_status == GETDNS_DNSSEC_BOGUS)
1215 continue;
1216 else if (completed_request->dnssec_return_only_secure
1217 && netreq->dnssec_status != GETDNS_DNSSEC_SECURE)
1218 continue;
1219 else if (completed_request->dnssec &&
1220 netreq->dnssec_status == GETDNS_DNSSEC_INDETERMINATE)
1221 continue;
1222 else if (netreq->tsig_status == GETDNS_DNSSEC_BOGUS)
1223 continue;
1224 }
1225 if (!(reply = _getdns_create_reply_dict(context,
1226 netreq, just_addrs, &rrsigs_in_answer, &srvs)))
1227 goto error;
1228
1229 if (!canonical_name) {
1230 if (!getdns_dict_get_bindata(
1231 reply, "canonical_name", &canonical_name) &&
1232 getdns_dict_set_bindata(
1233 result, "canonical_name", canonical_name))
1234 goto error;
1235 }
1236 /* TODO: Check instead if canonical_name for request_type
1237 * is in the answer section.
1238 */
1239 if (_getdns_rrset_answer(&answer_spc, netreq->response
1240 , netreq->response_len))
1241 nanswers++;
1242
1243 if (dnssec_return_status ||
1244 completed_request->dnssec_return_validation_chain) {
1245
1246 if (getdns_dict_set_int(reply, "dnssec_status",
1247 netreq->dnssec_status))
1248 goto error;
1249 }
1250 if (netreq->tsig_status != GETDNS_DNSSEC_INDETERMINATE) {
1251 if (getdns_dict_set_int(reply, "tsig_status",
1252 netreq->tsig_status))
1253 goto error;
1254 }
1255 if (_getdns_list_append_this_dict(replies_tree, reply)) {
1256 getdns_dict_destroy(reply);
1257 goto error;
1258 }
1259 if (_getdns_list_append_const_bindata(replies_full,
1260 netreq->response_len, netreq->response))
1261 goto error;
1262 }
1263 if (_getdns_dict_set_this_list(result, "replies_tree", replies_tree))
1264 goto error;
1265 replies_tree = NULL;
1266
1267 if (!canonical_name &&
1268 _getdns_dict_set_const_bindata(result, "canonical_name",
1269 completed_request->name_len, completed_request->name))
1270 goto error;
1271
1272 if (call_reporting) {
1273 if (_getdns_dict_set_this_list(
1274 result, "call_reporting", call_reporting))
1275 goto error_free_call_reporting;
1276 call_reporting = NULL;
1277 }
1278 if (_getdns_dict_set_this_list(result, "replies_full", replies_full))
1279 goto error_free_replies_full;
1280 replies_full = NULL;
1281
1282 if (just_addrs) {
1283 if (_getdns_dict_set_this_list(
1284 result, GETDNS_STR_KEY_JUST_ADDRS, just_addrs))
1285 goto error_free_result;
1286 just_addrs = NULL;
1287 }
1288 if (srvs.capacity) {
1289 if (!(srv_addrs = _create_srv_addrs(context, &srvs)) ||
1290 _getdns_dict_set_this_list(
1291 result, "srv_addresses", srv_addrs))
1292 goto error_free_result;
1293
1294 GETDNS_FREE(context->mf, srvs.rrs);
1295 }
1296 if (getdns_dict_set_int(result, GETDNS_STR_KEY_STATUS,
1297 completed_request->request_timed_out ||
1298 nreplies == 0 ? GETDNS_RESPSTATUS_ALL_TIMEOUT :
1299 ( completed_request->dnssec
1300 && nsecure == 0 && nindeterminate ) > 0
1301 ? GETDNS_RESPSTATUS_NO_SECURE_ANSWERS :
1302 ( completed_request->dnssec_return_only_secure
1303 && nsecure == 0 && ninsecure ) > 0
1304 ? GETDNS_RESPSTATUS_NO_SECURE_ANSWERS :
1305 ( completed_request->dnssec_return_only_secure
1306 || completed_request->dnssec ) && nsecure == 0 && nbogus > 0
1307 ? GETDNS_RESPSTATUS_ALL_BOGUS_ANSWERS :
1308 nanswers == 0 ? GETDNS_RESPSTATUS_NO_NAME
1309 : GETDNS_RESPSTATUS_GOOD))
1310 goto error_free_result;
1311
1312 return result;
1313 error:
1314 /* cleanup */
1315 getdns_list_destroy(replies_tree);
1316 error_free_call_reporting:
1317 getdns_list_destroy(call_reporting);
1318 error_free_replies_full:
1319 getdns_list_destroy(replies_full);
1320 error_free_result:
1321 if (srvs.capacity)
1322 GETDNS_FREE(context->mf, srvs.rrs);
1323 getdns_list_destroy(srv_addrs);
1324 getdns_list_destroy(just_addrs);
1325 getdns_dict_destroy(result);
1326 return NULL;
1327 }
1328
1329
1330 #ifdef HAVE_LIBUNBOUND
1331 getdns_return_t
getdns_apply_network_result(getdns_network_req * netreq,int rcode,void * pkt,int pkt_len,int sec,char * why_bogus)1332 getdns_apply_network_result(getdns_network_req* netreq,
1333 int rcode, void *pkt, int pkt_len, int sec, char* why_bogus)
1334 {
1335 (void)why_bogus;
1336
1337 netreq->dnssec_status = sec == 0 ? GETDNS_DNSSEC_INSECURE
1338 : sec == 2 ? GETDNS_DNSSEC_SECURE
1339 : GETDNS_DNSSEC_BOGUS;
1340
1341 if (pkt) {
1342 if (netreq->max_udp_payload_size < pkt_len)
1343 netreq->response = GETDNS_XMALLOC(
1344 netreq->owner->context->mf,
1345 uint8_t, pkt_len
1346 );
1347 (void) memcpy(netreq->response, pkt,
1348 (netreq->response_len = pkt_len));
1349 return GETDNS_RETURN_GOOD;
1350 }
1351
1352 if (rcode == GETDNS_RCODE_SERVFAIL) {
1353 /* Likely to be caused by timeout from a synchronous
1354 * lookup. Don't forge a packet.
1355 */
1356 return GETDNS_RETURN_GOOD;
1357 }
1358 /* Likely to be because libunbound refused the request
1359 * so ub_res->answer_packet=NULL, ub_res->answer_len=0
1360 * So we need to create an answer packet.
1361 */
1362 gldns_write_uint16(netreq->response , 0); /* query_id */
1363 gldns_write_uint16(netreq->response + 2, 0); /* reset all flags */
1364 gldns_write_uint16(netreq->response + GLDNS_QDCOUNT_OFF, 1);
1365 gldns_write_uint16(netreq->response + GLDNS_ANCOUNT_OFF, 0);
1366 gldns_write_uint16(netreq->response + GLDNS_NSCOUNT_OFF, 0);
1367 gldns_write_uint16(netreq->response + GLDNS_ARCOUNT_OFF, 0);
1368
1369 GLDNS_OPCODE_SET(netreq->response, 3);
1370 GLDNS_QR_SET(netreq->response);
1371 GLDNS_RD_SET(netreq->response);
1372 GLDNS_RA_SET(netreq->response);
1373 GLDNS_RCODE_SET(netreq->response, rcode);
1374
1375 (void) memcpy( netreq->response + GLDNS_HEADER_SIZE
1376 , netreq->owner->name, netreq->owner->name_len);
1377
1378 gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE
1379 + netreq->owner->name_len
1380 , netreq->request_type);
1381 gldns_write_uint16( netreq->response + GLDNS_HEADER_SIZE
1382 + netreq->owner->name_len + 2
1383 , netreq->owner->request_class);
1384
1385 netreq->response_len = GLDNS_HEADER_SIZE + netreq->owner->name_len + 4;
1386
1387 return GETDNS_RETURN_GOOD;
1388 }
1389 #endif
1390
1391
1392 getdns_return_t
_getdns_validate_dname(const char * dname)1393 _getdns_validate_dname(const char* dname) {
1394 int len;
1395 int label_len;
1396 const char* s;
1397 if (dname == NULL) {
1398 return GETDNS_RETURN_INVALID_PARAMETER;
1399 }
1400 len = strlen(dname);
1401 if (len > GETDNS_MAX_DNAME_LEN * 4 || len == 0) {
1402 return GETDNS_RETURN_BAD_DOMAIN_NAME;
1403 }
1404 if (len == 1 && dname[0] == '.') {
1405 /* root is ok */
1406 return GETDNS_RETURN_GOOD;
1407 }
1408 /* By specification [RFC1035] the total length of a DNS label is
1409 * restricted to 63 octets and must be larger than 0 (except for the
1410 * final root-label). The total length of a domain name (i.e., label
1411 * octets and label length octets) is restricted to 255 octets or less.
1412 * With a fully qualified domain name this includes the last label
1413 * length octet for the root label. In a normalized representation the
1414 * number of labels (including the root) plus the number of octets in
1415 * each label may not be larger than 255.
1416 */
1417 len = 0;
1418 label_len = 0;
1419 for (s = dname; *s; ++s) {
1420 switch (*s) {
1421 case '.':
1422 if (label_len > GETDNS_MAX_LABEL_LEN ||
1423 label_len == 0) {
1424 return GETDNS_RETURN_BAD_DOMAIN_NAME;
1425 }
1426 label_len = 0;
1427 len += 1;
1428 break;
1429 case '\\':
1430 s += 1;
1431 if (isdigit((unsigned char)s[0])) {
1432 /* octet value */
1433 if (! isdigit((unsigned char)s[1]) && ! isdigit((unsigned char)s[2]))
1434 return GETDNS_RETURN_BAD_DOMAIN_NAME;
1435
1436 if ((s[0] - '0') * 100 +
1437 (s[1] - '0') * 10 + (s[2] - '0') > 255)
1438 return GETDNS_RETURN_BAD_DOMAIN_NAME;
1439
1440 s += 2;
1441 }
1442 /* else literal char (1 octet) */
1443 label_len++;
1444 len += 1;
1445 break;
1446 default:
1447 label_len++;
1448 len += 1;
1449 break;
1450 }
1451 }
1452 if (len > GETDNS_MAX_DNAME_LEN || label_len > GETDNS_MAX_LABEL_LEN) {
1453 return GETDNS_RETURN_BAD_DOMAIN_NAME;
1454 }
1455 return GETDNS_RETURN_GOOD;
1456 } /* _getdns_validate_dname */
1457
1458
_getdns_reply2wire_buf(gldns_buffer * buf,const getdns_dict * reply)1459 static void _getdns_reply2wire_buf(gldns_buffer *buf, const getdns_dict *reply)
1460 {
1461 getdns_dict *rr_dict, *q_dict, *h_dict;
1462 getdns_list *section;
1463 size_t i, pkt_start;
1464 uint16_t ancount, nscount;
1465 uint32_t qtype, qclass = GETDNS_RRCLASS_IN, rcode = GETDNS_RCODE_NOERROR;
1466 getdns_bindata *qname;
1467
1468
1469 pkt_start = gldns_buffer_position(buf);
1470 /* Empty header */
1471 gldns_buffer_write_u32(buf, 0);
1472 gldns_buffer_write_u32(buf, 0);
1473 gldns_buffer_write_u32(buf, 0);
1474
1475 if ( !getdns_dict_get_dict(reply, "question", &q_dict)
1476 && !getdns_dict_get_int(q_dict, "qtype", &qtype)
1477 && !getdns_dict_get_bindata(q_dict, "qname", &qname)) {
1478
1479 gldns_buffer_write(buf, qname->data, qname->size);
1480 gldns_buffer_write_u16(buf, (uint16_t)qtype);
1481 gldns_buffer_write_u16(buf, (uint16_t)qclass);
1482 gldns_buffer_write_u16_at(
1483 buf, pkt_start + GLDNS_QDCOUNT_OFF, 1);
1484 }
1485
1486 if ( !getdns_dict_get_dict(reply, "header", &h_dict)
1487 && !getdns_dict_get_int(h_dict, "rcode", &rcode)) {
1488
1489 GLDNS_RCODE_SET(gldns_buffer_at(buf, pkt_start), rcode);
1490 }
1491 if (!getdns_dict_get_list(reply, "answer", §ion)) {
1492 for ( i = 0, ancount = 0
1493 ; !getdns_list_get_dict(section, i, &rr_dict)
1494 ; i++ ) {
1495
1496 if (!_getdns_rr_dict2wire(rr_dict, buf))
1497 ancount++;
1498 }
1499 gldns_buffer_write_u16_at(
1500 buf, pkt_start + GLDNS_ANCOUNT_OFF, ancount);
1501 }
1502 if (!getdns_dict_get_list(reply, "authority", §ion)) {
1503 for ( i = 0, nscount = 0
1504 ; !getdns_list_get_dict(section, i, &rr_dict)
1505 ; i++ ) {
1506
1507 if (!_getdns_rr_dict2wire(rr_dict, buf))
1508 nscount++;
1509 }
1510 gldns_buffer_write_u16_at(
1511 buf, pkt_start + GLDNS_NSCOUNT_OFF, nscount);
1512 }
1513 }
1514
_getdns_list2wire_buf(gldns_buffer * buf,const getdns_list * l)1515 static void _getdns_list2wire_buf(gldns_buffer *buf, const getdns_list *l)
1516 {
1517 getdns_dict *rr_dict;
1518 size_t i, pkt_start;
1519 uint16_t ancount;
1520 uint32_t qtype, qclass = GETDNS_RRCLASS_IN;
1521 getdns_bindata *qname;
1522
1523 pkt_start = gldns_buffer_position(buf);
1524 /* Empty header */
1525 gldns_buffer_write_u32(buf, 0);
1526 gldns_buffer_write_u32(buf, 0);
1527 gldns_buffer_write_u32(buf, 0);
1528
1529 for ( i = 0
1530 ; !getdns_list_get_dict(l, i, &rr_dict)
1531 ; i++ ) {
1532
1533 if (getdns_dict_get_int(rr_dict, "qtype", &qtype) ||
1534 getdns_dict_get_bindata(rr_dict, "qname", &qname))
1535 continue;
1536 (void) getdns_dict_get_int(rr_dict, "qclass", &qclass);
1537 gldns_buffer_write(buf, qname->data, qname->size);
1538 gldns_buffer_write_u16(buf, (uint16_t)qtype);
1539 gldns_buffer_write_u16(buf, (uint16_t)qclass);
1540 gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_QDCOUNT_OFF, 1);
1541 break;
1542 }
1543 for ( i = 0, ancount = 0
1544 ; !getdns_list_get_dict(l, i, &rr_dict)
1545 ; i++ ) {
1546
1547 if (!_getdns_rr_dict2wire(rr_dict, buf))
1548 ancount++;
1549 }
1550 gldns_buffer_write_u16_at(buf, pkt_start+GLDNS_ANCOUNT_OFF, ancount);
1551 }
1552
_getdns_list2wire(const getdns_list * l,uint8_t * buf,size_t * buf_len,const struct mem_funcs * mf)1553 uint8_t *_getdns_list2wire(const getdns_list *l,
1554 uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf)
1555 {
1556 gldns_buffer gbuf;
1557 size_t sz;
1558
1559 gldns_buffer_init_vfixed_frm_data(&gbuf, buf, *buf_len);
1560 _getdns_list2wire_buf(&gbuf, l);
1561
1562 if ((sz = gldns_buffer_position(&gbuf)) <= *buf_len) {
1563 *buf_len = sz;
1564 return buf;
1565 }
1566 if (!(buf = GETDNS_XMALLOC(*mf, uint8_t, (*buf_len = sz))))
1567 return NULL;
1568
1569 gldns_buffer_init_frm_data(&gbuf, buf, sz);
1570 _getdns_list2wire_buf(&gbuf, l);
1571 return buf;
1572 }
1573
_getdns_reply2wire(const getdns_dict * r,uint8_t * buf,size_t * buf_len,const struct mem_funcs * mf)1574 uint8_t *_getdns_reply2wire(const getdns_dict *r,
1575 uint8_t *buf, size_t *buf_len, const struct mem_funcs *mf)
1576 {
1577 gldns_buffer gbuf;
1578 size_t sz;
1579
1580 gldns_buffer_init_vfixed_frm_data(&gbuf, buf, *buf_len);
1581 _getdns_reply2wire_buf(&gbuf, r);
1582
1583 if ((sz = gldns_buffer_position(&gbuf)) <= *buf_len) {
1584 *buf_len = sz;
1585 return buf;
1586 }
1587 if (!(buf = GETDNS_XMALLOC(*mf, uint8_t, (*buf_len = sz))))
1588 return NULL;
1589
1590 gldns_buffer_init_frm_data(&gbuf, buf, sz);
1591 _getdns_reply2wire_buf(&gbuf, r);
1592 return buf;
1593 }
1594
_getdns_wire2list(const uint8_t * pkt,size_t pkt_len,getdns_list * l)1595 void _getdns_wire2list(const uint8_t *pkt, size_t pkt_len, getdns_list *l)
1596 {
1597 _getdns_rr_iter rr_spc, *rr;
1598 getdns_dict *rr_dict;
1599
1600 for ( rr = _getdns_rr_iter_init(&rr_spc, pkt, pkt_len)
1601 ; rr ; rr = _getdns_rr_iter_next(rr)) {
1602
1603 if (!(rr_dict = _getdns_rr_iter2rr_dict(&l->mf, rr)))
1604 continue;
1605
1606 if (_getdns_list_append_this_dict(l, rr_dict))
1607 getdns_dict_destroy(rr_dict);
1608 }
1609 }
1610
_getdns_auth_str(getdns_auth_state_t auth)1611 const char * _getdns_auth_str(getdns_auth_state_t auth) {
1612 static const char*
1613 getdns_auth_str_array[] = {
1614 GETDNS_STR_AUTH_NONE,
1615 GETDNS_STR_AUTH_FAILED,
1616 GETDNS_STR_AUTH_OK
1617 };
1618 return getdns_auth_str_array[auth];
1619 }
1620
1621 /* util-internal.c */
1622