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