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