iterator.c (275852) | iterator.c (276605) |
---|---|
1/* 2 * iterator/iterator.c - iterative resolver DNS query response module 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 240 unchanged lines hidden (view full) --- 249 * @return: 0 for use by caller, to make notation easy, like: 250 * return error_response(..). 251 */ 252static int 253error_response_cache(struct module_qstate* qstate, int id, int rcode) 254{ 255 /* store in cache */ 256 struct reply_info err; | 1/* 2 * iterator/iterator.c - iterative resolver DNS query response module 3 * 4 * Copyright (c) 2007, NLnet Labs. All rights reserved. 5 * 6 * This software is open source. 7 * 8 * Redistribution and use in source and binary forms, with or without --- 240 unchanged lines hidden (view full) --- 249 * @return: 0 for use by caller, to make notation easy, like: 250 * return error_response(..). 251 */ 252static int 253error_response_cache(struct module_qstate* qstate, int id, int rcode) 254{ 255 /* store in cache */ 256 struct reply_info err; |
257 if(qstate->prefetch_leeway > NORR_TTL) { 258 verbose(VERB_ALGO, "error response for prefetch in cache"); 259 /* attempt to adjust the cache entry prefetch */ 260 if(dns_cache_prefetch_adjust(qstate->env, &qstate->qinfo, 261 NORR_TTL, qstate->query_flags)) 262 return error_response(qstate, id, rcode); 263 /* if that fails (not in cache), fall through to store err */ 264 } |
|
257 memset(&err, 0, sizeof(err)); 258 err.flags = (uint16_t)(BIT_QR | BIT_RA); 259 FLAGS_SET_RCODE(err.flags, rcode); 260 err.qdcount = 1; 261 err.ttl = NORR_TTL; 262 err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl); 263 /* do not waste time trying to validate this servfail */ 264 err.security = sec_status_indeterminate; 265 verbose(VERB_ALGO, "store error response in message cache"); | 265 memset(&err, 0, sizeof(err)); 266 err.flags = (uint16_t)(BIT_QR | BIT_RA); 267 FLAGS_SET_RCODE(err.flags, rcode); 268 err.qdcount = 1; 269 err.ttl = NORR_TTL; 270 err.prefetch_ttl = PREFETCH_TTL_CALC(err.ttl); 271 /* do not waste time trying to validate this servfail */ 272 err.security = sec_status_indeterminate; 273 verbose(VERB_ALGO, "store error response in message cache"); |
266 iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL); | 274 iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL, 275 qstate->query_flags); |
267 return error_response(qstate, id, rcode); 268} 269 270/** check if prepend item is duplicate item */ 271static int 272prepend_is_duplicate(struct ub_packed_rrset_key** sets, size_t to, 273 struct ub_packed_rrset_key* dup) 274{ --- 219 unchanged lines hidden (view full) --- 494 struct iter_qstate* iq, enum iter_state initial_state, 495 enum iter_state finalstate, struct module_qstate** subq_ret, int v) 496{ 497 struct module_qstate* subq = NULL; 498 struct iter_qstate* subiq = NULL; 499 uint16_t qflags = 0; /* OPCODE QUERY, no flags */ 500 struct query_info qinf; 501 int prime = (finalstate == PRIME_RESP_STATE)?1:0; | 276 return error_response(qstate, id, rcode); 277} 278 279/** check if prepend item is duplicate item */ 280static int 281prepend_is_duplicate(struct ub_packed_rrset_key** sets, size_t to, 282 struct ub_packed_rrset_key* dup) 283{ --- 219 unchanged lines hidden (view full) --- 503 struct iter_qstate* iq, enum iter_state initial_state, 504 enum iter_state finalstate, struct module_qstate** subq_ret, int v) 505{ 506 struct module_qstate* subq = NULL; 507 struct iter_qstate* subiq = NULL; 508 uint16_t qflags = 0; /* OPCODE QUERY, no flags */ 509 struct query_info qinf; 510 int prime = (finalstate == PRIME_RESP_STATE)?1:0; |
511 int valrec = 0; |
|
502 qinf.qname = qname; 503 qinf.qname_len = qnamelen; 504 qinf.qtype = qtype; 505 qinf.qclass = qclass; 506 507 /* RD should be set only when sending the query back through the INIT 508 * state. */ 509 if(initial_state == INIT_REQUEST_STATE) 510 qflags |= BIT_RD; 511 /* We set the CD flag so we can send this through the "head" of 512 * the resolution chain, which might have a validator. We are 513 * uninterested in validating things not on the direct resolution 514 * path. */ | 512 qinf.qname = qname; 513 qinf.qname_len = qnamelen; 514 qinf.qtype = qtype; 515 qinf.qclass = qclass; 516 517 /* RD should be set only when sending the query back through the INIT 518 * state. */ 519 if(initial_state == INIT_REQUEST_STATE) 520 qflags |= BIT_RD; 521 /* We set the CD flag so we can send this through the "head" of 522 * the resolution chain, which might have a validator. We are 523 * uninterested in validating things not on the direct resolution 524 * path. */ |
515 if(!v) | 525 if(!v) { |
516 qflags |= BIT_CD; | 526 qflags |= BIT_CD; |
527 valrec = 1; 528 } |
|
517 518 /* attach subquery, lookup existing or make a new one */ 519 fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); | 529 530 /* attach subquery, lookup existing or make a new one */ 531 fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); |
520 if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, &subq)) { | 532 if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, valrec, 533 &subq)) { |
521 return 0; 522 } 523 *subq_ret = subq; 524 if(subq) { 525 /* initialise the new subquery */ 526 subq->curmod = id; 527 subq->ext_state[id] = module_state_initial; 528 subq->minfo[id] = regional_alloc(subq->region, --- 421 unchanged lines hidden (view full) --- 950 if(qstate->blacklist) { 951 /* if cache, or anything else, was blacklisted then 952 * getting older results from cache is a bad idea, no cache */ 953 verbose(VERB_ALGO, "cache blacklisted, going to the network"); 954 msg = NULL; 955 } else { 956 msg = dns_cache_lookup(qstate->env, iq->qchase.qname, 957 iq->qchase.qname_len, iq->qchase.qtype, | 534 return 0; 535 } 536 *subq_ret = subq; 537 if(subq) { 538 /* initialise the new subquery */ 539 subq->curmod = id; 540 subq->ext_state[id] = module_state_initial; 541 subq->minfo[id] = regional_alloc(subq->region, --- 421 unchanged lines hidden (view full) --- 963 if(qstate->blacklist) { 964 /* if cache, or anything else, was blacklisted then 965 * getting older results from cache is a bad idea, no cache */ 966 verbose(VERB_ALGO, "cache blacklisted, going to the network"); 967 msg = NULL; 968 } else { 969 msg = dns_cache_lookup(qstate->env, iq->qchase.qname, 970 iq->qchase.qname_len, iq->qchase.qtype, |
958 iq->qchase.qclass, qstate->region, qstate->env->scratch); | 971 iq->qchase.qclass, qstate->query_flags, 972 qstate->region, qstate->env->scratch); |
959 if(!msg && qstate->env->neg_cache) { 960 /* lookup in negative cache; may result in 961 * NOERROR/NODATA or NXDOMAIN answers that need validation */ 962 msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase, 963 qstate->region, qstate->env->rrset_cache, 964 qstate->env->scratch_buffer, 965 *qstate->env->now, 1/*add SOA*/, NULL); 966 } --- 916 unchanged lines hidden (view full) --- 1883 iq->dnssec_expected?"expected": "not expected", 1884 iq->dnssec_lame_query?" but lame_query anyway": ""); 1885 } 1886 fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query)); 1887 outq = (*qstate->env->send_query)( 1888 iq->qchase.qname, iq->qchase.qname_len, 1889 iq->qchase.qtype, iq->qchase.qclass, 1890 iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), EDNS_DO|BIT_CD, | 973 if(!msg && qstate->env->neg_cache) { 974 /* lookup in negative cache; may result in 975 * NOERROR/NODATA or NXDOMAIN answers that need validation */ 976 msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase, 977 qstate->region, qstate->env->rrset_cache, 978 qstate->env->scratch_buffer, 979 *qstate->env->now, 1/*add SOA*/, NULL); 980 } --- 916 unchanged lines hidden (view full) --- 1897 iq->dnssec_expected?"expected": "not expected", 1898 iq->dnssec_lame_query?" but lame_query anyway": ""); 1899 } 1900 fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query)); 1901 outq = (*qstate->env->send_query)( 1902 iq->qchase.qname, iq->qchase.qname_len, 1903 iq->qchase.qtype, iq->qchase.qclass, 1904 iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), EDNS_DO|BIT_CD, |
1891 iq->dnssec_expected, &target->addr, target->addrlen, 1892 iq->dp->name, iq->dp->namelen, qstate); | 1905 iq->dnssec_expected, iq->caps_fallback, &target->addr, 1906 target->addrlen, iq->dp->name, iq->dp->namelen, qstate); |
1893 if(!outq) { 1894 log_addr(VERB_DETAIL, "error sending query to auth server", 1895 &target->addr, target->addrlen); 1896 return next_state(iq, QUERYTARGETS_STATE); 1897 } 1898 outbound_list_insert(&iq->outlist, outq); 1899 iq->num_current_queries++; 1900 iq->sent_count++; --- 119 unchanged lines hidden (view full) --- 2020 qstate->env->detach_subs)); 2021 (*qstate->env->detach_subs)(qstate); 2022 iq->num_target_queries = 0; 2023 return processDSNSFind(qstate, iq, id); 2024 } 2025 iter_dns_store(qstate->env, &iq->response->qinfo, 2026 iq->response->rep, 0, qstate->prefetch_leeway, 2027 iq->dp&&iq->dp->has_parent_side_NS, | 1907 if(!outq) { 1908 log_addr(VERB_DETAIL, "error sending query to auth server", 1909 &target->addr, target->addrlen); 1910 return next_state(iq, QUERYTARGETS_STATE); 1911 } 1912 outbound_list_insert(&iq->outlist, outq); 1913 iq->num_current_queries++; 1914 iq->sent_count++; --- 119 unchanged lines hidden (view full) --- 2034 qstate->env->detach_subs)); 2035 (*qstate->env->detach_subs)(qstate); 2036 iq->num_target_queries = 0; 2037 return processDSNSFind(qstate, iq, id); 2038 } 2039 iter_dns_store(qstate->env, &iq->response->qinfo, 2040 iq->response->rep, 0, qstate->prefetch_leeway, 2041 iq->dp&&iq->dp->has_parent_side_NS, |
2028 qstate->region); | 2042 qstate->region, qstate->query_flags); |
2029 /* close down outstanding requests to be discarded */ 2030 outbound_list_clear(&iq->outlist); 2031 iq->num_current_queries = 0; 2032 fptr_ok(fptr_whitelist_modenv_detach_subs( 2033 qstate->env->detach_subs)); 2034 (*qstate->env->detach_subs)(qstate); 2035 iq->num_target_queries = 0; 2036 if(qstate->reply) --- 21 unchanged lines hidden (view full) --- 2058 || reply_find_rrset_section_an(iq->response->rep, 2059 iq->qchase.qname, iq->qchase.qname_len, 2060 LDNS_RR_TYPE_NS, iq->qchase.qclass) 2061 ) 2062 )) { 2063 /* Store the referral under the current query */ 2064 /* no prefetch-leeway, since its not the answer */ 2065 iter_dns_store(qstate->env, &iq->response->qinfo, | 2043 /* close down outstanding requests to be discarded */ 2044 outbound_list_clear(&iq->outlist); 2045 iq->num_current_queries = 0; 2046 fptr_ok(fptr_whitelist_modenv_detach_subs( 2047 qstate->env->detach_subs)); 2048 (*qstate->env->detach_subs)(qstate); 2049 iq->num_target_queries = 0; 2050 if(qstate->reply) --- 21 unchanged lines hidden (view full) --- 2072 || reply_find_rrset_section_an(iq->response->rep, 2073 iq->qchase.qname, iq->qchase.qname_len, 2074 LDNS_RR_TYPE_NS, iq->qchase.qclass) 2075 ) 2076 )) { 2077 /* Store the referral under the current query */ 2078 /* no prefetch-leeway, since its not the answer */ 2079 iter_dns_store(qstate->env, &iq->response->qinfo, |
2066 iq->response->rep, 1, 0, 0, NULL); | 2080 iq->response->rep, 1, 0, 0, NULL, 0); |
2067 if(iq->store_parent_NS) 2068 iter_store_parentside_NS(qstate->env, 2069 iq->response->rep); 2070 if(qstate->env->neg_cache) 2071 val_neg_addreferral(qstate->env->neg_cache, 2072 iq->response->rep, iq->dp->name); 2073 } 2074 /* store parent-side-in-zone-glue, if directly queried for */ --- 82 unchanged lines hidden (view full) --- 2157 &sname, &snamelen)) 2158 return error_response(qstate, id, LDNS_RCODE_SERVFAIL); 2159 /* cache the CNAME response under the current query */ 2160 /* NOTE : set referral=1, so that rrsets get stored but not 2161 * the partial query answer (CNAME only). */ 2162 /* prefetchleeway applied because this updates answer parts */ 2163 iter_dns_store(qstate->env, &iq->response->qinfo, 2164 iq->response->rep, 1, qstate->prefetch_leeway, | 2081 if(iq->store_parent_NS) 2082 iter_store_parentside_NS(qstate->env, 2083 iq->response->rep); 2084 if(qstate->env->neg_cache) 2085 val_neg_addreferral(qstate->env->neg_cache, 2086 iq->response->rep, iq->dp->name); 2087 } 2088 /* store parent-side-in-zone-glue, if directly queried for */ --- 82 unchanged lines hidden (view full) --- 2171 &sname, &snamelen)) 2172 return error_response(qstate, id, LDNS_RCODE_SERVFAIL); 2173 /* cache the CNAME response under the current query */ 2174 /* NOTE : set referral=1, so that rrsets get stored but not 2175 * the partial query answer (CNAME only). */ 2176 /* prefetchleeway applied because this updates answer parts */ 2177 iter_dns_store(qstate->env, &iq->response->qinfo, 2178 iq->response->rep, 1, qstate->prefetch_leeway, |
2165 iq->dp&&iq->dp->has_parent_side_NS, NULL); | 2179 iq->dp&&iq->dp->has_parent_side_NS, NULL, 2180 qstate->query_flags); |
2166 /* set the current request's qname to the new value. */ 2167 iq->qchase.qname = sname; 2168 iq->qchase.qname_len = snamelen; 2169 /* Clear the query state, since this is a query restart. */ 2170 iq->deleg_msg = NULL; 2171 iq->dp = NULL; 2172 iq->dsns_point = NULL; 2173 /* Note the query restart. */ --- 64 unchanged lines hidden (view full) --- 2238 2239 /* LAME, THROWAWAY and "unknown" all end up here. 2240 * Recycle to the QUERYTARGETS state to hopefully try a 2241 * different target. */ 2242 return next_state(iq, QUERYTARGETS_STATE); 2243} 2244 2245/** | 2181 /* set the current request's qname to the new value. */ 2182 iq->qchase.qname = sname; 2183 iq->qchase.qname_len = snamelen; 2184 /* Clear the query state, since this is a query restart. */ 2185 iq->deleg_msg = NULL; 2186 iq->dp = NULL; 2187 iq->dsns_point = NULL; 2188 /* Note the query restart. */ --- 64 unchanged lines hidden (view full) --- 2253 2254 /* LAME, THROWAWAY and "unknown" all end up here. 2255 * Recycle to the QUERYTARGETS state to hopefully try a 2256 * different target. */ 2257 return next_state(iq, QUERYTARGETS_STATE); 2258} 2259 2260/** |
2246 * Return priming query results to interestes super querystates. | 2261 * Return priming query results to interested super querystates. |
2247 * 2248 * Sets the delegation point and delegation message (not nonRD queries). 2249 * This is a callback from walk_supers. 2250 * 2251 * @param qstate: priming query state that finished. 2252 * @param id: module id. 2253 * @param forq: the qstate for which priming has been done. 2254 */ --- 414 unchanged lines hidden (view full) --- 2669 iq->response->rep->security = sec_status_unchecked; 2670 /* store message with the finished prepended items, 2671 * but only if we did recursion. The nonrecursion referral 2672 * from cache does not need to be stored in the msg cache. */ 2673 if(qstate->query_flags&BIT_RD) { 2674 iter_dns_store(qstate->env, &qstate->qinfo, 2675 iq->response->rep, 0, qstate->prefetch_leeway, 2676 iq->dp&&iq->dp->has_parent_side_NS, | 2262 * 2263 * Sets the delegation point and delegation message (not nonRD queries). 2264 * This is a callback from walk_supers. 2265 * 2266 * @param qstate: priming query state that finished. 2267 * @param id: module id. 2268 * @param forq: the qstate for which priming has been done. 2269 */ --- 414 unchanged lines hidden (view full) --- 2684 iq->response->rep->security = sec_status_unchecked; 2685 /* store message with the finished prepended items, 2686 * but only if we did recursion. The nonrecursion referral 2687 * from cache does not need to be stored in the msg cache. */ 2688 if(qstate->query_flags&BIT_RD) { 2689 iter_dns_store(qstate->env, &qstate->qinfo, 2690 iq->response->rep, 0, qstate->prefetch_leeway, 2691 iq->dp&&iq->dp->has_parent_side_NS, |
2677 qstate->region); | 2692 qstate->region, qstate->query_flags); |
2678 } 2679 } 2680 qstate->return_rcode = LDNS_RCODE_NOERROR; 2681 qstate->return_msg = iq->response; 2682 return 0; 2683} 2684 2685/* --- 108 unchanged lines hidden (view full) --- 2794 struct msg_parse* prs; 2795 struct edns_data edns; 2796 sldns_buffer* pkt; 2797 2798 verbose(VERB_ALGO, "process_response: new external response event"); 2799 iq->response = NULL; 2800 iq->state = QUERY_RESP_STATE; 2801 if(event == module_event_noreply || event == module_event_error) { | 2693 } 2694 } 2695 qstate->return_rcode = LDNS_RCODE_NOERROR; 2696 qstate->return_msg = iq->response; 2697 return 0; 2698} 2699 2700/* --- 108 unchanged lines hidden (view full) --- 2809 struct msg_parse* prs; 2810 struct edns_data edns; 2811 sldns_buffer* pkt; 2812 2813 verbose(VERB_ALGO, "process_response: new external response event"); 2814 iq->response = NULL; 2815 iq->state = QUERY_RESP_STATE; 2816 if(event == module_event_noreply || event == module_event_error) { |
2817 if(event == module_event_noreply && iq->sent_count >= 3 && 2818 qstate->env->cfg->use_caps_bits_for_id && 2819 !iq->caps_fallback) { 2820 /* start fallback */ 2821 iq->caps_fallback = 1; 2822 iq->caps_server = 0; 2823 iq->caps_reply = NULL; 2824 iq->state = QUERYTARGETS_STATE; 2825 iq->num_current_queries--; 2826 /* need fresh attempts for the 0x20 fallback, if 2827 * that was the cause for the failure */ 2828 iter_dec_attempts(iq->dp, 3); 2829 verbose(VERB_DETAIL, "Capsforid: timeouts, starting fallback"); 2830 goto handle_it; 2831 } |
|
2802 goto handle_it; 2803 } 2804 if( (event != module_event_reply && event != module_event_capsfail) 2805 || !qstate->reply) { 2806 log_err("Bad event combined with response"); 2807 outbound_list_remove(&iq->outlist, outbound); 2808 (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL); 2809 return; --- 32 unchanged lines hidden (view full) --- 2842 goto handle_it; 2843 log_query_info(VERB_DETAIL, "response for", &qstate->qinfo); 2844 log_name_addr(VERB_DETAIL, "reply from", iq->dp->name, 2845 &qstate->reply->addr, qstate->reply->addrlen); 2846 if(verbosity >= VERB_ALGO) 2847 log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo, 2848 iq->response->rep); 2849 | 2832 goto handle_it; 2833 } 2834 if( (event != module_event_reply && event != module_event_capsfail) 2835 || !qstate->reply) { 2836 log_err("Bad event combined with response"); 2837 outbound_list_remove(&iq->outlist, outbound); 2838 (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL); 2839 return; --- 32 unchanged lines hidden (view full) --- 2872 goto handle_it; 2873 log_query_info(VERB_DETAIL, "response for", &qstate->qinfo); 2874 log_name_addr(VERB_DETAIL, "reply from", iq->dp->name, 2875 &qstate->reply->addr, qstate->reply->addrlen); 2876 if(verbosity >= VERB_ALGO) 2877 log_dns_msg("incoming scrubbed packet:", &iq->response->qinfo, 2878 iq->response->rep); 2879 |
2850 if(event == module_event_capsfail) { | 2880 if(event == module_event_capsfail || iq->caps_fallback) { |
2851 if(!iq->caps_fallback) { 2852 /* start fallback */ 2853 iq->caps_fallback = 1; 2854 iq->caps_server = 0; 2855 iq->caps_reply = iq->response->rep; 2856 iq->state = QUERYTARGETS_STATE; 2857 iq->num_current_queries--; 2858 verbose(VERB_DETAIL, "Capsforid: starting fallback"); 2859 goto handle_it; 2860 } else { 2861 /* check if reply is the same, otherwise, fail */ | 2881 if(!iq->caps_fallback) { 2882 /* start fallback */ 2883 iq->caps_fallback = 1; 2884 iq->caps_server = 0; 2885 iq->caps_reply = iq->response->rep; 2886 iq->state = QUERYTARGETS_STATE; 2887 iq->num_current_queries--; 2888 verbose(VERB_DETAIL, "Capsforid: starting fallback"); 2889 goto handle_it; 2890 } else { 2891 /* check if reply is the same, otherwise, fail */ |
2862 if(!reply_equal(iq->response->rep, iq->caps_reply, | 2892 if(!iq->caps_reply) { 2893 iq->caps_reply = iq->response->rep; 2894 iq->caps_server = -1; /*become zero at ++, 2895 so that we start the full set of trials */ 2896 } else if(!reply_equal(iq->response->rep, iq->caps_reply, |
2863 qstate->env->scratch)) { 2864 verbose(VERB_DETAIL, "Capsforid fallback: " 2865 "getting different replies, failed"); 2866 outbound_list_remove(&iq->outlist, outbound); 2867 (void)error_response(qstate, id, 2868 LDNS_RCODE_SERVFAIL); 2869 return; 2870 } --- 143 unchanged lines hidden --- | 2897 qstate->env->scratch)) { 2898 verbose(VERB_DETAIL, "Capsforid fallback: " 2899 "getting different replies, failed"); 2900 outbound_list_remove(&iq->outlist, outbound); 2901 (void)error_response(qstate, id, 2902 LDNS_RCODE_SERVFAIL); 2903 return; 2904 } --- 143 unchanged lines hidden --- |