PageRenderTime 51ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/nsd-3.2.12/query.h

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