1 /*
2 * resolver.c
3 *
4 * resolver implementation
5 *
6 * a Net::DNS like library for C
7 *
8 * (c) NLnet Labs, 2004-2006
9 *
10 * See the file LICENSE for the license
11 */
12
13 #include <ldns/config.h>
14
15 #include <ldns/ldns.h>
16 #include <strings.h>
17
18 /* Access function for reading
19 * and setting the different Resolver
20 * options */
21
22 /* read */
23 uint16_t
ldns_resolver_port(const ldns_resolver * r)24 ldns_resolver_port(const ldns_resolver *r)
25 {
26 return r->_port;
27 }
28
29 ldns_rdf *
ldns_resolver_source(const ldns_resolver * r)30 ldns_resolver_source(const ldns_resolver *r)
31 {
32 return r->_source;
33 }
34
35 uint16_t
ldns_resolver_edns_udp_size(const ldns_resolver * r)36 ldns_resolver_edns_udp_size(const ldns_resolver *r)
37 {
38 return r->_edns_udp_size;
39 }
40
41 uint8_t
ldns_resolver_retry(const ldns_resolver * r)42 ldns_resolver_retry(const ldns_resolver *r)
43 {
44 return r->_retry;
45 }
46
47 uint8_t
ldns_resolver_retrans(const ldns_resolver * r)48 ldns_resolver_retrans(const ldns_resolver *r)
49 {
50 return r->_retrans;
51 }
52
53 bool
ldns_resolver_fallback(const ldns_resolver * r)54 ldns_resolver_fallback(const ldns_resolver *r)
55 {
56 return r->_fallback;
57 }
58
59 uint8_t
ldns_resolver_ip6(const ldns_resolver * r)60 ldns_resolver_ip6(const ldns_resolver *r)
61 {
62 return r->_ip6;
63 }
64
65 bool
ldns_resolver_recursive(const ldns_resolver * r)66 ldns_resolver_recursive(const ldns_resolver *r)
67 {
68 return r->_recursive;
69 }
70
71 bool
ldns_resolver_debug(const ldns_resolver * r)72 ldns_resolver_debug(const ldns_resolver *r)
73 {
74 return r->_debug;
75 }
76
77 bool
ldns_resolver_dnsrch(const ldns_resolver * r)78 ldns_resolver_dnsrch(const ldns_resolver *r)
79 {
80 return r->_dnsrch;
81 }
82
83 bool
ldns_resolver_fail(const ldns_resolver * r)84 ldns_resolver_fail(const ldns_resolver *r)
85 {
86 return r->_fail;
87 }
88
89 bool
ldns_resolver_defnames(const ldns_resolver * r)90 ldns_resolver_defnames(const ldns_resolver *r)
91 {
92 return r->_defnames;
93 }
94
95 ldns_rdf *
ldns_resolver_domain(const ldns_resolver * r)96 ldns_resolver_domain(const ldns_resolver *r)
97 {
98 return r->_domain;
99 }
100
101 ldns_rdf **
ldns_resolver_searchlist(const ldns_resolver * r)102 ldns_resolver_searchlist(const ldns_resolver *r)
103 {
104 return r->_searchlist;
105 }
106
107 ldns_rdf **
ldns_resolver_nameservers(const ldns_resolver * r)108 ldns_resolver_nameservers(const ldns_resolver *r)
109 {
110 return r->_nameservers;
111 }
112
113 size_t
ldns_resolver_nameserver_count(const ldns_resolver * r)114 ldns_resolver_nameserver_count(const ldns_resolver *r)
115 {
116 return r->_nameserver_count;
117 }
118
119 bool
ldns_resolver_dnssec(const ldns_resolver * r)120 ldns_resolver_dnssec(const ldns_resolver *r)
121 {
122 return r->_dnssec;
123 }
124
125 bool
ldns_resolver_dnssec_cd(const ldns_resolver * r)126 ldns_resolver_dnssec_cd(const ldns_resolver *r)
127 {
128 return r->_dnssec_cd;
129 }
130
131 ldns_rr_list *
ldns_resolver_dnssec_anchors(const ldns_resolver * r)132 ldns_resolver_dnssec_anchors(const ldns_resolver *r)
133 {
134 return r->_dnssec_anchors;
135 }
136
137 bool
ldns_resolver_trusted_key(const ldns_resolver * r,ldns_rr_list * keys,ldns_rr_list * trusted_keys)138 ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys)
139 {
140 size_t i;
141 bool result = false;
142
143 ldns_rr_list * trust_anchors;
144 ldns_rr * cur_rr;
145
146 if (!r || !keys) { return false; }
147
148 trust_anchors = ldns_resolver_dnssec_anchors(r);
149
150 if (!trust_anchors) { return false; }
151
152 for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
153
154 cur_rr = ldns_rr_list_rr(keys, i);
155 if (ldns_rr_list_contains_rr(trust_anchors, cur_rr)) {
156 if (trusted_keys) { ldns_rr_list_push_rr(trusted_keys, cur_rr); }
157 result = true;
158 }
159 }
160
161 return result;
162 }
163
164 bool
ldns_resolver_igntc(const ldns_resolver * r)165 ldns_resolver_igntc(const ldns_resolver *r)
166 {
167 return r->_igntc;
168 }
169
170 bool
ldns_resolver_usevc(const ldns_resolver * r)171 ldns_resolver_usevc(const ldns_resolver *r)
172 {
173 return r->_usevc;
174 }
175
176 size_t *
ldns_resolver_rtt(const ldns_resolver * r)177 ldns_resolver_rtt(const ldns_resolver *r)
178 {
179 return r->_rtt;
180 }
181
182 size_t
ldns_resolver_nameserver_rtt(const ldns_resolver * r,size_t pos)183 ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos)
184 {
185 size_t *rtt;
186
187 assert(r != NULL);
188
189 rtt = ldns_resolver_rtt(r);
190
191 if (pos >= ldns_resolver_nameserver_count(r)) {
192 /* error ?*/
193 return 0;
194 } else {
195 return rtt[pos];
196 }
197
198 }
199
200 struct timeval
ldns_resolver_timeout(const ldns_resolver * r)201 ldns_resolver_timeout(const ldns_resolver *r)
202 {
203 return r->_timeout;
204 }
205
206 const char *
ldns_resolver_tsig_keyname(const ldns_resolver * r)207 ldns_resolver_tsig_keyname(const ldns_resolver *r)
208 {
209 return r->_tsig_keyname;
210 }
211
212 const char *
ldns_resolver_tsig_algorithm(const ldns_resolver * r)213 ldns_resolver_tsig_algorithm(const ldns_resolver *r)
214 {
215 return r->_tsig_algorithm;
216 }
217
218 const char *
ldns_resolver_tsig_keydata(const ldns_resolver * r)219 ldns_resolver_tsig_keydata(const ldns_resolver *r)
220 {
221 return r->_tsig_keydata;
222 }
223
224 bool
ldns_resolver_random(const ldns_resolver * r)225 ldns_resolver_random(const ldns_resolver *r)
226 {
227 return r->_random;
228 }
229
230 size_t
ldns_resolver_searchlist_count(const ldns_resolver * r)231 ldns_resolver_searchlist_count(const ldns_resolver *r)
232 {
233 return r->_searchlist_count;
234 }
235
236 /* write */
237 void
ldns_resolver_set_port(ldns_resolver * r,uint16_t p)238 ldns_resolver_set_port(ldns_resolver *r, uint16_t p)
239 {
240 r->_port = p;
241 }
242
243 void
ldns_resolver_set_source(ldns_resolver * r,ldns_rdf * s)244 ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s)
245 {
246 r->_source = s;
247 }
248
249 ldns_rdf *
ldns_resolver_pop_nameserver(ldns_resolver * r)250 ldns_resolver_pop_nameserver(ldns_resolver *r)
251 {
252 ldns_rdf **nameservers;
253 ldns_rdf *pop;
254 size_t ns_count;
255 size_t *rtt;
256
257 assert(r != NULL);
258
259 ns_count = ldns_resolver_nameserver_count(r);
260 nameservers = ldns_resolver_nameservers(r);
261 rtt = ldns_resolver_rtt(r);
262 if (ns_count == 0 || !nameservers) {
263 return NULL;
264 }
265
266 pop = nameservers[ns_count - 1];
267
268 if (ns_count == 1) {
269 LDNS_FREE(nameservers);
270 LDNS_FREE(rtt);
271
272 ldns_resolver_set_nameservers(r, NULL);
273 ldns_resolver_set_rtt(r, NULL);
274 } else {
275 nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *,
276 (ns_count - 1));
277 rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
278
279 ldns_resolver_set_nameservers(r, nameservers);
280 ldns_resolver_set_rtt(r, rtt);
281 }
282 /* decr the count */
283 ldns_resolver_dec_nameserver_count(r);
284 return pop;
285 }
286
287 ldns_status
ldns_resolver_push_nameserver(ldns_resolver * r,const ldns_rdf * n)288 ldns_resolver_push_nameserver(ldns_resolver *r, const ldns_rdf *n)
289 {
290 ldns_rdf **nameservers;
291 size_t ns_count;
292 size_t *rtt;
293
294 if (ldns_rdf_get_type(n) != LDNS_RDF_TYPE_A &&
295 ldns_rdf_get_type(n) != LDNS_RDF_TYPE_AAAA) {
296 return LDNS_STATUS_ERR;
297 }
298
299 ns_count = ldns_resolver_nameserver_count(r);
300 nameservers = ldns_resolver_nameservers(r);
301 rtt = ldns_resolver_rtt(r);
302
303 /* make room for the next one */
304 if (ns_count == 0) {
305 nameservers = LDNS_XMALLOC(ldns_rdf *, 1);
306 } else {
307 nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1));
308 }
309 if(!nameservers)
310 return LDNS_STATUS_MEM_ERR;
311
312 /* set the new value in the resolver */
313 ldns_resolver_set_nameservers(r, nameservers);
314
315 /* don't forget the rtt */
316 if (ns_count == 0) {
317 rtt = LDNS_XMALLOC(size_t, 1);
318 } else {
319 rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1));
320 }
321 if(!rtt)
322 return LDNS_STATUS_MEM_ERR;
323
324 /* slide n in its slot. */
325 /* we clone it here, because then we can free the original
326 * rr's where it stood */
327 nameservers[ns_count] = ldns_rdf_clone(n);
328 rtt[ns_count] = LDNS_RESOLV_RTT_MIN;
329 ldns_resolver_incr_nameserver_count(r);
330 ldns_resolver_set_rtt(r, rtt);
331 return LDNS_STATUS_OK;
332 }
333
334 ldns_status
ldns_resolver_push_nameserver_rr(ldns_resolver * r,const ldns_rr * rr)335 ldns_resolver_push_nameserver_rr(ldns_resolver *r, const ldns_rr *rr)
336 {
337 ldns_rdf *address;
338 if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A &&
339 ldns_rr_get_type(rr) != LDNS_RR_TYPE_AAAA)) {
340 return LDNS_STATUS_ERR;
341 }
342 address = ldns_rr_rdf(rr, 0); /* extract the ip number */
343 if (address) {
344 return ldns_resolver_push_nameserver(r, address);
345 } else {
346 return LDNS_STATUS_ERR;
347 }
348 }
349
350 ldns_status
ldns_resolver_push_nameserver_rr_list(ldns_resolver * r,const ldns_rr_list * rrlist)351 ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, const ldns_rr_list *rrlist)
352 {
353 ldns_rr *rr;
354 ldns_status stat;
355 size_t i;
356
357 stat = LDNS_STATUS_OK;
358 if (rrlist) {
359 for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
360 rr = ldns_rr_list_rr(rrlist, i);
361 if (ldns_resolver_push_nameserver_rr(r, rr) != LDNS_STATUS_OK) {
362 stat = LDNS_STATUS_ERR;
363 break;
364 }
365 }
366 return stat;
367 } else {
368 return LDNS_STATUS_ERR;
369 }
370 }
371
372 void
ldns_resolver_set_edns_udp_size(ldns_resolver * r,uint16_t s)373 ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
374 {
375 r->_edns_udp_size = s;
376 }
377
378 void
ldns_resolver_set_recursive(ldns_resolver * r,bool re)379 ldns_resolver_set_recursive(ldns_resolver *r, bool re)
380 {
381 r->_recursive = re;
382 }
383
384 void
ldns_resolver_set_dnssec(ldns_resolver * r,bool d)385 ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
386 {
387 r->_dnssec = d;
388 }
389
390 void
ldns_resolver_set_dnssec_cd(ldns_resolver * r,bool d)391 ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
392 {
393 r->_dnssec_cd = d;
394 }
395
396 void
ldns_resolver_set_dnssec_anchors(ldns_resolver * r,ldns_rr_list * l)397 ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
398 {
399 r->_dnssec_anchors = l;
400 }
401
402 ldns_status
ldns_resolver_push_dnssec_anchor(ldns_resolver * r,ldns_rr * rr)403 ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
404 {
405 ldns_rr_list * trust_anchors;
406
407 if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY &&
408 ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS)) {
409
410 return LDNS_STATUS_ERR;
411 }
412
413 if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */
414 trust_anchors = ldns_rr_list_new();
415 ldns_resolver_set_dnssec_anchors(r, trust_anchors);
416 }
417
418 return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
419 }
420
421 void
ldns_resolver_set_igntc(ldns_resolver * r,bool i)422 ldns_resolver_set_igntc(ldns_resolver *r, bool i)
423 {
424 r->_igntc = i;
425 }
426
427 void
ldns_resolver_set_usevc(ldns_resolver * r,bool vc)428 ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
429 {
430 r->_usevc = vc;
431 }
432
433 void
ldns_resolver_set_debug(ldns_resolver * r,bool d)434 ldns_resolver_set_debug(ldns_resolver *r, bool d)
435 {
436 r->_debug = d;
437 }
438
439 void
ldns_resolver_set_ip6(ldns_resolver * r,uint8_t ip6)440 ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
441 {
442 r->_ip6 = ip6;
443 }
444
445 void
ldns_resolver_set_fail(ldns_resolver * r,bool f)446 ldns_resolver_set_fail(ldns_resolver *r, bool f)
447 {
448 r->_fail =f;
449 }
450
451 static void
ldns_resolver_set_searchlist_count(ldns_resolver * r,size_t c)452 ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
453 {
454 r->_searchlist_count = c;
455 }
456
457 void
ldns_resolver_set_nameserver_count(ldns_resolver * r,size_t c)458 ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
459 {
460 r->_nameserver_count = c;
461 }
462
463 void
ldns_resolver_set_dnsrch(ldns_resolver * r,bool d)464 ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
465 {
466 r->_dnsrch = d;
467 }
468
469 void
ldns_resolver_set_retry(ldns_resolver * r,uint8_t retry)470 ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
471 {
472 r->_retry = retry;
473 }
474
475 void
ldns_resolver_set_retrans(ldns_resolver * r,uint8_t retrans)476 ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
477 {
478 r->_retrans = retrans;
479 }
480
481 void
ldns_resolver_set_fallback(ldns_resolver * r,bool fallback)482 ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
483 {
484 r->_fallback = fallback;
485 }
486
487 void
ldns_resolver_set_nameservers(ldns_resolver * r,ldns_rdf ** n)488 ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
489 {
490 r->_nameservers = n;
491 }
492
493 void
ldns_resolver_set_defnames(ldns_resolver * r,bool d)494 ldns_resolver_set_defnames(ldns_resolver *r, bool d)
495 {
496 r->_defnames = d;
497 }
498
499 void
ldns_resolver_set_rtt(ldns_resolver * r,size_t * rtt)500 ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
501 {
502 r->_rtt = rtt;
503 }
504
505 void
ldns_resolver_set_nameserver_rtt(ldns_resolver * r,size_t pos,size_t value)506 ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
507 {
508 size_t *rtt;
509
510 assert(r != NULL);
511
512 rtt = ldns_resolver_rtt(r);
513
514 if (pos >= ldns_resolver_nameserver_count(r)) {
515 /* error ?*/
516 } else {
517 rtt[pos] = value;
518 }
519
520 }
521
522 void
ldns_resolver_incr_nameserver_count(ldns_resolver * r)523 ldns_resolver_incr_nameserver_count(ldns_resolver *r)
524 {
525 size_t c;
526
527 c = ldns_resolver_nameserver_count(r);
528 ldns_resolver_set_nameserver_count(r, ++c);
529 }
530
531 void
ldns_resolver_dec_nameserver_count(ldns_resolver * r)532 ldns_resolver_dec_nameserver_count(ldns_resolver *r)
533 {
534 size_t c;
535
536 c = ldns_resolver_nameserver_count(r);
537 if (c == 0) {
538 return;
539 } else {
540 ldns_resolver_set_nameserver_count(r, --c);
541 }
542 }
543
544 void
ldns_resolver_set_domain(ldns_resolver * r,ldns_rdf * d)545 ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
546 {
547 r->_domain = d;
548 }
549
550 void
ldns_resolver_set_timeout(ldns_resolver * r,struct timeval timeout)551 ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout)
552 {
553 r->_timeout.tv_sec = timeout.tv_sec;
554 r->_timeout.tv_usec = timeout.tv_usec;
555 }
556
557 void
ldns_resolver_push_searchlist(ldns_resolver * r,ldns_rdf * d)558 ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d)
559 {
560 ldns_rdf **searchlist;
561 size_t list_count;
562
563 if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
564 return;
565 }
566
567 list_count = ldns_resolver_searchlist_count(r);
568 searchlist = ldns_resolver_searchlist(r);
569
570 searchlist = LDNS_XREALLOC(searchlist, ldns_rdf *, (list_count + 1));
571 if (searchlist) {
572 r->_searchlist = searchlist;
573
574 searchlist[list_count] = ldns_rdf_clone(d);
575 ldns_resolver_set_searchlist_count(r, list_count + 1);
576 } /* no way to report mem err */
577 }
578
579 void
ldns_resolver_set_tsig_keyname(ldns_resolver * r,const char * tsig_keyname)580 ldns_resolver_set_tsig_keyname(ldns_resolver *r, const char *tsig_keyname)
581 {
582 LDNS_FREE(r->_tsig_keyname);
583 r->_tsig_keyname = strdup(tsig_keyname);
584 }
585
586 void
ldns_resolver_set_tsig_algorithm(ldns_resolver * r,const char * tsig_algorithm)587 ldns_resolver_set_tsig_algorithm(ldns_resolver *r, const char *tsig_algorithm)
588 {
589 LDNS_FREE(r->_tsig_algorithm);
590 r->_tsig_algorithm = strdup(tsig_algorithm);
591 }
592
593 void
ldns_resolver_set_tsig_keydata(ldns_resolver * r,const char * tsig_keydata)594 ldns_resolver_set_tsig_keydata(ldns_resolver *r, const char *tsig_keydata)
595 {
596 LDNS_FREE(r->_tsig_keydata);
597 r->_tsig_keydata = strdup(tsig_keydata);
598 }
599
600 void
ldns_resolver_set_random(ldns_resolver * r,bool b)601 ldns_resolver_set_random(ldns_resolver *r, bool b)
602 {
603 r->_random = b;
604 }
605
606 /* more sophisticated functions */
607 ldns_resolver *
ldns_resolver_new(void)608 ldns_resolver_new(void)
609 {
610 ldns_resolver *r;
611
612 r = LDNS_MALLOC(ldns_resolver);
613 if (!r) {
614 return NULL;
615 }
616
617 r->_searchlist = NULL;
618 r->_nameservers = NULL;
619 r->_rtt = NULL;
620
621 /* defaults are filled out */
622 ldns_resolver_set_searchlist_count(r, 0);
623 ldns_resolver_set_nameserver_count(r, 0);
624 ldns_resolver_set_usevc(r, 0);
625 ldns_resolver_set_port(r, LDNS_PORT);
626 ldns_resolver_set_domain(r, NULL);
627 ldns_resolver_set_defnames(r, false);
628 ldns_resolver_set_retry(r, 3);
629 ldns_resolver_set_retrans(r, 2);
630 ldns_resolver_set_fallback(r, true);
631 ldns_resolver_set_fail(r, false);
632 ldns_resolver_set_edns_udp_size(r, 0);
633 ldns_resolver_set_dnssec(r, false);
634 ldns_resolver_set_dnssec_cd(r, false);
635 ldns_resolver_set_dnssec_anchors(r, NULL);
636 ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
637 ldns_resolver_set_igntc(r, false);
638 ldns_resolver_set_recursive(r, false);
639 ldns_resolver_set_dnsrch(r, true);
640 ldns_resolver_set_source(r, NULL);
641 ldns_resolver_set_ixfr_serial(r, 0);
642
643 /* randomize the nameserver to be queried
644 * when there are multiple
645 */
646 ldns_resolver_set_random(r, true);
647
648 ldns_resolver_set_debug(r, 0);
649
650 r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
651 r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;
652
653 r->_socket = -1;
654 r->_axfr_soa_count = 0;
655 r->_axfr_i = 0;
656 r->_cur_axfr_pkt = NULL;
657
658 r->_tsig_keyname = NULL;
659 r->_tsig_keydata = NULL;
660 r->_tsig_algorithm = NULL;
661 return r;
662 }
663
664 ldns_resolver *
ldns_resolver_clone(ldns_resolver * src)665 ldns_resolver_clone(ldns_resolver *src)
666 {
667 ldns_resolver *dst;
668 size_t i;
669
670 assert(src != NULL);
671
672 if (!(dst = LDNS_MALLOC(ldns_resolver))) return NULL;
673 (void) memcpy(dst, src, sizeof(ldns_resolver));
674
675 if (dst->_searchlist_count == 0)
676 dst->_searchlist = NULL;
677 else {
678 if (!(dst->_searchlist =
679 LDNS_XMALLOC(ldns_rdf *, dst->_searchlist_count)))
680 goto error;
681 for (i = 0; i < dst->_searchlist_count; i++)
682 if (!(dst->_searchlist[i] =
683 ldns_rdf_clone(src->_searchlist[i]))) {
684 dst->_searchlist_count = i;
685 goto error_searchlist;
686 }
687 }
688 if (dst->_nameserver_count == 0) {
689 dst->_nameservers = NULL;
690 dst->_rtt = NULL;
691 } else {
692 if (!(dst->_nameservers =
693 LDNS_XMALLOC(ldns_rdf *, dst->_nameserver_count)))
694 goto error_searchlist;
695 for (i = 0; i < dst->_nameserver_count; i++)
696 if (!(dst->_nameservers[i] =
697 ldns_rdf_clone(src->_nameservers[i]))) {
698 dst->_nameserver_count = i;
699 goto error_nameservers;
700 }
701 if (!(dst->_rtt =
702 LDNS_XMALLOC(size_t, dst->_nameserver_count)))
703 goto error_nameservers;
704 (void) memcpy(dst->_rtt, src->_rtt,
705 sizeof(size_t) * dst->_nameserver_count);
706 }
707 if (dst->_domain && (!(dst->_domain = ldns_rdf_clone(src->_domain))))
708 goto error_rtt;
709
710 if (dst->_tsig_keyname &&
711 (!(dst->_tsig_keyname = strdup(src->_tsig_keyname))))
712 goto error_domain;
713
714 if (dst->_tsig_keydata &&
715 (!(dst->_tsig_keydata = strdup(src->_tsig_keydata))))
716 goto error_tsig_keyname;
717
718 if (dst->_tsig_algorithm &&
719 (!(dst->_tsig_algorithm = strdup(src->_tsig_algorithm))))
720 goto error_tsig_keydata;
721
722 if (dst->_cur_axfr_pkt &&
723 (!(dst->_cur_axfr_pkt = ldns_pkt_clone(src->_cur_axfr_pkt))))
724 goto error_tsig_algorithm;
725
726 if (dst->_dnssec_anchors &&
727 (!(dst->_dnssec_anchors=ldns_rr_list_clone(src->_dnssec_anchors))))
728 goto error_cur_axfr_pkt;
729
730 return dst;
731
732 error_cur_axfr_pkt:
733 ldns_pkt_free(dst->_cur_axfr_pkt);
734 error_tsig_algorithm:
735 LDNS_FREE(dst->_tsig_algorithm);
736 error_tsig_keydata:
737 LDNS_FREE(dst->_tsig_keydata);
738 error_tsig_keyname:
739 LDNS_FREE(dst->_tsig_keyname);
740 error_domain:
741 ldns_rdf_deep_free(dst->_domain);
742 error_rtt:
743 LDNS_FREE(dst->_rtt);
744 error_nameservers:
745 for (i = 0; i < dst->_nameserver_count; i++)
746 ldns_rdf_deep_free(dst->_nameservers[i]);
747 LDNS_FREE(dst->_nameservers);
748 error_searchlist:
749 for (i = 0; i < dst->_searchlist_count; i++)
750 ldns_rdf_deep_free(dst->_searchlist[i]);
751 LDNS_FREE(dst->_searchlist);
752 error:
753 LDNS_FREE(dst);
754 return NULL;
755 }
756
757
758 ldns_status
ldns_resolver_new_frm_fp(ldns_resolver ** res,FILE * fp)759 ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
760 {
761 return ldns_resolver_new_frm_fp_l(res, fp, NULL);
762 }
763
764 ldns_status
ldns_resolver_new_frm_fp_l(ldns_resolver ** res,FILE * fp,int * line_nr)765 ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
766 {
767 ldns_resolver *r = NULL;
768 const char *keyword[LDNS_RESOLV_KEYWORDS];
769 char word[LDNS_MAX_LINELEN + 1];
770 int8_t expect;
771 uint8_t i;
772 ldns_rdf *tmp;
773 #ifdef HAVE_SSL
774 ldns_rr *tmp_rr;
775 #endif
776 ssize_t gtr, bgtr;
777 ldns_buffer *b;
778 int lnr = 0;
779 FILE* myfp = fp;
780 if(!line_nr) line_nr = &lnr;
781
782 if(!fp) {
783 myfp = fopen(LDNS_RESOLV_CONF, "r");
784 if(!myfp)
785 return LDNS_STATUS_FILE_ERR;
786 }
787
788 /* do this better
789 * expect =
790 * 0: keyword
791 * 1: default domain dname
792 * 2: NS aaaa or a record
793 */
794
795 /* recognized keywords */
796 keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
797 keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
798 keyword[LDNS_RESOLV_SEARCH] = "search";
799 /* these two are read but not used atm TODO */
800 keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
801 keyword[LDNS_RESOLV_OPTIONS] = "options";
802 keyword[LDNS_RESOLV_ANCHOR] = "anchor";
803
804 r = ldns_resolver_new();
805 if (!r) {
806 if(!fp) fclose(myfp);
807 return LDNS_STATUS_MEM_ERR;
808 }
809
810 gtr = 1;
811 word[0] = 0;
812 expect = LDNS_RESOLV_KEYWORD;
813 while (gtr > 0) {
814 switch(expect) {
815 case LDNS_RESOLV_KEYWORD:
816 /* keyword */
817 gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
818 if (gtr != 0) {
819 for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
820 if (strcasecmp(keyword[i], word) == 0) {
821 /* chosen the keyword and
822 * expect values carefully
823 */
824 expect = i;
825 break;
826 }
827 }
828 /* no keyword recognized */
829 if (expect == LDNS_RESOLV_KEYWORD) {
830 /* skip line */
831 /*
832 ldns_resolver_deep_free(r);
833 if(!fp) fclose(myfp);
834 return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
835 */
836 }
837 }
838 break;
839 case LDNS_RESOLV_DEFDOMAIN:
840 /* default domain dname */
841 gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
842 if (gtr == 0) {
843 if(!fp) fclose(myfp);
844 ldns_resolver_deep_free(r);
845 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
846 }
847 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
848 if (!tmp) {
849 if(!fp) fclose(myfp);
850 ldns_resolver_deep_free(r);
851 return LDNS_STATUS_SYNTAX_DNAME_ERR;
852 }
853
854 /* DOn't free, because we copy the pointer */
855 ldns_resolver_set_domain(r, tmp);
856 expect = LDNS_RESOLV_KEYWORD;
857 break;
858 case LDNS_RESOLV_NAMESERVER:
859 /* NS aaaa or a record */
860 gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
861 if (gtr == 0) {
862 if(!fp) fclose(myfp);
863 ldns_resolver_deep_free(r);
864 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
865 }
866 if(strchr(word, '%')) {
867 /* snip off interface labels,
868 * fe80::222:19ff:fe31:4222%eth0 */
869 strchr(word, '%')[0]=0;
870 }
871 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
872 if (!tmp) {
873 /* try ip4 */
874 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word);
875 }
876 /* could not parse it, exit */
877 if (!tmp) {
878 ldns_resolver_deep_free(r);
879 if(!fp) fclose(myfp);
880 return LDNS_STATUS_SYNTAX_ERR;
881 }
882 (void)ldns_resolver_push_nameserver(r, tmp);
883 ldns_rdf_deep_free(tmp);
884 expect = LDNS_RESOLV_KEYWORD;
885 break;
886 case LDNS_RESOLV_SEARCH:
887 /* search list domain dname */
888 gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
889 b = LDNS_MALLOC(ldns_buffer);
890 if(!b) {
891 ldns_resolver_deep_free(r);
892 if(!fp) fclose(myfp);
893 return LDNS_STATUS_MEM_ERR;
894 }
895
896 ldns_buffer_new_frm_data(b, word, (size_t) gtr);
897 if(ldns_buffer_status(b) != LDNS_STATUS_OK) {
898 LDNS_FREE(b);
899 ldns_resolver_deep_free(r);
900 if(!fp) fclose(myfp);
901 return LDNS_STATUS_MEM_ERR;
902 }
903 bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1);
904 while (bgtr > 0) {
905 gtr -= bgtr;
906 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
907 if (!tmp) {
908 ldns_resolver_deep_free(r);
909 ldns_buffer_free(b);
910 if(!fp) fclose(myfp);
911 return LDNS_STATUS_SYNTAX_DNAME_ERR;
912 }
913
914 ldns_resolver_push_searchlist(r, tmp);
915
916 ldns_rdf_deep_free(tmp);
917 bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL,
918 (size_t) gtr + 1);
919 }
920 ldns_buffer_free(b);
921 if (expect != LDNS_RESOLV_KEYWORD) {
922 gtr = 1;
923 expect = LDNS_RESOLV_KEYWORD;
924 }
925 break;
926 case LDNS_RESOLV_SORTLIST:
927 gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
928 /* sortlist not implemented atm */
929 expect = LDNS_RESOLV_KEYWORD;
930 break;
931 case LDNS_RESOLV_OPTIONS:
932 gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
933 /* options not implemented atm */
934 expect = LDNS_RESOLV_KEYWORD;
935 break;
936 case LDNS_RESOLV_ANCHOR:
937 /* a file containing a DNSSEC trust anchor */
938 gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
939 if (gtr == 0) {
940 ldns_resolver_deep_free(r);
941 if(!fp) fclose(myfp);
942 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
943 }
944 #ifdef HAVE_SSL
945 tmp_rr = ldns_read_anchor_file(word);
946 (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
947 ldns_rr_free(tmp_rr);
948 #endif
949 expect = LDNS_RESOLV_KEYWORD;
950 break;
951 }
952 }
953
954 if(!fp)
955 fclose(myfp);
956
957 if (res) {
958 *res = r;
959 return LDNS_STATUS_OK;
960 } else {
961 ldns_resolver_deep_free(r);
962 return LDNS_STATUS_NULL;
963 }
964 }
965
966 ldns_status
ldns_resolver_new_frm_file(ldns_resolver ** res,const char * filename)967 ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
968 {
969 ldns_resolver *r;
970 FILE *fp;
971 ldns_status s;
972
973 if (!filename) {
974 fp = fopen(LDNS_RESOLV_CONF, "r");
975
976 } else {
977 fp = fopen(filename, "r");
978 }
979 if (!fp) {
980 return LDNS_STATUS_FILE_ERR;
981 }
982
983 s = ldns_resolver_new_frm_fp(&r, fp);
984 fclose(fp);
985 if (s == LDNS_STATUS_OK) {
986 if (res) {
987 *res = r;
988 return LDNS_STATUS_OK;
989 } else {
990 ldns_resolver_free(r);
991 return LDNS_STATUS_NULL;
992 }
993 }
994 return s;
995 }
996
997 void
ldns_resolver_free(ldns_resolver * res)998 ldns_resolver_free(ldns_resolver *res)
999 {
1000 LDNS_FREE(res);
1001 }
1002
1003 void
ldns_resolver_deep_free(ldns_resolver * res)1004 ldns_resolver_deep_free(ldns_resolver *res)
1005 {
1006 size_t i;
1007
1008 if (res) {
1009 close_socket(res->_socket);
1010
1011 if (res->_searchlist) {
1012 for (i = 0; i < ldns_resolver_searchlist_count(res); i++) {
1013 ldns_rdf_deep_free(res->_searchlist[i]);
1014 }
1015 LDNS_FREE(res->_searchlist);
1016 }
1017 if (res->_nameservers) {
1018 for (i = 0; i < res->_nameserver_count; i++) {
1019 ldns_rdf_deep_free(res->_nameservers[i]);
1020 }
1021 LDNS_FREE(res->_nameservers);
1022 }
1023 if (ldns_resolver_domain(res)) {
1024 ldns_rdf_deep_free(ldns_resolver_domain(res));
1025 }
1026 if (res->_tsig_keyname) {
1027 LDNS_FREE(res->_tsig_keyname);
1028 }
1029 if (res->_tsig_keydata) {
1030 LDNS_FREE(res->_tsig_keydata);
1031 }
1032 if (res->_tsig_algorithm) {
1033 LDNS_FREE(res->_tsig_algorithm);
1034 }
1035
1036 if (res->_cur_axfr_pkt) {
1037 ldns_pkt_free(res->_cur_axfr_pkt);
1038 }
1039
1040 if (res->_rtt) {
1041 LDNS_FREE(res->_rtt);
1042 }
1043 if (res->_dnssec_anchors) {
1044 ldns_rr_list_deep_free(res->_dnssec_anchors);
1045 }
1046 LDNS_FREE(res);
1047 }
1048 }
1049
1050 ldns_status
ldns_resolver_search_status(ldns_pkt ** pkt,ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)1051 ldns_resolver_search_status(ldns_pkt** pkt,
1052 ldns_resolver *r, const ldns_rdf *name,
1053 ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1054 {
1055 ldns_rdf *new_name;
1056 ldns_rdf **search_list;
1057 size_t i;
1058 ldns_status s = LDNS_STATUS_OK;
1059 ldns_rdf root_dname = { 1, LDNS_RDF_TYPE_DNAME, (void *)"" };
1060
1061 if (ldns_dname_absolute(name)) {
1062 /* query as-is */
1063 return ldns_resolver_query_status(pkt, r, name, t, c, flags);
1064 } else if (ldns_resolver_dnsrch(r)) {
1065 ldns_pkt *return_pkt = NULL;
1066
1067 search_list = ldns_resolver_searchlist(r);
1068 for (i = 0; i <= ldns_resolver_searchlist_count(r); i++) {
1069 if (i == ldns_resolver_searchlist_count(r)) {
1070 new_name = ldns_dname_cat_clone(name,
1071 &root_dname);
1072 } else {
1073 new_name = ldns_dname_cat_clone(name,
1074 search_list[i]);
1075 }
1076
1077 s = ldns_resolver_query_status(&return_pkt, r,
1078 new_name, t, c, flags);
1079 ldns_rdf_deep_free(new_name);
1080
1081 if (return_pkt) {
1082 if (s == LDNS_STATUS_OK &&
1083 ldns_pkt_get_rcode(return_pkt)
1084 == LDNS_RCODE_NOERROR) {
1085
1086 return LDNS_STATUS_OK;
1087 } else if (i < ldns_resolver_searchlist_count(r)) {
1088 ldns_pkt_free(return_pkt);
1089 return_pkt = NULL;
1090 }
1091 }
1092 }
1093 if (pkt && return_pkt) {
1094 *pkt = return_pkt;
1095 }
1096 }
1097 return s;
1098 }
1099
1100 ldns_pkt *
ldns_resolver_search(const ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)1101 ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name,
1102 ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1103 {
1104 ldns_pkt* pkt = NULL;
1105 if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r,
1106 name, t, c, flags) != LDNS_STATUS_OK) {
1107 ldns_pkt_free(pkt);
1108 return NULL;
1109 }
1110 return pkt;
1111 }
1112
1113 ldns_status
ldns_resolver_query_status(ldns_pkt ** pkt,ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)1114 ldns_resolver_query_status(ldns_pkt** pkt,
1115 ldns_resolver *r, const ldns_rdf *name,
1116 ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1117 {
1118 ldns_rdf *newname;
1119 ldns_status status;
1120
1121 if (!ldns_resolver_defnames(r) || !ldns_resolver_domain(r)) {
1122 return ldns_resolver_send(pkt, r, name, t, c, flags);
1123 }
1124
1125 newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r));
1126 if (!newname) {
1127 return LDNS_STATUS_MEM_ERR;
1128 }
1129 status = ldns_resolver_send(pkt, r, newname, t, c, flags);
1130 ldns_rdf_free(newname);
1131 return status;
1132 }
1133
1134 ldns_pkt *
ldns_resolver_query(const ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)1135 ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
1136 ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1137 {
1138 ldns_pkt* pkt = NULL;
1139 if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r,
1140 name, t, c, flags) != LDNS_STATUS_OK) {
1141 ldns_pkt_free(pkt);
1142 return NULL;
1143 }
1144 return pkt;
1145 }
1146
1147 static size_t *
ldns_resolver_backup_rtt(ldns_resolver * r)1148 ldns_resolver_backup_rtt(ldns_resolver *r)
1149 {
1150 size_t *new_rtt;
1151 size_t *old_rtt = ldns_resolver_rtt(r);
1152
1153 if (old_rtt && ldns_resolver_nameserver_count(r)) {
1154 new_rtt = LDNS_XMALLOC(size_t
1155 , ldns_resolver_nameserver_count(r));
1156 if (!new_rtt) return NULL;
1157 memcpy(new_rtt, old_rtt, sizeof(size_t)
1158 * ldns_resolver_nameserver_count(r));
1159 ldns_resolver_set_rtt(r, new_rtt);
1160 return old_rtt;
1161 }
1162 return NULL;
1163 }
1164
1165 static void
ldns_resolver_restore_rtt(ldns_resolver * r,size_t * old_rtt)1166 ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt)
1167 {
1168 size_t *cur_rtt = ldns_resolver_rtt(r);
1169
1170 if (cur_rtt) {
1171 LDNS_FREE(cur_rtt);
1172 }
1173 ldns_resolver_set_rtt(r, old_rtt);
1174 }
1175
1176 ldns_status
ldns_resolver_send_pkt(ldns_pkt ** answer,ldns_resolver * r,ldns_pkt * query_pkt)1177 ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
1178 ldns_pkt *query_pkt)
1179 {
1180 ldns_pkt *answer_pkt = NULL;
1181 ldns_status stat = LDNS_STATUS_OK;
1182 size_t *rtt;
1183
1184 stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
1185 if (stat != LDNS_STATUS_OK) {
1186 if(answer_pkt) {
1187 ldns_pkt_free(answer_pkt);
1188 answer_pkt = NULL;
1189 }
1190 } else {
1191 /* if tc=1 fall back to EDNS and/or TCP */
1192 /* check for tcp first (otherwise we don't care about tc=1) */
1193 if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
1194 if (ldns_pkt_tc(answer_pkt)) {
1195 /* was EDNS0 set? */
1196 if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
1197 ldns_pkt_set_edns_udp_size(query_pkt
1198 , 4096);
1199 ldns_pkt_free(answer_pkt);
1200 answer_pkt = NULL;
1201 /* Nameservers should not become
1202 * unreachable because fragments are
1203 * dropped (network error). We might
1204 * still have success with TCP.
1205 * Therefore maintain reachability
1206 * statuses of the nameservers by
1207 * backup and restore the rtt list.
1208 */
1209 rtt = ldns_resolver_backup_rtt(r);
1210 stat = ldns_send(&answer_pkt, r
1211 , query_pkt);
1212 ldns_resolver_restore_rtt(r, rtt);
1213 }
1214 /* either way, if it is still truncated, use TCP */
1215 if (stat != LDNS_STATUS_OK ||
1216 ldns_pkt_tc(answer_pkt)) {
1217 ldns_resolver_set_usevc(r, true);
1218 ldns_pkt_free(answer_pkt);
1219 answer_pkt = NULL;
1220 stat = ldns_send(&answer_pkt, r, query_pkt);
1221 ldns_resolver_set_usevc(r, false);
1222 }
1223 }
1224 }
1225 }
1226
1227 if (answer && answer_pkt) {
1228 *answer = answer_pkt;
1229 }
1230
1231 return stat;
1232 }
1233
1234 ldns_status
ldns_resolver_prepare_query_pkt(ldns_pkt ** query_pkt,ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)1235 ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r,
1236 const ldns_rdf *name, ldns_rr_type t,
1237 ldns_rr_class c, uint16_t flags)
1238 {
1239 struct timeval now;
1240 ldns_rr* soa = NULL;
1241
1242 /* prepare a question pkt from the parameters
1243 * and then send this */
1244 if (t == LDNS_RR_TYPE_IXFR) {
1245 ldns_rdf *owner_rdf;
1246 ldns_rdf *mname_rdf;
1247 ldns_rdf *rname_rdf;
1248 ldns_rdf *serial_rdf;
1249 ldns_rdf *refresh_rdf;
1250 ldns_rdf *retry_rdf;
1251 ldns_rdf *expire_rdf;
1252 ldns_rdf *minimum_rdf;
1253 soa = ldns_rr_new();
1254
1255 if (!soa) {
1256 return LDNS_STATUS_ERR;
1257 }
1258 owner_rdf = ldns_rdf_clone(name);
1259 if (!owner_rdf) {
1260 ldns_rr_free(soa);
1261 return LDNS_STATUS_ERR;
1262 }
1263 ldns_rr_set_owner(soa, owner_rdf);
1264 ldns_rr_set_type(soa, LDNS_RR_TYPE_SOA);
1265 ldns_rr_set_class(soa, c);
1266 ldns_rr_set_question(soa, false);
1267 if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
1268 ldns_rr_free(soa);
1269 return LDNS_STATUS_ERR;
1270 } else ldns_rr_push_rdf(soa, mname_rdf);
1271 if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
1272 ldns_rr_free(soa);
1273 return LDNS_STATUS_ERR;
1274 } else ldns_rr_push_rdf(soa, rname_rdf);
1275 serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, ldns_resolver_get_ixfr_serial(r));
1276 if (!serial_rdf) {
1277 ldns_rr_free(soa);
1278 return LDNS_STATUS_ERR;
1279 } else ldns_rr_push_rdf(soa, serial_rdf);
1280 refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1281 if (!refresh_rdf) {
1282 ldns_rr_free(soa);
1283 return LDNS_STATUS_ERR;
1284 } else ldns_rr_push_rdf(soa, refresh_rdf);
1285 retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1286 if (!retry_rdf) {
1287 ldns_rr_free(soa);
1288 return LDNS_STATUS_ERR;
1289 } else ldns_rr_push_rdf(soa, retry_rdf);
1290 expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1291 if (!expire_rdf) {
1292 ldns_rr_free(soa);
1293 return LDNS_STATUS_ERR;
1294 } else ldns_rr_push_rdf(soa, expire_rdf);
1295 minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1296 if (!minimum_rdf) {
1297 ldns_rr_free(soa);
1298 return LDNS_STATUS_ERR;
1299 } else ldns_rr_push_rdf(soa, minimum_rdf);
1300
1301 *query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name),
1302 c, flags, soa);
1303 } else {
1304 *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
1305 }
1306 if (!*query_pkt) {
1307 ldns_rr_free(soa);
1308 return LDNS_STATUS_ERR;
1309 }
1310
1311 /* set DO bit if necessary */
1312 if (ldns_resolver_dnssec(r)) {
1313 if (ldns_resolver_edns_udp_size(r) == 0) {
1314 ldns_resolver_set_edns_udp_size(r, 4096);
1315 }
1316 ldns_pkt_set_edns_do(*query_pkt, true);
1317 if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) {
1318 ldns_pkt_set_cd(*query_pkt, true);
1319 }
1320 }
1321
1322 /* transfer the udp_edns_size from the resolver to the packet */
1323 if (ldns_resolver_edns_udp_size(r) != 0) {
1324 ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r));
1325 }
1326
1327 /* set the timestamp */
1328 now.tv_sec = time(NULL);
1329 now.tv_usec = 0;
1330 ldns_pkt_set_timestamp(*query_pkt, now);
1331
1332
1333 if (ldns_resolver_debug(r)) {
1334 ldns_pkt_print(stdout, *query_pkt);
1335 }
1336
1337 /* only set the id if it is not set yet */
1338 if (ldns_pkt_id(*query_pkt) == 0) {
1339 ldns_pkt_set_random_id(*query_pkt);
1340 }
1341
1342 return LDNS_STATUS_OK;
1343 }
1344
1345 ldns_status
ldns_resolver_send(ldns_pkt ** answer,ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)1346 ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
1347 ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1348 {
1349 ldns_pkt *query_pkt;
1350 ldns_pkt *answer_pkt;
1351 ldns_status status;
1352
1353 assert(r != NULL);
1354 assert(name != NULL);
1355
1356 answer_pkt = NULL;
1357
1358 /* do all the preprocessing here, then fire of an query to
1359 * the network */
1360
1361 if (0 == t) {
1362 t= LDNS_RR_TYPE_A;
1363 }
1364 if (0 == c) {
1365 c= LDNS_RR_CLASS_IN;
1366 }
1367 if (0 == ldns_resolver_nameserver_count(r)) {
1368 return LDNS_STATUS_RES_NO_NS;
1369 }
1370 if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
1371 return LDNS_STATUS_RES_QUERY;
1372 }
1373
1374 status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name,
1375 t, c, flags);
1376 if (status != LDNS_STATUS_OK) {
1377 return status;
1378 }
1379
1380 /* if tsig values are set, tsign it */
1381 /* TODO: make last 3 arguments optional too? maybe make complete
1382 rr instead of separate values in resolver (and packet)
1383 Jelte
1384 should this go in pkt_prepare?
1385 */
1386 if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) {
1387 #ifdef HAVE_SSL
1388 status = ldns_pkt_tsig_sign(query_pkt,
1389 ldns_resolver_tsig_keyname(r),
1390 ldns_resolver_tsig_keydata(r),
1391 300, ldns_resolver_tsig_algorithm(r), NULL);
1392 if (status != LDNS_STATUS_OK) {
1393 ldns_pkt_free(query_pkt);
1394 return LDNS_STATUS_CRYPTO_TSIG_ERR;
1395 }
1396 #else
1397 ldns_pkt_free(query_pkt);
1398 return LDNS_STATUS_CRYPTO_TSIG_ERR;
1399 #endif /* HAVE_SSL */
1400 }
1401
1402 status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
1403 ldns_pkt_free(query_pkt);
1404
1405 /* allows answer to be NULL when not interested in return value */
1406 if (answer) {
1407 *answer = answer_pkt;
1408 }
1409 return status;
1410 }
1411
1412 ldns_rr *
ldns_axfr_next(ldns_resolver * resolver)1413 ldns_axfr_next(ldns_resolver *resolver)
1414 {
1415 ldns_rr *cur_rr;
1416 uint8_t *packet_wire;
1417 size_t packet_wire_size;
1418 ldns_status status;
1419
1420 /* check if start() has been called */
1421 if (!resolver || resolver->_socket == -1) {
1422 return NULL;
1423 }
1424
1425 if (resolver->_cur_axfr_pkt) {
1426 if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
1427 ldns_pkt_free(resolver->_cur_axfr_pkt);
1428 resolver->_cur_axfr_pkt = NULL;
1429 return ldns_axfr_next(resolver);
1430 }
1431 cur_rr = ldns_rr_clone(ldns_rr_list_rr(
1432 ldns_pkt_answer(resolver->_cur_axfr_pkt),
1433 resolver->_axfr_i));
1434 resolver->_axfr_i++;
1435 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
1436 resolver->_axfr_soa_count++;
1437 if (resolver->_axfr_soa_count >= 2) {
1438
1439 close_socket(resolver->_socket);
1440
1441 ldns_pkt_free(resolver->_cur_axfr_pkt);
1442 resolver->_cur_axfr_pkt = NULL;
1443 }
1444 }
1445 return cur_rr;
1446 } else {
1447 packet_wire = ldns_tcp_read_wire_timeout(resolver->_socket, &packet_wire_size, resolver->_timeout);
1448 if(!packet_wire)
1449 return NULL;
1450
1451 status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
1452 packet_wire_size);
1453 LDNS_FREE(packet_wire);
1454
1455 resolver->_axfr_i = 0;
1456 if (status != LDNS_STATUS_OK) {
1457 /* TODO: make status return type of this function (...api change) */
1458 #ifdef STDERR_MSGS
1459 fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
1460 #endif
1461
1462 /* we must now also close the socket, otherwise subsequent uses of the
1463 same resolver structure will fail because the link is still open or
1464 in an undefined state */
1465
1466 close_socket(resolver->_socket);
1467
1468 return NULL;
1469 } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
1470 #ifdef STDERR_MSGS
1471 ldns_lookup_table *rcode = ldns_lookup_by_id(
1472 ldns_rcodes,(int) ldns_pkt_get_rcode(
1473 resolver->_cur_axfr_pkt));
1474 if (rcode) {
1475 fprintf(stderr, "Error in AXFR: %s\n",
1476 rcode->name);
1477 } else {
1478 fprintf(stderr, "Error in AXFR: %d\n",
1479 (int) ldns_pkt_get_rcode(
1480 resolver->_cur_axfr_pkt));
1481 }
1482 #endif
1483
1484 /* we must now also close the socket, otherwise subsequent uses of the
1485 same resolver structure will fail because the link is still open or
1486 in an undefined state */
1487
1488 close_socket(resolver->_socket);
1489
1490 return NULL;
1491 } else {
1492 return ldns_axfr_next(resolver);
1493 }
1494
1495 }
1496
1497 }
1498
1499 /* this function is needed to abort a transfer that is in progress;
1500 * without it an aborted transfer will lead to the AXFR code in the
1501 * library staying in an indetermined state because the socket for the
1502 * AXFR is never closed
1503 */
1504 void
ldns_axfr_abort(ldns_resolver * resolver)1505 ldns_axfr_abort(ldns_resolver *resolver)
1506 {
1507 /* Only abort if an actual AXFR is in progress */
1508 if (resolver->_socket != -1)
1509 {
1510 #ifndef USE_WINSOCK
1511 close(resolver->_socket);
1512 #else
1513 closesocket(resolver->_socket);
1514 #endif
1515 resolver->_socket = -1;
1516 }
1517 }
1518
1519 bool
ldns_axfr_complete(const ldns_resolver * res)1520 ldns_axfr_complete(const ldns_resolver *res)
1521 {
1522 /* complete when soa count is 2? */
1523 return res->_axfr_soa_count == 2;
1524 }
1525
1526 ldns_pkt *
ldns_axfr_last_pkt(const ldns_resolver * res)1527 ldns_axfr_last_pkt(const ldns_resolver *res)
1528 {
1529 return res->_cur_axfr_pkt;
1530 }
1531
1532 void
ldns_resolver_set_ixfr_serial(ldns_resolver * r,uint32_t serial)1533 ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial)
1534 {
1535 r->_serial = serial;
1536 }
1537
1538 uint32_t
ldns_resolver_get_ixfr_serial(const ldns_resolver * res)1539 ldns_resolver_get_ixfr_serial(const ldns_resolver *res)
1540 {
1541 return res->_serial;
1542 }
1543
1544
1545 /* random isn't really that good */
1546 void
ldns_resolver_nameservers_randomize(ldns_resolver * r)1547 ldns_resolver_nameservers_randomize(ldns_resolver *r)
1548 {
1549 uint16_t i, j;
1550 ldns_rdf **ns, *tmpns;
1551 size_t *rtt, tmprtt;
1552
1553 /* should I check for ldns_resolver_random?? */
1554 assert(r != NULL);
1555
1556 ns = ldns_resolver_nameservers(r);
1557 rtt = ldns_resolver_rtt(r);
1558 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
1559 j = ldns_get_random() % ldns_resolver_nameserver_count(r);
1560 tmpns = ns[i];
1561 ns[i] = ns[j];
1562 ns[j] = tmpns;
1563 tmprtt = rtt[i];
1564 rtt[i] = rtt[j];
1565 rtt[j] = tmprtt;
1566 }
1567 ldns_resolver_set_nameservers(r, ns);
1568 }
1569
1570