Detect FPU by checking CPUID features.
[dragonfly.git] / contrib / bind-9.5.2 / lib / dns / include / dns / acache.h
blob28990c2aab0c249d3c48154441e012d19d7a5240
1 /*
2 * Copyright (C) 2004, 2006, 2007 Internet Systems Consortium, Inc. ("ISC")
4 * Permission to use, copy, modify, and/or distribute this software for any
5 * purpose with or without fee is hereby granted, provided that the above
6 * copyright notice and this permission notice appear in all copies.
8 * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
9 * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
10 * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
11 * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
12 * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
13 * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
14 * PERFORMANCE OF THIS SOFTWARE.
17 /* $Id: acache.h,v 1.8 2007/06/19 23:47:16 tbox Exp $ */
19 #ifndef DNS_ACACHE_H
20 #define DNS_ACACHE_H 1
22 /*****
23 ***** Module Info
24 *****/
27 * Acache
29 * The Additional Cache Object
31 * This module manages internal caching entries that correspond to
32 * the additional section data of a DNS DB node (an RRset header, more
33 * accurately). An additional cache entry is expected to be (somehow)
34 * attached to a particular RR in a particular DB node, and contains a set
35 * of information of an additional data for the DB node.
37 * An additional cache object is intended to be created as a per-view
38 * object, and manages all cache entries within the view.
40 * The intended usage of the additional caching is to provide a short cut
41 * to additional glue RRs of an NS RR. For each NS RR, it is often
42 * necessary to look for glue RRs to make a proper response. Once the
43 * glue RRs are known, the additional caching allows the client to
44 * associate the information to the original NS RR so that further
45 * expensive lookups can be avoided for the NS RR.
47 * Each additional cache entry contains information to identify a
48 * particular DB node and (optionally) an associated RRset. The
49 * information consists of its zone, database, the version of the
50 * database, database node, and RRset.
52 * A "negative" information can also be cached. For example, if a glue
53 * RR does not exist as an authoritative data in the same zone as that
54 * of the NS RR, this fact can be cached by specifying a NULL pointer
55 * for the database, version, and node. (See the description for
56 * dns_acache_getentry() below for more details.)
58 * Since each member stored in an additional cache entry holds a reference
59 * to a corresponding object, a stale cache entry may cause unnecessary
60 * memory consumption. For instance, when a zone is reloaded, additional
61 * cache entries that have a reference to the zone (and its DB and/or
62 * DB nodes) can delay the cleanup of the referred objects. In order to
63 * minimize such a bad effect, this module provides several cleanup
64 * mechanisms.
66 * The first one is a shutdown procedure called when the associated view
67 * is shut down. In this case, dns_acache_shutdown() will be called and
68 * all cache entries will be purged. This mechanism will help the
69 * situation when the configuration is reloaded or the main server is
70 * stopped.
72 * Per-DB cleanup mechanism is also provided. Each additional cache entry
73 * is associated with related DB, which is expected to have been
74 * registered when the DB was created by dns_acache_setdb(). If a
75 * particular DB is going to be destroyed, the primary holder of the DB,
76 * a typical example of which is a zone, will call dns_acache_putdb().
77 * Then this module will clean-up all cache entries associated with the
78 * DB. This mechanism is effective when a secondary zone DB is going to
79 * be stale after a zone transfer.
81 * Finally, this module supports for periodic clean-up of stale entries.
82 * Each cache entry has a timestamp field, which is updated every time
83 * the entry is referred. A periodically invoked cleaner checks the
84 * timestamp of each entry, and purge entries that have not been referred
85 * for a certain period. The cleaner interval can be specified by
86 * dns_acache_setcleaninginterval(). If the periodic clean-up is not
87 * enough, it is also possible to specify the upper limit of entries
88 * in terms of the memory consumption. If the maximum value is
89 * specified, the cleaner is invoked when the memory consumption reaches
90 * the high watermark inferred from the maximum value. In this case,
91 * the cleaner will use more aggressive algorithm to decide the "victim"
92 * entries. The maximum value can be specified by
93 * dns_acache_setcachesize().
95 * When a cache entry is going to be purged within this module, the
96 * callback function specified at the creation time will be called.
97 * The callback function is expected to release all internal resources
98 * related to the entry, which will typically be specific to DB
99 * implementation, and to call dns_acache_detachentry(). The callback
100 * mechanism is very important, since the holder of an additional cache
101 * entry may not be able to initiate the clean-up of the entry, due to
102 * the reference ordering. For example, as long as an additional cache
103 * entry has a reference to a DB object, the DB cannot be freed, in which
104 * a DB node may have a reference to the cache entry.
106 * Credits:
107 * The basic idea of this kind of short-cut for frequently used
108 * information is similar to the "pre-compiled answer" approach adopted
109 * in nsd by NLnet LABS with RIPE NCC. Our work here is an independent
110 * effort, but the success of nsd encouraged us to pursue this path.
112 * The design and implementation of the periodic memory management and
113 * the upper limitation of memory consumption was derived from the cache
114 * DB implementation of BIND9.
116 * MP:
117 * There are two main locks in this module. One is for each entry, and
118 * the other is for the additional cache object.
120 * Reliability:
121 * The callback function for a cache entry is called with holding the
122 * entry lock. Thus, it implicitly assumes the callback function does not
123 * call a function that can require the lock. Typically, the only
124 * function that can be called from the callback function safely is
125 * dns_acache_detachentry(). The breakage of this implicit assumption
126 * may cause a deadlock.
128 * Resources:
129 * In a 32-bit architecture (such as i386), the following additional
130 * memory is required comparing to the case that disables this module.
131 * - 76 bytes for each additional cache entry
132 * - if the entry has a DNS name and associated RRset,
133 * * 44 bytes + size of the name (1-255 bytes)
134 * * 52 bytes x number_of_RRs
135 * - 28 bytes for each DB related to this module
137 * Using the additional cache also requires extra memory consumption in
138 * the DB implementation. In the current implementation for rbtdb, we
139 * need:
140 * - two additional pointers for each DB node (8 bytes for a 32-bit
141 * architecture
142 * - for each RR associated to an RR in a DB node, we also need
143 * a pointer and management objects to support the additional cache
144 * function. These are allocated on-demand. The total size is
145 * 32 bytes for a 32-bit architecture.
147 * Security:
148 * Since this module does not handle any low-level data directly,
149 * no security issue specific to this module is anticipated.
151 * Standards:
152 * None.
155 /***
156 *** Imports
157 ***/
159 #include <isc/mutex.h>
160 #include <isc/lang.h>
161 #include <isc/refcount.h>
162 #include <isc/stdtime.h>
164 #include <dns/types.h>
166 /***
167 *** Functions
168 ***/
169 ISC_LANG_BEGINDECLS
171 isc_result_t
172 dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx,
173 isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr);
175 * Create a new DNS additional cache object.
177 * Requires:
179 * 'mctx' is a valid memory context
181 * 'taskmgr' is a valid task manager
183 * 'timermgr' is a valid timer or NULL. If NULL, no periodic cleaning of
184 * the cache will take place.
186 * 'acachep' is a valid pointer, and *acachep == NULL
188 * Ensures:
190 * '*acachep' is attached to the newly created cache
192 * Returns:
194 * ISC_R_SUCCESS
195 * ISC_R_NOMEMORY
196 * ISC_R_UNEXPECTED
199 void
200 dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp);
202 * Attach *targetp to cache.
204 * Requires:
206 * 'acache' is a valid additional cache.
208 * 'targetp' points to a NULL dns_acache_t *.
210 * Ensures:
212 * *targetp is attached to the 'source' additional cache.
215 void
216 dns_acache_detach(dns_acache_t **acachep);
218 * Detach *acachep from its cache.
220 * Requires:
222 * '*acachep' points to a valid additional cache.
224 * Ensures:
226 * *acachep is NULL.
228 * If '*acachep' is the last reference to the cache and the additional
229 * cache does not have an outstanding task, all resources used by the
230 * cache will be freed.
233 void
234 dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t);
236 * Set the periodic cleaning interval of an additional cache to 'interval'
237 * seconds.
240 void
241 dns_acache_setcachesize(dns_acache_t *acache, isc_uint32_t size);
243 * Set the maximum additional cache size. 0 means unlimited.
246 isc_result_t
247 dns_acache_setdb(dns_acache_t *acache, dns_db_t *db);
249 * Set 'db' in 'acache' when the db can be referred from acache, in order
250 * to provide a hint for resolving the back reference.
252 * Requires:
253 * 'acache' is a valid acache pointer.
254 * 'db' is a valid DNS DB pointer.
256 * Ensures:
257 * 'acache' will have a reference to 'db'.
259 * Returns:
260 * ISC_R_SUCCESS
261 * ISC_R_EXISTS (which means the specified 'db' is already set)
262 * ISC_R_NOMEMORY
265 isc_result_t
266 dns_acache_putdb(dns_acache_t *acache, dns_db_t *db);
268 * Release 'db' from 'acache' if it has been set by dns_acache_setdb().
270 * Requires:
271 * 'acache' is a valid acache pointer.
272 * 'db' is a valid DNS DB pointer.
274 * Ensures:
275 * 'acache' will release the reference to 'db'. Additionally, the content
276 * of each cache entry that is related to the 'db' will be released via
277 * the callback function.
279 * Returns:
280 * ISC_R_SUCCESS
281 * ISC_R_NOTFOUND (which means the specified 'db' is not set in 'acache')
282 * ISC_R_NOMEMORY
285 void
286 dns_acache_shutdown(dns_acache_t *acache);
288 * Shutdown 'acache'.
290 * Requires:
292 * '*acache' is a valid additional cache.
295 isc_result_t
296 dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb,
297 void (*callback)(dns_acacheentry_t *, void **),
298 void *cbarg, dns_acacheentry_t **entryp);
300 * Create an additional cache entry. A new entry is created and attached to
301 * the given additional cache object. A callback function is also associated
302 * with the created entry, which will be called when the cache entry is purged
303 * for some reason.
305 * Requires:
307 * 'acache' is a valid additional cache.
308 * 'entryp' is a valid pointer, and *entryp == NULL
309 * 'origdb' is a valid DNS DB pointer.
310 * 'callback' and 'cbarg' can be NULL. In this case, however, the entry
311 * is meaningless (and will be cleaned-up in the next periodical
312 * cleaning).
314 * Ensures:
315 * '*entryp' will point to a new additional cache entry.
317 * Returns:
318 * ISC_R_SUCCESS
319 * ISC_R_NOMEMORY
322 isc_result_t
323 dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep,
324 dns_db_t **dbp, dns_dbversion_t **versionp,
325 dns_dbnode_t **nodep, dns_name_t *fname,
326 dns_message_t *msg, isc_stdtime_t now);
328 * Get content from a particular additional cache entry.
330 * Requires:
332 * 'entry' is a valid additional cache entry.
333 * 'zonep' is a NULL pointer or '*zonep' == NULL (this is the only
334 * optional parameter.)
335 * 'dbp' is a valid pointer, and '*dbp' == NULL
336 * 'versionp' is a valid pointer, and '*versionp' == NULL
337 * 'nodep' is a valid pointer, and '*nodep' == NULL
338 * 'fname' is a valid DNS name.
339 * 'msg' is a valid DNS message.
341 * Ensures:
342 * Several possible cases can happen according to the content.
343 * 1. For a positive cache entry,
344 * '*zonep' will point to the corresponding zone (if zonep is a valid
345 * pointer),
346 * '*dbp' will point to a DB for the zone,
347 * '*versionp' will point to its version, and
348 * '*nodep' will point to the corresponding DB node.
349 * 'fname' will have the DNS name of the DB node and contain a list of
350 * rdataset for the node (which can be an empty list).
352 * 2. For a negative cache entry that means no corresponding zone exists,
353 * '*zonep' == NULL (if zonep is a valid pointer)
354 * '*dbp', '*versionp', and '*nodep' will be NULL.
356 * 3. For a negative cache entry that means no corresponding DB node
357 * exists, '*zonep' will point to the corresponding zone (if zonep is a
358 * valid pointer),
359 * '*dbp' will point to a corresponding DB for zone,
360 * '*versionp' will point to its version.
361 * '*nodep' will be kept as NULL.
362 * 'fname' will not change.
364 * On failure, no new references will be created.
366 * Returns:
367 * ISC_R_SUCCESS
368 * ISC_R_NOMEMORY
371 isc_result_t
372 dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry,
373 dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
374 dns_dbnode_t *node, dns_name_t *fname);
376 * Set content to a particular additional cache entry.
378 * Requires:
379 * 'acache' is a valid additional cache.
380 * 'entry' is a valid additional cache entry.
381 * All the others pointers are NULL or a valid pointer of the
382 * corresponding type.
384 * Returns:
385 * ISC_R_SUCCESS
386 * ISC_R_NOMEMORY
387 * ISC_R_NOTFOUND
390 void
391 dns_acache_cancelentry(dns_acacheentry_t *entry);
393 * Cancel the use of the cache entry 'entry'. This function is supposed to
394 * be called when the node that holds the entry finds the content is not
395 * correct any more. This function will try to release as much dependency as
396 * possible, and will be ready to be cleaned-up. The registered callback
397 * function will be canceled and will never called.
399 * Requires:
400 * 'entry' is a valid additional cache entry.
403 void
404 dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp);
406 * Attach *targetp to the cache entry 'source'.
408 * Requires:
410 * 'source' is a valid additional cache entry.
412 * 'targetp' points to a NULL dns_acacheentry_t *.
414 * Ensures:
416 * *targetp is attached to 'source'.
419 void
420 dns_acache_detachentry(dns_acacheentry_t **entryp);
422 * Detach *entryp from its cache.
424 * Requires:
426 * '*entryp' points to a valid additional cache entry.
428 * Ensures:
430 * *entryp is NULL.
432 * If '*entryp' is the last reference to the entry,
433 * cache does not have an outstanding task, all resources used by the
434 * entry (including the entry object itself) will be freed.
437 void
438 dns_acache_countquerymiss(dns_acache_t *acache);
440 * Count up a missed acache query. XXXMLG need more docs.
443 ISC_LANG_ENDDECLS
445 #endif /* DNS_ACACHE_H */