acache.h

Go to the documentation of this file.
00001 /*
00002  * Copyright (C) 2004, 2006, 2007, 2013  Internet Systems Consortium, Inc. ("ISC")
00003  *
00004  * Permission to use, copy, modify, and/or distribute this software for any
00005  * purpose with or without fee is hereby granted, provided that the above
00006  * copyright notice and this permission notice appear in all copies.
00007  *
00008  * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
00009  * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
00010  * AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
00011  * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
00012  * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
00013  * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
00014  * PERFORMANCE OF THIS SOFTWARE.
00015  */
00016 
00017 /* $Id: acache.h,v 1.8 2007/06/19 23:47:16 tbox Exp $ */
00018 
00019 #ifndef DNS_ACACHE_H
00020 #define DNS_ACACHE_H 1
00021 
00022 /*****
00023  ***** Module Info
00024  *****/
00025 
00026 /*
00027  * Acache
00028  *
00029  * The Additional Cache Object
00030  *
00031  *      This module manages internal caching entries that correspond to
00032  *      the additional section data of a DNS DB node (an RRset header, more
00033  *      accurately).  An additional cache entry is expected to be (somehow)
00034  *      attached to a particular RR in a particular DB node, and contains a set
00035  *      of information of an additional data for the DB node.
00036  *
00037  *      An additional cache object is intended to be created as a per-view
00038  *      object, and manages all cache entries within the view.
00039  *
00040  *      The intended usage of the additional caching is to provide a short cut
00041  *      to additional glue RRs of an NS RR.  For each NS RR, it is often
00042  *      necessary to look for glue RRs to make a proper response.  Once the
00043  *      glue RRs are known, the additional caching allows the client to
00044  *      associate the information to the original NS RR so that further
00045  *      expensive lookups can be avoided for the NS RR.
00046  *
00047  *      Each additional cache entry contains information to identify a
00048  *      particular DB node and (optionally) an associated RRset.  The
00049  *      information consists of its zone, database, the version of the
00050  *      database, database node, and RRset.
00051  *
00052  *      A "negative" information can also be cached.  For example, if a glue
00053  *      RR does not exist as an authoritative data in the same zone as that
00054  *      of the NS RR, this fact can be cached by specifying a NULL pointer
00055  *      for the database, version, and node.  (See the description for
00056  *      dns_acache_getentry() below for more details.)
00057  *
00058  *      Since each member stored in an additional cache entry holds a reference
00059  *      to a corresponding object, a stale cache entry may cause unnecessary
00060  *      memory consumption.  For instance, when a zone is reloaded, additional
00061  *      cache entries that have a reference to the zone (and its DB and/or
00062  *      DB nodes) can delay the cleanup of the referred objects.  In order to
00063  *      minimize such a bad effect, this module provides several cleanup
00064  *      mechanisms.
00065  *
00066  *      The first one is a shutdown procedure called when the associated view
00067  *      is shut down.  In this case, dns_acache_shutdown() will be called and
00068  *      all cache entries will be purged.  This mechanism will help the
00069  *      situation when the configuration is reloaded or the main server is
00070  *      stopped.
00071  *
00072  *      Per-DB cleanup mechanism is also provided.  Each additional cache entry
00073  *      is associated with related DB, which is expected to have been
00074  *      registered when the DB was created by dns_acache_setdb().  If a
00075  *      particular DB is going to be destroyed, the primary holder of the DB,
00076  *      a typical example of which is a zone, will call dns_acache_putdb().
00077  *      Then this module will clean-up all cache entries associated with the
00078  *      DB.  This mechanism is effective when a secondary zone DB is going to
00079  *      be stale after a zone transfer.
00080  *
00081  *      Finally, this module supports for periodic clean-up of stale entries.
00082  *      Each cache entry has a timestamp field, which is updated every time
00083  *      the entry is referred.  A periodically invoked cleaner checks the
00084  *      timestamp of each entry, and purge entries that have not been referred
00085  *      for a certain period.  The cleaner interval can be specified by
00086  *      dns_acache_setcleaninginterval().  If the periodic clean-up is not
00087  *      enough, it is also possible to specify the upper limit of entries
00088  *      in terms of the memory consumption.  If the maximum value is
00089  *      specified, the cleaner is invoked when the memory consumption reaches
00090  *      the high watermark inferred from the maximum value.  In this case,
00091  *      the cleaner will use more aggressive algorithm to decide the "victim"
00092  *      entries.  The maximum value can be specified by
00093  *      dns_acache_setcachesize().
00094  *
00095  *      When a cache entry is going to be purged within this module, the
00096  *      callback function specified at the creation time will be called.
00097  *      The callback function is expected to release all internal resources
00098  *      related to the entry, which will typically be specific to DB
00099  *      implementation, and to call dns_acache_detachentry().  The callback
00100  *      mechanism is very important, since the holder of an additional cache
00101  *      entry may not be able to initiate the clean-up of the entry, due to
00102  *      the reference ordering.  For example, as long as an additional cache
00103  *      entry has a reference to a DB object, the DB cannot be freed, in which
00104  *      a DB node may have a reference to the cache entry.
00105  *
00106  *      Credits:
00107  *      The basic idea of this kind of short-cut for frequently used
00108  *      information is similar to the "pre-compiled answer" approach adopted
00109  *      in nsd by NLnet LABS with RIPE NCC.  Our work here is an independent
00110  *      effort, but the success of nsd encouraged us to pursue this path.
00111  *
00112  *      The design and implementation of the periodic memory management and
00113  *      the upper limitation of memory consumption was derived from the cache
00114  *      DB implementation of BIND9.
00115  *
00116  * MP:
00117  *      There are two main locks in this module.  One is for each entry, and
00118  *      the other is for the additional cache object.
00119  *
00120  * Reliability:
00121  *      The callback function for a cache entry is called with holding the
00122  *      entry lock.  Thus, it implicitly assumes the callback function does not
00123  *      call a function that can require the lock.  Typically, the only
00124  *      function that can be called from the callback function safely is
00125  *      dns_acache_detachentry().  The breakage of this implicit assumption
00126  *      may cause a deadlock.
00127  *
00128  * Resources:
00129  *      In a 32-bit architecture (such as i386), the following additional
00130  *      memory is required comparing to the case that disables this module.
00131  *      - 76 bytes for each additional cache entry
00132  *      - if the entry has a DNS name and associated RRset,
00133  *        * 44 bytes + size of the name (1-255 bytes)
00134  *        * 52 bytes x number_of_RRs
00135  *      - 28 bytes for each DB related to this module
00136  *
00137  *      Using the additional cache also requires extra memory consumption in
00138  *      the DB implementation.  In the current implementation for rbtdb, we
00139  *      need:
00140  *      - two additional pointers for each DB node (8 bytes for a 32-bit
00141  *        architecture
00142  *      - for each RR associated to an RR in a DB node, we also need
00143  *        a pointer and management objects to support the additional cache
00144  *        function.  These are allocated on-demand.  The total size is
00145  *        32 bytes for a 32-bit architecture.
00146  *
00147  * Security:
00148  *      Since this module does not handle any low-level data directly,
00149  *      no security issue specific to this module is anticipated.
00150  *
00151  * Standards:
00152  *      None.
00153  */
00154 
00155 /***
00156  *** Imports
00157  ***/
00158 
00159 #include <isc/mutex.h>
00160 #include <isc/lang.h>
00161 #include <isc/refcount.h>
00162 #include <isc/stdtime.h>
00163 
00164 #include <dns/types.h>
00165 
00166 /***
00167  *** Functions
00168  ***/
00169 ISC_LANG_BEGINDECLS
00170 
00171 isc_result_t
00172 dns_acache_create(dns_acache_t **acachep, isc_mem_t *mctx,
00173                   isc_taskmgr_t *taskmgr, isc_timermgr_t *timermgr);
00174 /*
00175  * Create a new DNS additional cache object.
00176  *
00177  * Requires:
00178  *
00179  *      'mctx' is a valid memory context
00180  *
00181  *      'taskmgr' is a valid task manager
00182  *
00183  *      'timermgr' is a valid timer or NULL.  If NULL, no periodic cleaning of
00184  *      the cache will take place.
00185  *
00186  *      'acachep' is a valid pointer, and *acachep == NULL
00187  *
00188  * Ensures:
00189  *
00190  *      '*acachep' is attached to the newly created cache
00191  *
00192  * Returns:
00193  *
00194  *      ISC_R_SUCCESS
00195  *      ISC_R_NOMEMORY
00196  *      ISC_R_UNEXPECTED
00197  */
00198 
00199 void
00200 dns_acache_attach(dns_acache_t *source, dns_acache_t **targetp);
00201 /*
00202  * Attach *targetp to cache.
00203  *
00204  * Requires:
00205  *
00206  *      'acache' is a valid additional cache.
00207  *
00208  *      'targetp' points to a NULL dns_acache_t *.
00209  *
00210  * Ensures:
00211  *
00212  *      *targetp is attached to the 'source' additional cache.
00213  */
00214 
00215 void
00216 dns_acache_detach(dns_acache_t **acachep);
00217 /*
00218  * Detach *acachep from its cache.
00219  *
00220  * Requires:
00221  *
00222  *      '*acachep' points to a valid additional cache.
00223  *
00224  * Ensures:
00225  *
00226  *      *acachep is NULL.
00227  *
00228  *      If '*acachep' is the last reference to the cache and the additional
00229  *      cache does not have an outstanding task, all resources used by the
00230  *      cache will be freed.
00231  */
00232 
00233 void
00234 dns_acache_setcleaninginterval(dns_acache_t *acache, unsigned int t);
00235 /*
00236  * Set the periodic cleaning interval of an additional cache to 'interval'
00237  * seconds.
00238  */
00239 
00240 void
00241 dns_acache_setcachesize(dns_acache_t *acache, size_t size);
00242 /*
00243  * Set the maximum additional cache size.  0 means unlimited.
00244  */
00245 
00246 isc_result_t
00247 dns_acache_setdb(dns_acache_t *acache, dns_db_t *db);
00248 /*
00249  * Set 'db' in 'acache' when the db can be referred from acache, in order
00250  * to provide a hint for resolving the back reference.
00251  *
00252  * Requires:
00253  *      'acache' is a valid acache pointer.
00254  *      'db' is a valid DNS DB pointer.
00255  *
00256  * Ensures:
00257  *      'acache' will have a reference to 'db'.
00258  *
00259  * Returns:
00260  *      ISC_R_SUCCESS
00261  *      ISC_R_EXISTS    (which means the specified 'db' is already set)
00262  *      ISC_R_NOMEMORY
00263  */
00264 
00265 isc_result_t
00266 dns_acache_putdb(dns_acache_t *acache, dns_db_t *db);
00267 /*
00268  * Release 'db' from 'acache' if it has been set by dns_acache_setdb().
00269  *
00270  * Requires:
00271  *      'acache' is a valid acache pointer.
00272  *      'db' is a valid DNS DB pointer.
00273  *
00274  * Ensures:
00275  *      'acache' will release the reference to 'db'.  Additionally, the content
00276  *      of each cache entry that is related to the 'db' will be released via
00277  *      the callback function.
00278  *
00279  * Returns:
00280  *      ISC_R_SUCCESS
00281  *      ISC_R_NOTFOUND  (which means the specified 'db' is not set in 'acache')
00282  *      ISC_R_NOMEMORY
00283  */
00284 
00285 void
00286 dns_acache_shutdown(dns_acache_t *acache);
00287 /*
00288  * Shutdown 'acache'.
00289  *
00290  * Requires:
00291  *
00292  *      '*acache' is a valid additional cache.
00293  */
00294 
00295 isc_result_t
00296 dns_acache_createentry(dns_acache_t *acache, dns_db_t *origdb,
00297                        void (*callback)(dns_acacheentry_t *, void **),
00298                        void *cbarg, dns_acacheentry_t **entryp);
00299 /*
00300  * Create an additional cache entry.  A new entry is created and attached to
00301  * the given additional cache object.  A callback function is also associated
00302  * with the created entry, which will be called when the cache entry is purged
00303  * for some reason.
00304  *
00305  * Requires:
00306  *
00307  *      'acache' is a valid additional cache.
00308  *      'entryp' is a valid pointer, and *entryp == NULL
00309  *      'origdb' is a valid DNS DB pointer.
00310  *      'callback' and 'cbarg' can be NULL.  In this case, however, the entry
00311  *      is meaningless (and will be cleaned-up in the next periodical
00312  *      cleaning).
00313  *
00314  * Ensures:
00315  *      '*entryp' will point to a new additional cache entry.
00316  *
00317  * Returns:
00318  *      ISC_R_SUCCESS
00319  *      ISC_R_NOMEMORY
00320  */
00321 
00322 isc_result_t
00323 dns_acache_getentry(dns_acacheentry_t *entry, dns_zone_t **zonep,
00324                     dns_db_t **dbp, dns_dbversion_t **versionp,
00325                     dns_dbnode_t **nodep, dns_name_t *fname,
00326                     dns_message_t *msg, isc_stdtime_t now);
00327 /*
00328  * Get content from a particular additional cache entry.
00329  *
00330  * Requires:
00331  *
00332  *      'entry' is a valid additional cache entry.
00333  *      'zonep' is a NULL pointer or '*zonep' == NULL (this is the only
00334  *      optional parameter.)
00335  *      'dbp' is a valid pointer, and '*dbp' == NULL
00336  *      'versionp' is a valid pointer, and '*versionp' == NULL
00337  *      'nodep' is a valid pointer, and '*nodep' == NULL
00338  *      'fname' is a valid DNS name.
00339  *      'msg' is a valid DNS message.
00340  *
00341  * Ensures:
00342  *      Several possible cases can happen according to the content.
00343  *      1. For a positive cache entry,
00344  *      '*zonep' will point to the corresponding zone (if zonep is a valid
00345  *      pointer),
00346  *      '*dbp' will point to a DB for the zone,
00347  *      '*versionp' will point to its version, and
00348  *      '*nodep' will point to the corresponding DB node.
00349  *      'fname' will have the DNS name of the DB node and contain a list of
00350  *      rdataset for the node (which can be an empty list).
00351  *
00352  *      2. For a negative cache entry that means no corresponding zone exists,
00353  *      '*zonep' == NULL (if zonep is a valid pointer)
00354  *      '*dbp', '*versionp', and '*nodep' will be NULL.
00355  *
00356  *      3. For a negative cache entry that means no corresponding DB node
00357  *      exists, '*zonep' will point to the corresponding zone (if zonep is a
00358  *      valid pointer),
00359  *      '*dbp' will point to a corresponding DB for zone,
00360  *      '*versionp' will point to its version.
00361  *      '*nodep' will be kept as NULL.
00362  *      'fname' will not change.
00363  *
00364  *      On failure, no new references will be created.
00365  *
00366  * Returns:
00367  *      ISC_R_SUCCESS
00368  *      ISC_R_NOMEMORY
00369  */
00370 
00371 isc_result_t
00372 dns_acache_setentry(dns_acache_t *acache, dns_acacheentry_t *entry,
00373                     dns_zone_t *zone, dns_db_t *db, dns_dbversion_t *version,
00374                     dns_dbnode_t *node, dns_name_t *fname);
00375 /*
00376  * Set content to a particular additional cache entry.
00377  *
00378  * Requires:
00379  *      'acache' is a valid additional cache.
00380  *      'entry' is a valid additional cache entry.
00381  *      All the others pointers are NULL or a valid pointer of the
00382  *      corresponding type.
00383  *
00384  * Returns:
00385  *      ISC_R_SUCCESS
00386  *      ISC_R_NOMEMORY
00387  *      ISC_R_NOTFOUND
00388  */
00389 
00390 isc_boolean_t
00391 dns_acache_cancelentry(dns_acacheentry_t *entry);
00392 /*
00393  * Cancel the use of the cache entry 'entry'.  This function is supposed to
00394  * be called when the node that holds the entry finds the content is not
00395  * correct any more.  This function will try to release as much dependency as
00396  * possible, and will be ready to be cleaned-up.  The registered callback
00397  * function will be canceled and will never called.
00398  *
00399  * Requires:
00400  *      'entry' is a valid additional cache entry.
00401  *
00402  * Returns:
00403  *      ISC_TRUE if the entry was active when canceled
00404  */
00405 
00406 void
00407 dns_acache_attachentry(dns_acacheentry_t *source, dns_acacheentry_t **targetp);
00408 /*
00409  * Attach *targetp to the cache entry 'source'.
00410  *
00411  * Requires:
00412  *
00413  *      'source' is a valid additional cache entry.
00414  *
00415  *      'targetp' points to a NULL dns_acacheentry_t *.
00416  *
00417  * Ensures:
00418  *
00419  *      *targetp is attached to 'source'.
00420  */
00421 
00422 void
00423 dns_acache_detachentry(dns_acacheentry_t **entryp);
00424 /*
00425  * Detach *entryp from its cache.
00426  *
00427  * Requires:
00428  *
00429  *      '*entryp' points to a valid additional cache entry.
00430  *
00431  * Ensures:
00432  *
00433  *      *entryp is NULL.
00434  *
00435  *      If '*entryp' is the last reference to the entry,
00436  *      cache does not have an outstanding task, all resources used by the
00437  *      entry (including the entry object itself) will be freed.
00438  */
00439 
00440 void
00441 dns_acache_countquerymiss(dns_acache_t *acache);
00442 /*
00443  * Count up a missed acache query.  XXXMLG need more docs.
00444  */
00445 
00446 ISC_LANG_ENDDECLS
00447 
00448 #endif /* DNS_ACACHE_H */

Generated on Tue Apr 28 17:40:57 2015 by Doxygen 1.5.4 for BIND9 Internals 9.11.0pre-alpha