From: Wouter Wijngaards Date: Tue, 5 Jun 2007 12:54:43 +0000 (+0000) Subject: - priming failure returns SERVFAIL. X-Git-Tag: release-0.4~96 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=523c1bdb064f0e5cd84648f289d1525db1f844b6;p=thirdparty%2Funbound.git - priming failure returns SERVFAIL. - priming gives LAME result, returns SERVFAIL. - debug routine to print dns_msg as handled by iterator. - memleak in config file stubs fixup. git-svn-id: file:///svn/unbound/trunk@370 be551aaa-1e26-0410-a405-d3ace91eadb9 --- diff --git a/daemon/worker.c b/daemon/worker.c index c8272908d..d9e74f805 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -125,18 +125,20 @@ qstate_free(struct worker* worker, struct module_qstate* qstate) { if(!qstate) return; - while(qstate->subquery_first) { - /* put subqueries on slumber list */ - struct module_qstate* s = qstate->subquery_first; - module_subreq_remove(&qstate->subquery_first, s); - s->parent = NULL; - s->work_info = NULL; - s->subquery_next = worker->slumber_list; - s->subquery_prev = NULL; - worker->slumber_list = s; - } - verbose(VERB_ALGO, "worker: slumber list has %d entries", - module_subreq_num(worker->slumber_list)); + if(qstate->subquery_first) { + while(qstate->subquery_first) { + /* put subqueries on slumber list */ + struct module_qstate* s = qstate->subquery_first; + module_subreq_remove(&qstate->subquery_first, s); + s->parent = NULL; + s->work_info = NULL; + s->subquery_next = worker->slumber_list; + s->subquery_prev = NULL; + worker->slumber_list = s; + } + verbose(VERB_ALGO, "worker: slumber list has %d entries", + module_subreq_num(worker->slumber_list)); + } qstate_cleanup(worker, qstate); } diff --git a/doc/Changelog b/doc/Changelog index 61436008a..ab1f4f7b8 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -3,6 +3,10 @@ - subrequests without parent store in cache and stop. - worker slumber list for ongoing promiscuous queries. - subrequest error handling. + - priming failure returns SERVFAIL. + - priming gives LAME result, returns SERVFAIL. + - debug routine to print dns_msg as handled by iterator. + - memleak in config file stubs fixup. 4 June 2007: Wouter - random selection of equally preferred nameserver targets. diff --git a/doc/TODO b/doc/TODO index d6ab8671d..3c1af63aa 100644 --- a/doc/TODO +++ b/doc/TODO @@ -23,3 +23,4 @@ o understand NSEC/NSEC3, aggressive negative caching, so that updates to NSEC/NSEC3 will result in proper negative responses. o fallback without EDNS if result is NOTIMPL, now only on FORMERR like in java. o scrubber has slow pkt_subdomain and pkt_strict_subdomain functions. +o get serverselection algorithm out of local optimum. diff --git a/iterator/iter_resptype.c b/iterator/iter_resptype.c index d12a3b77c..a61fa0a92 100644 --- a/iterator/iter_resptype.c +++ b/iterator/iter_resptype.c @@ -116,7 +116,7 @@ response_type_from_server(struct dns_msg* msg, struct query_info* request, /* Other response codes mean (so far) to throw the response away as * meaningless and move on to the next nameserver. */ - if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NOERROR) + if(FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR) return RESPONSE_TYPE_THROWAWAY; /* Note: TC bit has already been handled */ diff --git a/iterator/iterator.c b/iterator/iterator.c index 7357d912a..e84aed2b4 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -1504,10 +1504,12 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq, memset(&edns, 0, sizeof(edns)); pkt = qstate->reply->c->buffer; ldns_buffer_set_position(pkt, 0); - if(!parse_packet(pkt, prs, qstate->scratch)) + if(parse_packet(pkt, prs, qstate->scratch) != LDNS_RCODE_NOERROR) { + verbose(VERB_ALGO, "parse error on reply packet"); goto handle_it; + } /* edns is not examined, but removed from message to help cache */ - if(!parse_extract_edns(prs, &edns)) + if(parse_extract_edns(prs, &edns) != LDNS_RCODE_NOERROR) goto handle_it; /* normalize and sanitize: easy to delete items from linked lists */ @@ -1519,6 +1521,8 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq, iq->response = dns_alloc_msg(pkt, prs, qstate->region); if(!iq->response) goto handle_it; + log_dns_msg("incoming scrubbed packet", &iq->response->qinfo, + iq->response->rep); handle_it: outbound_list_remove(&iq->outlist, outbound); @@ -1544,7 +1548,7 @@ process_subq_error(struct module_qstate* qstate, struct iter_qstate* iq, } if(errinf.qtype == LDNS_RR_TYPE_NS) { /* a priming query has failed. */ - iter_handle(qstate, iq, ie, id); + (void)error_response(qstate, id, LDNS_RCODE_SERVFAIL); return; } if(errinf.qtype != LDNS_RR_TYPE_A && @@ -1576,6 +1580,8 @@ iter_operate(struct module_qstate* qstate, enum module_ev event, int id, struct iter_qstate* iq = (struct iter_qstate*)qstate->minfo[id]; verbose(VERB_ALGO, "iterator[module %d] operate: extstate:%s event:%s", id, strextstate(qstate->ext_state[id]), strmodulevent(event)); + if(iq) log_nametypeclass("for qstate", qstate->qinfo.qname, + qstate->qinfo.qtype, qstate->qinfo.qclass); if(ie->fwd_addrlen != 0) { perform_forward(qstate, event, id, outbound); return; @@ -1627,12 +1633,14 @@ iter_clear(struct module_qstate* qstate, int id) if(!qstate) return; iq = (struct iter_qstate*)qstate->minfo[id]; - if(iq->orig_qname) { + if(iq && iq->orig_qname) { /* so the correct qname gets free'd */ qstate->qinfo.qname = iq->orig_qname; qstate->qinfo.qname_len = iq->orig_qnamelen; } - outbound_list_clear(&iq->outlist); + if(iq) { + outbound_list_clear(&iq->outlist); + } qstate->minfo[id] = NULL; } diff --git a/services/outside_network.c b/services/outside_network.c index b9a8bf9b0..15fbde93d 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -989,10 +989,11 @@ static void serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c, struct comm_reply* rep) { - struct service_callback* p = sq->cblist; + struct service_callback* p = sq->cblist, *n; while(p) { + n = p->next; (void)(*p->cb)(c, p->cb_arg, error, rep); - p = p->next; + p = n; } } diff --git a/util/config_file.c b/util/config_file.c index 42fb8bf2f..cda0f8004 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -178,6 +178,7 @@ config_delete(struct config_file* cfg) free(p->name); config_delstrlist(p->hosts); config_delstrlist(p->addrs); + free(p); p = np; } } diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 5c8a43b5c..fc9b7661b 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -49,6 +49,7 @@ #include "util/data/dname.h" #include "util/region-allocator.h" #include "util/data/msgparse.h" +#include "util/data/msgencode.h" /** allocate qinfo, return 0 on error. */ static int @@ -449,7 +450,6 @@ query_info_parse(struct query_info* m, ldns_buffer* query) /* minimum size: header + \0 + qtype + qclass */ if(ldns_buffer_limit(query) < LDNS_HEADER_SIZE + 5) return 0; - log_assert(!LDNS_QR_WIRE(q)); log_assert(LDNS_OPCODE_WIRE(q) == LDNS_PACKET_QUERY); log_assert(LDNS_QDCOUNT(q) == 1); log_assert(ldns_buffer_position(query) == 0); @@ -651,3 +651,36 @@ reply_find_answer_rrset(struct query_info* qinfo, struct reply_info* rep) } return NULL; } + +void +log_dns_msg(const char* str, struct query_info* qinfo, struct reply_info* rep) +{ + /* not particularly fast but flexible, make wireformat and print */ + ldns_buffer* buf = ldns_buffer_new(65535); + struct region* region = region_create(malloc, free); + if(!reply_info_encode(qinfo, rep, 0, rep->flags, buf, 0, + region, 65535)) { + log_info("%s: log_dns_msg: out of memory", str); + } else { + ldns_status s; + ldns_pkt* pkt = NULL; + s = ldns_buffer2pkt_wire(&pkt, buf); + if(s != LDNS_STATUS_OK) { + log_info("%s: log_dns_msg: ldns parse gave: %s", + str, ldns_get_errorstr_by_id(s)); + } else { + ldns_buffer_clear(buf); + s = ldns_pkt2buffer_str(buf, pkt); + if(s != LDNS_STATUS_OK) { + log_info("%s: log_dns_msg: ldns tostr gave: %s", + str, ldns_get_errorstr_by_id(s)); + } else { + log_info("%s %s", + str, (char*)ldns_buffer_begin(buf)); + } + } + ldns_pkt_free(pkt); + } + ldns_buffer_free(buf); + region_destroy(region); +} diff --git a/util/data/msgreply.h b/util/data/msgreply.h index 075180469..4af25c2d3 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -300,4 +300,13 @@ struct reply_info* reply_info_copy(struct reply_info* rep, struct ub_packed_rrset_key* reply_find_answer_rrset(struct query_info* qinfo, struct reply_info* rep); +/** + * Debug send the query info and reply info to the log in readable form. + * @param str: descriptive string printed with packet content. + * @param qinfo: query section. + * @param rep: rest of message. + */ +void log_dns_msg(const char* str, struct query_info* qinfo, + struct reply_info* rep); + #endif /* UTIL_DATA_MSGREPLY_H */