1 /* 2 * answer.c -- manipulating query answers and encoding them. 3 * 4 * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #include <config.h> 11 12 #include <string.h> 13 14 #include "answer.h" 15 #include "packet.h" 16 #include "query.h" 17 18 void 19 answer_init(answer_type *answer) 20 { 21 answer->rrset_count = 0; 22 } 23 24 int 25 answer_add_rrset(answer_type *answer, rr_section_type section, 26 domain_type *domain, rrset_type *rrset) 27 { 28 size_t i; 29 30 assert(section >= ANSWER_SECTION && section < RR_SECTION_COUNT); 31 assert(domain); 32 assert(rrset); 33 34 /* Don't add an RRset multiple times. */ 35 for (i = 0; i < answer->rrset_count; ++i) { 36 if (answer->rrsets[i] == rrset) { 37 if (section < answer->section[i]) { 38 answer->section[i] = section; 39 return 1; 40 } else { 41 return 0; 42 } 43 } 44 } 45 46 if (answer->rrset_count >= MAXRRSPP) { 47 /* XXX: Generate warning/error? */ 48 return 0; 49 } 50 51 answer->section[answer->rrset_count] = section; 52 answer->domains[answer->rrset_count] = domain; 53 answer->rrsets[answer->rrset_count] = rrset; 54 ++answer->rrset_count; 55 56 return 1; 57 } 58 59 void 60 encode_answer(query_type *q, const answer_type *answer) 61 { 62 uint16_t counts[RR_SECTION_COUNT]; 63 rr_section_type section; 64 size_t i; 65 66 for (section = ANSWER_SECTION; section < RR_SECTION_COUNT; ++section) { 67 counts[section] = 0; 68 } 69 70 for (section = ANSWER_SECTION; 71 !TC(q->packet) && section < RR_SECTION_COUNT; 72 ++section) 73 { 74 for (i = 0; !TC(q->packet) && i < answer->rrset_count; ++i) { 75 if (answer->section[i] == section) { 76 counts[section] += packet_encode_rrset( 77 q, 78 answer->domains[i], 79 answer->rrsets[i], 80 section); 81 } 82 } 83 } 84 85 ANCOUNT_SET(q->packet, counts[ANSWER_SECTION]); 86 NSCOUNT_SET(q->packet, counts[AUTHORITY_SECTION]); 87 ARCOUNT_SET(q->packet, 88 counts[ADDITIONAL_A_SECTION] 89 + counts[ADDITIONAL_AAAA_SECTION] 90 + counts[ADDITIONAL_OTHER_SECTION]); 91 } 92