1 /* 2 * query.h -- manipulation with the queries 3 * 4 * Copyright (c) 2001-2011, NLnet Labs. All rights reserved. 5 * 6 * See LICENSE for the license. 7 * 8 */ 9 10 #ifndef _QUERY_H_ 11 #define _QUERY_H_ 12 13 #include <assert.h> 14 #include <string.h> 15 16 #include "namedb.h" 17 #include "nsd.h" 18 #include "packet.h" 19 #include "tsig.h" 20 21 enum query_state { 22 QUERY_PROCESSED, 23 QUERY_DISCARDED, 24 QUERY_IN_AXFR 25 }; 26 typedef enum query_state query_state_type; 27 28 /* Query as we pass it around */ 29 typedef struct query query_type; 30 struct query { 31 /* 32 * Memory region freed whenever the query is reset. 33 */ 34 region_type *region; 35 36 /* 37 * The address the query was received from. 38 */ 39 #ifdef INET6 40 struct sockaddr_storage addr; 41 #else 42 struct sockaddr_in addr; 43 #endif 44 socklen_t addrlen; 45 46 /* 47 * Maximum supported query size. 48 */ 49 size_t maxlen; 50 51 /* 52 * Space reserved for optional records like EDNS. 53 */ 54 size_t reserved_space; 55 56 /* EDNS information provided by the client. */ 57 edns_record_type edns; 58 59 /* TSIG record information and running hash for query-response */ 60 tsig_record_type tsig; 61 /* tsig actions can be overridden, for axfr transfer. */ 62 int tsig_prepare_it, tsig_update_it, tsig_sign_it; 63 64 int tcp; 65 uint16_t tcplen; 66 67 buffer_type *packet; 68 69 /* Normalized query domain name. */ 70 const dname_type *qname; 71 72 /* Query type and class in host byte order. */ 73 uint16_t qtype; 74 uint16_t qclass; 75 76 /* The zone used to answer the query. */ 77 zone_type *zone; 78 79 /* The domain used to answer the query. */ 80 domain_type *domain; 81 82 /* The delegation domain, if any. */ 83 domain_type *delegation_domain; 84 85 /* The delegation NS rrset, if any. */ 86 rrset_type *delegation_rrset; 87 88 /* Original opcode. */ 89 uint8_t opcode; 90 91 /* 92 * The number of CNAMES followed. After a CNAME is followed 93 * we no longer change the RCODE to NXDOMAIN and no longer add 94 * SOA records to the authority section in case of NXDOMAIN 95 * and NODATA. 96 * Also includes number of DNAMES followed. 97 */ 98 int cname_count; 99 100 /* Used for dname compression. */ 101 uint16_t compressed_dname_count; 102 domain_type *compressed_dnames[MAXRRSPP]; 103 104 /* 105 * Indexed by domain->number, index 0 is reserved for the 106 * query name when generated from a wildcard record. 107 */ 108 uint16_t *compressed_dname_offsets; 109 uint32_t compressed_dname_offsets_size; 110 111 /* number of temporary domains used for the query */ 112 uint32_t number_temporary_domains; 113 114 /* 115 * Used for AXFR processing. 116 */ 117 int axfr_is_done; 118 zone_type *axfr_zone; 119 domain_type *axfr_current_domain; 120 rrset_type *axfr_current_rrset; 121 uint16_t axfr_current_rr; 122 }; 123 124 125 /* Check if the last write resulted in an overflow. */ 126 static inline int query_overflow(struct query *q); 127 128 /* 129 * Store the offset of the specified domain in the dname compression 130 * table. 131 */ 132 void query_put_dname_offset(struct query *query, 133 domain_type *domain, 134 uint16_t offset); 135 /* 136 * Lookup the offset of the specified domain in the dname compression 137 * table. Offset 0 is used to indicate the domain is not yet in the 138 * compression table. 139 */ 140 static inline 141 uint16_t query_get_dname_offset(struct query *query, domain_type *domain) 142 { 143 return query->compressed_dname_offsets[domain->number]; 144 } 145 146 /* 147 * Remove all compressed dnames that have an offset that points beyond 148 * the end of the current answer. This must be done after some RRs 149 * are truncated and before adding new RRs. Otherwise dnames may be 150 * compressed using truncated data! 151 */ 152 void query_clear_dname_offsets(struct query *query, size_t max_offset); 153 154 /* 155 * Clear the compression tables. 156 */ 157 void query_clear_compression_tables(struct query *query); 158 159 /* 160 * Enter the specified domain into the compression table starting at 161 * the specified offset. 162 */ 163 void query_add_compression_domain(struct query *query, 164 domain_type *domain, 165 uint16_t offset); 166 167 168 /* 169 * Create a new query structure. 170 */ 171 query_type *query_create(region_type *region, 172 uint16_t *compressed_dname_offsets, 173 uint32_t compressed_dname_size); 174 175 /* 176 * Reset a query structure so it is ready for receiving and processing 177 * a new query. 178 */ 179 void query_reset(query_type *query, size_t maxlen, int is_tcp); 180 181 /* 182 * Process a query and write the response in the query I/O buffer. 183 */ 184 query_state_type query_process(query_type *q, nsd_type *nsd); 185 186 /* 187 * Prepare the query structure for writing the response. The packet 188 * data up-to the current packet limit is preserved. This usually 189 * includes the packet header and question section. Space is reserved 190 * for the optional EDNS record, if required. 191 */ 192 void query_prepare_response(query_type *q); 193 194 /* 195 * Add EDNS0 information to the response if required. 196 */ 197 void query_add_optional(query_type *q, nsd_type *nsd); 198 199 /* 200 * Write an error response into the query structure with the indicated 201 * RCODE. 202 */ 203 query_state_type query_error(query_type *q, nsd_rc_type rcode); 204 205 static inline int 206 query_overflow(query_type *q) 207 { 208 return buffer_position(q->packet) > (q->maxlen - q->reserved_space); 209 } 210 static inline int 211 query_overflow_nsid(query_type *q, uint16_t nsid_len) 212 { 213 return buffer_position(q->packet) > (q->maxlen - q->reserved_space - nsid_len); 214 } 215 #endif /* _QUERY_H_ */ 216