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) {
/* 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;