Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/contrib/ldns/resolver.c
39478 views
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
24
ldns_resolver_port(const ldns_resolver *r)
25
{
26
return r->_port;
27
}
28
29
ldns_rdf *
30
ldns_resolver_source(const ldns_resolver *r)
31
{
32
return r->_source;
33
}
34
35
uint16_t
36
ldns_resolver_edns_udp_size(const ldns_resolver *r)
37
{
38
return r->_edns_udp_size;
39
}
40
41
uint8_t
42
ldns_resolver_retry(const ldns_resolver *r)
43
{
44
return r->_retry;
45
}
46
47
uint8_t
48
ldns_resolver_retrans(const ldns_resolver *r)
49
{
50
return r->_retrans;
51
}
52
53
bool
54
ldns_resolver_fallback(const ldns_resolver *r)
55
{
56
return r->_fallback;
57
}
58
59
uint8_t
60
ldns_resolver_ip6(const ldns_resolver *r)
61
{
62
return r->_ip6;
63
}
64
65
bool
66
ldns_resolver_recursive(const ldns_resolver *r)
67
{
68
return r->_recursive;
69
}
70
71
bool
72
ldns_resolver_debug(const ldns_resolver *r)
73
{
74
return r->_debug;
75
}
76
77
bool
78
ldns_resolver_dnsrch(const ldns_resolver *r)
79
{
80
return r->_dnsrch;
81
}
82
83
bool
84
ldns_resolver_fail(const ldns_resolver *r)
85
{
86
return r->_fail;
87
}
88
89
bool
90
ldns_resolver_defnames(const ldns_resolver *r)
91
{
92
return r->_defnames;
93
}
94
95
ldns_rdf *
96
ldns_resolver_domain(const ldns_resolver *r)
97
{
98
return r->_domain;
99
}
100
101
ldns_rdf **
102
ldns_resolver_searchlist(const ldns_resolver *r)
103
{
104
return r->_searchlist;
105
}
106
107
ldns_rdf **
108
ldns_resolver_nameservers(const ldns_resolver *r)
109
{
110
return r->_nameservers;
111
}
112
113
size_t
114
ldns_resolver_nameserver_count(const ldns_resolver *r)
115
{
116
return r->_nameserver_count;
117
}
118
119
bool
120
ldns_resolver_dnssec(const ldns_resolver *r)
121
{
122
return r->_dnssec;
123
}
124
125
bool
126
ldns_resolver_dnssec_cd(const ldns_resolver *r)
127
{
128
return r->_dnssec_cd;
129
}
130
131
ldns_rr_list *
132
ldns_resolver_dnssec_anchors(const ldns_resolver *r)
133
{
134
return r->_dnssec_anchors;
135
}
136
137
bool
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
165
ldns_resolver_igntc(const ldns_resolver *r)
166
{
167
return r->_igntc;
168
}
169
170
bool
171
ldns_resolver_usevc(const ldns_resolver *r)
172
{
173
return r->_usevc;
174
}
175
176
size_t *
177
ldns_resolver_rtt(const ldns_resolver *r)
178
{
179
return r->_rtt;
180
}
181
182
size_t
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
201
ldns_resolver_timeout(const ldns_resolver *r)
202
{
203
return r->_timeout;
204
}
205
206
const char *
207
ldns_resolver_tsig_keyname(const ldns_resolver *r)
208
{
209
return r->_tsig_keyname;
210
}
211
212
const char *
213
ldns_resolver_tsig_algorithm(const ldns_resolver *r)
214
{
215
return r->_tsig_algorithm;
216
}
217
218
const char *
219
ldns_resolver_tsig_keydata(const ldns_resolver *r)
220
{
221
return r->_tsig_keydata;
222
}
223
224
bool
225
ldns_resolver_random(const ldns_resolver *r)
226
{
227
return r->_random;
228
}
229
230
size_t
231
ldns_resolver_searchlist_count(const ldns_resolver *r)
232
{
233
return r->_searchlist_count;
234
}
235
236
/* write */
237
void
238
ldns_resolver_set_port(ldns_resolver *r, uint16_t p)
239
{
240
r->_port = p;
241
}
242
243
void
244
ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s)
245
{
246
r->_source = s;
247
}
248
249
ldns_rdf *
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
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
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
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
373
ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
374
{
375
r->_edns_udp_size = s;
376
}
377
378
void
379
ldns_resolver_set_recursive(ldns_resolver *r, bool re)
380
{
381
r->_recursive = re;
382
}
383
384
void
385
ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
386
{
387
r->_dnssec = d;
388
}
389
390
void
391
ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
392
{
393
r->_dnssec_cd = d;
394
}
395
396
void
397
ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
398
{
399
r->_dnssec_anchors = l;
400
}
401
402
ldns_status
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
422
ldns_resolver_set_igntc(ldns_resolver *r, bool i)
423
{
424
r->_igntc = i;
425
}
426
427
void
428
ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
429
{
430
r->_usevc = vc;
431
}
432
433
void
434
ldns_resolver_set_debug(ldns_resolver *r, bool d)
435
{
436
r->_debug = d;
437
}
438
439
void
440
ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
441
{
442
r->_ip6 = ip6;
443
}
444
445
void
446
ldns_resolver_set_fail(ldns_resolver *r, bool f)
447
{
448
r->_fail =f;
449
}
450
451
static void
452
ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
453
{
454
r->_searchlist_count = c;
455
}
456
457
void
458
ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
459
{
460
r->_nameserver_count = c;
461
}
462
463
void
464
ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
465
{
466
r->_dnsrch = d;
467
}
468
469
void
470
ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
471
{
472
r->_retry = retry;
473
}
474
475
void
476
ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
477
{
478
r->_retrans = retrans;
479
}
480
481
void
482
ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
483
{
484
r->_fallback = fallback;
485
}
486
487
void
488
ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
489
{
490
r->_nameservers = n;
491
}
492
493
void
494
ldns_resolver_set_defnames(ldns_resolver *r, bool d)
495
{
496
r->_defnames = d;
497
}
498
499
void
500
ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
501
{
502
r->_rtt = rtt;
503
}
504
505
void
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
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
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
545
ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
546
{
547
r->_domain = d;
548
}
549
550
void
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
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
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
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
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
601
ldns_resolver_set_random(ldns_resolver *r, bool b)
602
{
603
r->_random = b;
604
}
605
606
/* more sophisticated functions */
607
ldns_resolver *
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 *
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
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
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
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
998
ldns_resolver_free(ldns_resolver *res)
999
{
1000
LDNS_FREE(res);
1001
}
1002
1003
void
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
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
search_list = ldns_resolver_searchlist(r);
1066
for (i = 0; i <= ldns_resolver_searchlist_count(r); i++) {
1067
if (i == ldns_resolver_searchlist_count(r)) {
1068
new_name = ldns_dname_cat_clone(name,
1069
&root_dname);
1070
} else {
1071
new_name = ldns_dname_cat_clone(name,
1072
search_list[i]);
1073
}
1074
1075
s = ldns_resolver_query_status(pkt, r,
1076
new_name, t, c, flags);
1077
ldns_rdf_deep_free(new_name);
1078
1079
if (pkt && *pkt) {
1080
if (s == LDNS_STATUS_OK &&
1081
ldns_pkt_get_rcode(*pkt) ==
1082
LDNS_RCODE_NOERROR) {
1083
1084
return LDNS_STATUS_OK;
1085
}
1086
ldns_pkt_free(*pkt);
1087
*pkt = NULL;
1088
}
1089
}
1090
}
1091
return s;
1092
}
1093
1094
ldns_pkt *
1095
ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name,
1096
ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1097
{
1098
ldns_pkt* pkt = NULL;
1099
if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r,
1100
name, t, c, flags) != LDNS_STATUS_OK) {
1101
ldns_pkt_free(pkt);
1102
return NULL;
1103
}
1104
return pkt;
1105
}
1106
1107
ldns_status
1108
ldns_resolver_query_status(ldns_pkt** pkt,
1109
ldns_resolver *r, const ldns_rdf *name,
1110
ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1111
{
1112
ldns_rdf *newname;
1113
ldns_status status;
1114
1115
if (!ldns_resolver_defnames(r) || !ldns_resolver_domain(r)) {
1116
return ldns_resolver_send(pkt, r, name, t, c, flags);
1117
}
1118
1119
newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r));
1120
if (!newname) {
1121
return LDNS_STATUS_MEM_ERR;
1122
}
1123
status = ldns_resolver_send(pkt, r, newname, t, c, flags);
1124
ldns_rdf_free(newname);
1125
return status;
1126
}
1127
1128
ldns_pkt *
1129
ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
1130
ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1131
{
1132
ldns_pkt* pkt = NULL;
1133
if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r,
1134
name, t, c, flags) != LDNS_STATUS_OK) {
1135
ldns_pkt_free(pkt);
1136
return NULL;
1137
}
1138
return pkt;
1139
}
1140
1141
static size_t *
1142
ldns_resolver_backup_rtt(ldns_resolver *r)
1143
{
1144
size_t *new_rtt;
1145
size_t *old_rtt = ldns_resolver_rtt(r);
1146
1147
if (old_rtt && ldns_resolver_nameserver_count(r)) {
1148
new_rtt = LDNS_XMALLOC(size_t
1149
, ldns_resolver_nameserver_count(r));
1150
if (!new_rtt) return NULL;
1151
memcpy(new_rtt, old_rtt, sizeof(size_t)
1152
* ldns_resolver_nameserver_count(r));
1153
ldns_resolver_set_rtt(r, new_rtt);
1154
return old_rtt;
1155
}
1156
return NULL;
1157
}
1158
1159
static void
1160
ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt)
1161
{
1162
size_t *cur_rtt = ldns_resolver_rtt(r);
1163
1164
if (cur_rtt) {
1165
LDNS_FREE(cur_rtt);
1166
}
1167
ldns_resolver_set_rtt(r, old_rtt);
1168
}
1169
1170
ldns_status
1171
ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
1172
ldns_pkt *query_pkt)
1173
{
1174
ldns_pkt *answer_pkt = NULL;
1175
ldns_status stat = LDNS_STATUS_OK;
1176
size_t *rtt;
1177
1178
stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
1179
if (stat != LDNS_STATUS_OK) {
1180
if(answer_pkt) {
1181
ldns_pkt_free(answer_pkt);
1182
answer_pkt = NULL;
1183
}
1184
} else {
1185
/* if tc=1 fall back to EDNS and/or TCP */
1186
/* check for tcp first (otherwise we don't care about tc=1) */
1187
if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
1188
if (ldns_pkt_tc(answer_pkt)) {
1189
/* was EDNS0 set? */
1190
if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
1191
ldns_pkt_set_edns_udp_size(query_pkt
1192
, 4096);
1193
ldns_pkt_free(answer_pkt);
1194
answer_pkt = NULL;
1195
/* Nameservers should not become
1196
* unreachable because fragments are
1197
* dropped (network error). We might
1198
* still have success with TCP.
1199
* Therefore maintain reachability
1200
* statuses of the nameservers by
1201
* backup and restore the rtt list.
1202
*/
1203
rtt = ldns_resolver_backup_rtt(r);
1204
stat = ldns_send(&answer_pkt, r
1205
, query_pkt);
1206
ldns_resolver_restore_rtt(r, rtt);
1207
}
1208
/* either way, if it is still truncated, use TCP */
1209
if (stat != LDNS_STATUS_OK ||
1210
ldns_pkt_tc(answer_pkt)) {
1211
ldns_resolver_set_usevc(r, true);
1212
ldns_pkt_free(answer_pkt);
1213
answer_pkt = NULL;
1214
stat = ldns_send(&answer_pkt, r, query_pkt);
1215
ldns_resolver_set_usevc(r, false);
1216
}
1217
}
1218
}
1219
}
1220
1221
if (answer && answer_pkt) {
1222
*answer = answer_pkt;
1223
}
1224
1225
return stat;
1226
}
1227
1228
ldns_status
1229
ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r,
1230
const ldns_rdf *name, ldns_rr_type t,
1231
ldns_rr_class c, uint16_t flags)
1232
{
1233
struct timeval now;
1234
ldns_rr* soa = NULL;
1235
1236
/* prepare a question pkt from the parameters
1237
* and then send this */
1238
if (t == LDNS_RR_TYPE_IXFR) {
1239
ldns_rdf *owner_rdf;
1240
ldns_rdf *mname_rdf;
1241
ldns_rdf *rname_rdf;
1242
ldns_rdf *serial_rdf;
1243
ldns_rdf *refresh_rdf;
1244
ldns_rdf *retry_rdf;
1245
ldns_rdf *expire_rdf;
1246
ldns_rdf *minimum_rdf;
1247
soa = ldns_rr_new();
1248
1249
if (!soa) {
1250
return LDNS_STATUS_ERR;
1251
}
1252
owner_rdf = ldns_rdf_clone(name);
1253
if (!owner_rdf) {
1254
ldns_rr_free(soa);
1255
return LDNS_STATUS_ERR;
1256
}
1257
ldns_rr_set_owner(soa, owner_rdf);
1258
ldns_rr_set_type(soa, LDNS_RR_TYPE_SOA);
1259
ldns_rr_set_class(soa, c);
1260
ldns_rr_set_question(soa, false);
1261
if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
1262
ldns_rr_free(soa);
1263
return LDNS_STATUS_ERR;
1264
} else ldns_rr_push_rdf(soa, mname_rdf);
1265
if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
1266
ldns_rr_free(soa);
1267
return LDNS_STATUS_ERR;
1268
} else ldns_rr_push_rdf(soa, rname_rdf);
1269
serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, ldns_resolver_get_ixfr_serial(r));
1270
if (!serial_rdf) {
1271
ldns_rr_free(soa);
1272
return LDNS_STATUS_ERR;
1273
} else ldns_rr_push_rdf(soa, serial_rdf);
1274
refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1275
if (!refresh_rdf) {
1276
ldns_rr_free(soa);
1277
return LDNS_STATUS_ERR;
1278
} else ldns_rr_push_rdf(soa, refresh_rdf);
1279
retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1280
if (!retry_rdf) {
1281
ldns_rr_free(soa);
1282
return LDNS_STATUS_ERR;
1283
} else ldns_rr_push_rdf(soa, retry_rdf);
1284
expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1285
if (!expire_rdf) {
1286
ldns_rr_free(soa);
1287
return LDNS_STATUS_ERR;
1288
} else ldns_rr_push_rdf(soa, expire_rdf);
1289
minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1290
if (!minimum_rdf) {
1291
ldns_rr_free(soa);
1292
return LDNS_STATUS_ERR;
1293
} else ldns_rr_push_rdf(soa, minimum_rdf);
1294
1295
*query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name),
1296
c, flags, soa);
1297
} else {
1298
*query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
1299
}
1300
if (!*query_pkt) {
1301
ldns_rr_free(soa);
1302
return LDNS_STATUS_ERR;
1303
}
1304
1305
/* set DO bit if necessary */
1306
if (ldns_resolver_dnssec(r)) {
1307
if (ldns_resolver_edns_udp_size(r) == 0) {
1308
ldns_resolver_set_edns_udp_size(r, 4096);
1309
}
1310
ldns_pkt_set_edns_do(*query_pkt, true);
1311
if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) {
1312
ldns_pkt_set_cd(*query_pkt, true);
1313
}
1314
}
1315
1316
/* transfer the udp_edns_size from the resolver to the packet */
1317
if (ldns_resolver_edns_udp_size(r) != 0) {
1318
ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r));
1319
}
1320
1321
/* set the timestamp */
1322
now.tv_sec = time(NULL);
1323
now.tv_usec = 0;
1324
ldns_pkt_set_timestamp(*query_pkt, now);
1325
1326
1327
if (ldns_resolver_debug(r)) {
1328
ldns_pkt_print(stdout, *query_pkt);
1329
}
1330
1331
/* only set the id if it is not set yet */
1332
if (ldns_pkt_id(*query_pkt) == 0) {
1333
ldns_pkt_set_random_id(*query_pkt);
1334
}
1335
1336
return LDNS_STATUS_OK;
1337
}
1338
1339
ldns_status
1340
ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
1341
ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1342
{
1343
ldns_pkt *query_pkt;
1344
ldns_pkt *answer_pkt;
1345
ldns_status status;
1346
1347
assert(r != NULL);
1348
assert(name != NULL);
1349
1350
answer_pkt = NULL;
1351
1352
/* do all the preprocessing here, then fire of an query to
1353
* the network */
1354
1355
if (0 == t) {
1356
t= LDNS_RR_TYPE_A;
1357
}
1358
if (0 == c) {
1359
c= LDNS_RR_CLASS_IN;
1360
}
1361
if (0 == ldns_resolver_nameserver_count(r)) {
1362
return LDNS_STATUS_RES_NO_NS;
1363
}
1364
if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
1365
return LDNS_STATUS_RES_QUERY;
1366
}
1367
1368
status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name,
1369
t, c, flags);
1370
if (status != LDNS_STATUS_OK) {
1371
return status;
1372
}
1373
1374
/* if tsig values are set, tsign it */
1375
/* TODO: make last 3 arguments optional too? maybe make complete
1376
rr instead of separate values in resolver (and packet)
1377
Jelte
1378
should this go in pkt_prepare?
1379
*/
1380
if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) {
1381
#ifdef HAVE_SSL
1382
status = ldns_pkt_tsig_sign(query_pkt,
1383
ldns_resolver_tsig_keyname(r),
1384
ldns_resolver_tsig_keydata(r),
1385
300, ldns_resolver_tsig_algorithm(r), NULL);
1386
if (status != LDNS_STATUS_OK) {
1387
ldns_pkt_free(query_pkt);
1388
return LDNS_STATUS_CRYPTO_TSIG_ERR;
1389
}
1390
#else
1391
ldns_pkt_free(query_pkt);
1392
return LDNS_STATUS_CRYPTO_TSIG_ERR;
1393
#endif /* HAVE_SSL */
1394
}
1395
1396
status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
1397
ldns_pkt_free(query_pkt);
1398
1399
/* allows answer to be NULL when not interested in return value */
1400
if (answer) {
1401
*answer = answer_pkt;
1402
}
1403
return status;
1404
}
1405
1406
ldns_rr *
1407
ldns_axfr_next(ldns_resolver *resolver)
1408
{
1409
ldns_rr *cur_rr;
1410
uint8_t *packet_wire;
1411
size_t packet_wire_size;
1412
ldns_status status;
1413
1414
/* check if start() has been called */
1415
if (!resolver || resolver->_socket == -1) {
1416
return NULL;
1417
}
1418
1419
if (resolver->_cur_axfr_pkt) {
1420
if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
1421
ldns_pkt_free(resolver->_cur_axfr_pkt);
1422
resolver->_cur_axfr_pkt = NULL;
1423
return ldns_axfr_next(resolver);
1424
}
1425
cur_rr = ldns_rr_clone(ldns_rr_list_rr(
1426
ldns_pkt_answer(resolver->_cur_axfr_pkt),
1427
resolver->_axfr_i));
1428
resolver->_axfr_i++;
1429
if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
1430
resolver->_axfr_soa_count++;
1431
if (resolver->_axfr_soa_count >= 2) {
1432
1433
close_socket(resolver->_socket);
1434
1435
ldns_pkt_free(resolver->_cur_axfr_pkt);
1436
resolver->_cur_axfr_pkt = NULL;
1437
}
1438
}
1439
return cur_rr;
1440
} else {
1441
packet_wire = ldns_tcp_read_wire_timeout(resolver->_socket, &packet_wire_size, resolver->_timeout);
1442
if(!packet_wire)
1443
return NULL;
1444
1445
status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
1446
packet_wire_size);
1447
LDNS_FREE(packet_wire);
1448
1449
resolver->_axfr_i = 0;
1450
if (status != LDNS_STATUS_OK) {
1451
/* TODO: make status return type of this function (...api change) */
1452
#ifdef STDERR_MSGS
1453
fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
1454
#endif
1455
1456
/* we must now also close the socket, otherwise subsequent uses of the
1457
same resolver structure will fail because the link is still open or
1458
in an undefined state */
1459
1460
close_socket(resolver->_socket);
1461
1462
return NULL;
1463
} else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
1464
#ifdef STDERR_MSGS
1465
ldns_lookup_table *rcode = ldns_lookup_by_id(
1466
ldns_rcodes,(int) ldns_pkt_get_rcode(
1467
resolver->_cur_axfr_pkt));
1468
if (rcode) {
1469
fprintf(stderr, "Error in AXFR: %s\n",
1470
rcode->name);
1471
} else {
1472
fprintf(stderr, "Error in AXFR: %d\n",
1473
(int) ldns_pkt_get_rcode(
1474
resolver->_cur_axfr_pkt));
1475
}
1476
#endif
1477
1478
/* we must now also close the socket, otherwise subsequent uses of the
1479
same resolver structure will fail because the link is still open or
1480
in an undefined state */
1481
1482
close_socket(resolver->_socket);
1483
1484
return NULL;
1485
} else {
1486
return ldns_axfr_next(resolver);
1487
}
1488
1489
}
1490
1491
}
1492
1493
/* this function is needed to abort a transfer that is in progress;
1494
* without it an aborted transfer will lead to the AXFR code in the
1495
* library staying in an indetermined state because the socket for the
1496
* AXFR is never closed
1497
*/
1498
void
1499
ldns_axfr_abort(ldns_resolver *resolver)
1500
{
1501
/* Only abort if an actual AXFR is in progress */
1502
if (resolver->_socket != -1)
1503
{
1504
#ifndef USE_WINSOCK
1505
close(resolver->_socket);
1506
#else
1507
closesocket(resolver->_socket);
1508
#endif
1509
resolver->_socket = -1;
1510
}
1511
}
1512
1513
bool
1514
ldns_axfr_complete(const ldns_resolver *res)
1515
{
1516
/* complete when soa count is 2? */
1517
return res->_axfr_soa_count == 2;
1518
}
1519
1520
ldns_pkt *
1521
ldns_axfr_last_pkt(const ldns_resolver *res)
1522
{
1523
return res->_cur_axfr_pkt;
1524
}
1525
1526
void
1527
ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial)
1528
{
1529
r->_serial = serial;
1530
}
1531
1532
uint32_t
1533
ldns_resolver_get_ixfr_serial(const ldns_resolver *res)
1534
{
1535
return res->_serial;
1536
}
1537
1538
1539
/* random isn't really that good */
1540
void
1541
ldns_resolver_nameservers_randomize(ldns_resolver *r)
1542
{
1543
uint16_t i, j;
1544
ldns_rdf **ns, *tmpns;
1545
size_t *rtt, tmprtt;
1546
1547
/* should I check for ldns_resolver_random?? */
1548
assert(r != NULL);
1549
1550
ns = ldns_resolver_nameservers(r);
1551
rtt = ldns_resolver_rtt(r);
1552
for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
1553
j = ldns_get_random() % ldns_resolver_nameserver_count(r);
1554
tmpns = ns[i];
1555
ns[i] = ns[j];
1556
ns[j] = tmpns;
1557
tmprtt = rtt[i];
1558
rtt[i] = rtt[j];
1559
rtt[j] = tmprtt;
1560
}
1561
ldns_resolver_set_nameservers(r, ns);
1562
}
1563
1564
1565