3 * Where all the hard work concerning chasing
5 * (c) 2005, 2006 NLnet Labs
7 * See the file LICENSE for the license
12 #include <ldns/ldns.h>
15 * trace down from the root to name
18 /* same naive method as in drill0.9
19 * We resolver _ALL_ the names, which is ofcourse not needed
20 * We _do_ use the local resolver to do that, so it still is
21 * fast, but it can be made to run much faster
24 do_trace(ldns_resolver
*local_res
, ldns_rdf
*name
, ldns_rr_type t
,
29 ldns_rr_list
*new_nss_a
;
30 ldns_rr_list
*new_nss_aaaa
;
31 ldns_rr_list
*final_answer
;
32 ldns_rr_list
*new_nss
;
33 ldns_rr_list
*ns_addr
;
46 res
= ldns_resolver_new();
50 ldns_resolver_free(res
);
52 error("Memory allocation failed");
57 error("Memory allocation failed");
61 /* transfer some properties of local_res to res,
62 * because they were given on the commandline */
63 ldns_resolver_set_ip6(res
,
64 ldns_resolver_ip6(local_res
));
65 ldns_resolver_set_port(res
,
66 ldns_resolver_port(local_res
));
67 ldns_resolver_set_debug(res
,
68 ldns_resolver_debug(local_res
));
69 ldns_resolver_set_dnssec(res
,
70 ldns_resolver_dnssec(local_res
));
71 ldns_resolver_set_fail(res
,
72 ldns_resolver_fail(local_res
));
73 ldns_resolver_set_usevc(res
,
74 ldns_resolver_usevc(local_res
));
75 ldns_resolver_set_random(res
,
76 ldns_resolver_random(local_res
));
77 ldns_resolver_set_recursive(res
, false);
79 /* setup the root nameserver in the new resolver */
80 status
= ldns_resolver_push_nameserver_rr_list(res
, global_dns_root
);
81 if (status
!= LDNS_STATUS_OK
) {
82 fprintf(stderr
, "Error adding root servers to resolver: %s\n", ldns_get_errorstr_by_id(status
));
83 ldns_rr_list_print(stdout
, global_dns_root
);
84 ldns_resolver_free(res
);
89 /* this must be a real query to local_res */
90 status
= ldns_resolver_send(&p
, res
, ldns_dname_new_frm_str("."), LDNS_RR_TYPE_NS
, c
, 0);
91 /* p can still be NULL */
94 if (ldns_pkt_empty(p
)) {
95 warning("No root server information received");
98 if (status
== LDNS_STATUS_OK
) {
99 if (!ldns_pkt_empty(p
)) {
100 drill_pkt_print(stdout
, local_res
, p
);
103 error("cannot use local resolver");
107 status
= ldns_resolver_send(&p
, res
, name
, t
, c
, 0);
109 while(status
== LDNS_STATUS_OK
&&
110 ldns_pkt_reply_type(p
) == LDNS_PACKET_REFERRAL
) {
113 /* some error occurred, bail out */
117 new_nss_a
= ldns_pkt_rr_list_by_type(p
,
118 LDNS_RR_TYPE_A
, LDNS_SECTION_ADDITIONAL
);
119 new_nss_aaaa
= ldns_pkt_rr_list_by_type(p
,
120 LDNS_RR_TYPE_AAAA
, LDNS_SECTION_ADDITIONAL
);
121 new_nss
= ldns_pkt_rr_list_by_type(p
,
122 LDNS_RR_TYPE_NS
, LDNS_SECTION_AUTHORITY
);
124 if (verbosity
!= -1) {
125 ldns_rr_list_print(stdout
, new_nss
);
127 /* checks itself for verbosity */
128 drill_pkt_print_footer(stdout
, local_res
, p
);
130 /* remove the old nameserver from the resolver */
131 while(ldns_resolver_pop_nameserver(res
)) { /* do it */ }
133 /* also check for new_nss emptyness */
135 if (!new_nss_aaaa
&& !new_nss_a
) {
137 * no nameserver found!!!
138 * try to resolve the names we do got
140 for(i
= 0; i
< ldns_rr_list_rr_count(new_nss
); i
++) {
141 /* get the name of the nameserver */
142 pop
= ldns_rr_rdf(ldns_rr_list_rr(new_nss
, i
), 0);
147 ldns_rr_list_print(stdout
, new_nss
);
148 ldns_rdf_print(stdout
, pop
);
149 /* retrieve it's addresses */
150 ns_addr
= ldns_rr_list_cat_clone(ns_addr
,
151 ldns_get_rr_list_addr_by_name(local_res
, pop
, c
, 0));
155 if (ldns_resolver_push_nameserver_rr_list(res
, ns_addr
) !=
157 error("Error adding new nameservers");
161 ldns_rr_list_free(ns_addr
);
163 ldns_rr_list_print(stdout
, ns_addr
);
164 error("Could not find the nameserver ip addr; abort");
170 /* add the new ones */
172 if (ldns_resolver_push_nameserver_rr_list(res
, new_nss_aaaa
) !=
174 error("adding new nameservers");
180 if (ldns_resolver_push_nameserver_rr_list(res
, new_nss_a
) !=
182 error("adding new nameservers");
188 if (loop_count
++ > 20) {
189 /* unlikely that we are doing something usefull */
190 error("Looks like we are looping");
195 status
= ldns_resolver_send(&p
, res
, name
, t
, c
, 0);
201 status
= ldns_resolver_send(&p
, res
, name
, t
, c
, 0);
207 new_nss
= ldns_pkt_authority(p
);
208 final_answer
= ldns_pkt_answer(p
);
210 if (verbosity
!= -1) {
211 ldns_rr_list_print(stdout
, final_answer
);
212 ldns_rr_list_print(stdout
, new_nss
);
215 drill_pkt_print_footer(stdout
, local_res
, p
);
222 * Chase the given rr to a known and trusted key
226 * the last argument prev_key_list, if not null, and type == DS, then the ds
227 * rr list we have must all be a ds for the keys in this list
231 do_chase(ldns_resolver
*res
,
235 ldns_rr_list
*trusted_keys
,
238 ldns_rr_list
* ATTR_UNUSED(prev_key_list
),
241 ldns_rr_list
*rrset
= NULL
;
243 ldns_rr
*orig_rr
= NULL
;
252 ldns_status tree_result
;
253 ldns_dnssec_data_chain
*chain
;
254 ldns_dnssec_trust_tree
*tree
;
256 const ldns_rr_descriptor
*descriptor
;
257 descriptor
= ldns_rr_descript(type
);
259 ldns_dname2canonical(name
);
261 pkt
= ldns_pkt_clone(pkt_o
);
263 mesg("No name to chase");
265 return LDNS_STATUS_EMPTY_LABEL
;
267 if (verbosity
!= -1) {
268 printf(";; Chasing: ");
269 ldns_rdf_print(stdout
, name
);
270 if (descriptor
&& descriptor
->_name
) {
271 printf(" %s\n", descriptor
->_name
);
273 printf(" type %d\n", type
);
277 if (!trusted_keys
|| ldns_rr_list_rr_count(trusted_keys
) < 1) {
278 warning("No trusted keys specified");
282 rrset
= ldns_pkt_rr_list_by_name_and_type(pkt
,
288 /* nothing in answer, try authority */
289 rrset
= ldns_pkt_rr_list_by_name_and_type(pkt
,
292 LDNS_SECTION_AUTHORITY
295 /* answer might be a cname, chase that first, then chase
296 cname target? (TODO) */
298 rrset
= ldns_pkt_rr_list_by_name_and_type(pkt
,
304 /* nothing in answer, try authority */
305 rrset
= ldns_pkt_rr_list_by_name_and_type(pkt
,
308 LDNS_SECTION_AUTHORITY
314 if (verbosity
>= 0) {
315 fprintf(stderr
, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_MEM_ERR
));
316 fprintf(stderr
, "\n");
318 return LDNS_STATUS_MEM_ERR
;
322 /* not found in original packet, try again */
325 pkt
= ldns_resolver_query(res
, name
, type
, c
, qflags
);
328 if (verbosity
>= 0) {
329 fprintf(stderr
, "%s", ldns_get_errorstr_by_id(LDNS_STATUS_NETWORK_ERR
));
330 fprintf(stderr
, "\n");
332 return LDNS_STATUS_NETWORK_ERR
;
334 if (verbosity
>= 5) {
335 ldns_pkt_print(stdout
, pkt
);
338 rrset
= ldns_pkt_rr_list_by_name_and_type(pkt
,
345 orig_rr
= ldns_rr_new();
347 /* if the answer had no answer section, we need to construct our own rr (for instance if
348 * the rr qe asked for doesn't exist. This rr will be destroyed when the chain is freed */
349 if (ldns_pkt_ancount(pkt
) < 1) {
350 ldns_rr_set_type(orig_rr
, type
);
351 ldns_rr_set_owner(orig_rr
, ldns_rdf_clone(name
));
353 chain
= ldns_dnssec_build_data_chain(res
, qflags
, rrset
, pkt
, ldns_rr_clone(orig_rr
));
355 /* chase the first answer */
356 chain
= ldns_dnssec_build_data_chain(res
, qflags
, rrset
, pkt
, NULL
);
359 if (verbosity
>= 4) {
360 printf("\n\nDNSSEC Data Chain:\n");
361 ldns_dnssec_data_chain_print(stdout
, chain
);
364 result
= LDNS_STATUS_OK
;
366 tree
= ldns_dnssec_derive_trust_tree(chain
, NULL
);
368 if (verbosity
>= 2) {
369 printf("\n\nDNSSEC Trust tree:\n");
370 ldns_dnssec_trust_tree_print(stdout
, tree
, 0, true);
373 if (ldns_rr_list_rr_count(trusted_keys
) > 0) {
374 tree_result
= ldns_dnssec_trust_tree_contains_keys(tree
, trusted_keys
);
376 if (tree_result
== LDNS_STATUS_DNSSEC_EXISTENCE_DENIED
) {
377 if (verbosity
>= 1) {
378 printf("Existence denied or verifiably insecure\n");
380 result
= LDNS_STATUS_OK
;
381 } else if (tree_result
!= LDNS_STATUS_OK
) {
382 if (verbosity
>= 1) {
383 printf("No trusted keys found in tree: first error was: %s\n", ldns_get_errorstr_by_id(tree_result
));
385 result
= tree_result
;
389 if (verbosity
>= 0) {
390 printf("You have not provided any trusted keys.\n");
394 ldns_rr_free(orig_rr
);
395 ldns_dnssec_trust_tree_free(tree
);
396 ldns_dnssec_data_chain_deep_free(chain
);
398 ldns_rr_list_deep_free(rrset
);
400 /* ldns_rr_free(orig_rr);*/
404 #endif /* HAVE_SSL */