diff --git a/daemon/worker.c b/daemon/worker.c index 22638002c..e6a1f4718 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -234,6 +234,11 @@ worker_handle_reply(struct comm_point* c, void* arg, int error, return 0; /* not a reply to a query. */ if(LDNS_QDCOUNT(ldns_buffer_begin(c->buffer)) > 1) return 0; /* too much in the query section */ + /* see if it is truncated */ + if(LDNS_TC_WIRE(ldns_buffer_begin(c->buffer)) && c->type == comm_udp) { + log_info("TC: truncated. retry in TCP mode."); + return 0; + } /* woohoo a reply! */ if((r=reply_info_parse(c->buffer, &w->worker->alloc, &qinf, &rep, w->worker->scratchpad, &svr_edns))!=0) { diff --git a/util/data/msgparse.c b/util/data/msgparse.c index 71b9246d1..01964477d 100644 --- a/util/data/msgparse.c +++ b/util/data/msgparse.c @@ -694,11 +694,17 @@ add_rr_to_rrset(struct rrset_parse* rrset, ldns_buffer* pkt, /* check section of rrset. */ if(rrset->section != section && type != LDNS_RR_TYPE_RRSIG && rrset->type != LDNS_RR_TYPE_RRSIG) { - /* silently drop it - it is a security problem, since + /* silently drop it - we drop the last part, since * trust in rr data depends on the section it is in. - * the less trustworthy part is discarded. */ + * the less trustworthy part is discarded. + * also the last part is more likely to be incomplete. + * RFC 2181: must put RRset only once in response. */ + /* verbose(VERB_DETAIL, "Packet contains rrset data in " "multiple sections, dropped last part."); + log_hex("packet was: ", ldns_buffer_begin(pkt), + ldns_buffer_limit(pkt)); + */ /* forwards */ if(!skip_ttl_rdata(pkt)) return LDNS_RCODE_FORMERR;