int packet_encode_rrset(query_type *query, domain_type *owner, rrset_type *rrset, int section) { uint16_t i; size_t truncation_mark; uint16_t added = 0; int all_added = 1; int truncate_rrset = (section == ANSWER_SECTION || section == AUTHORITY_SECTION); rrset_type *rrsig; assert(rrset->rr_count > 0); truncation_mark = buffer_position(query->packet); for (i = 0; i < rrset->rr_count; ++i) { if (packet_encode_rr(query, owner, &rrset->rrs[i])) { ++added; } else { all_added = 0; break; } } if (all_added && query->edns.dnssec_ok && zone_is_secure(rrset->zone) && rrset_rrtype(rrset) != TYPE_RRSIG && (rrsig = domain_find_rrset(owner, rrset->zone, TYPE_RRSIG))) { for (i = 0; i < rrsig->rr_count; ++i) { if (rr_rrsig_type_covered(&rrsig->rrs[i]) == rrset_rrtype(rrset)) { if (packet_encode_rr(query, owner, &rrsig->rrs[i])) { ++added; } else { all_added = 0; break; } } } } if (!all_added && truncate_rrset) { /* Truncate entire RRset and set truncate flag. */ buffer_set_position(query->packet, truncation_mark); query_clear_dname_offsets(query, truncation_mark); TC_SET(query->packet); added = 0; } return added; }
query_state_type rrl_slip(query_type* query) { /* discard half the packets, randomly */ if((random() & 0x1)) { /* set TC on the rest */ TC_SET(query->packet); ANCOUNT_SET(query->packet, 0); NSCOUNT_SET(query->packet, 0); ARCOUNT_SET(query->packet, 0); if(query->qname) /* header, type, class, qname */ buffer_set_position(query->packet, QHEADERSZ+4+query->qname->name_size); else buffer_set_position(query->packet, QHEADERSZ); return QUERY_PROCESSED; } return QUERY_DISCARDED; }