--- /dev/null
+Copyright (C) 2004 Internet Systems Consortium, Inc. ("ISC")
+Copyright (C) 1999-2002 Internet Software Consortium.
+See COPYRIGHT in the source root or http://isc.org/copyright.html for terms.
+
+$Id: magic_numbers,v 1.7 2004/03/05 05:04:50 marka Exp $
+
+Magic Numbers
+
+A number of data structures in the ISC and DNS libraries have an unsigned int
+magic number as the first field. The purpose of the magic number is
+principally to validate that a pointer a subroutine has gotten really points
+to the type it claims to be. This helps detect problems caused by resources
+being freed prematurely, that have been corrupted, or that have not been
+properly initialized. It can also be handy in debugging.
+
+Magic numbers should always be the first field. They never require locking
+to access. As to the actual value to be used, something mnemonic is good:
+
+ #define TASK_MAGIC 0x5441534BU /* TASK. */
+ #define VALID_TASK(t) ((t) != NULL && \
+ (t)->magic == TASK_MAGIC)
+
+ #define TASK_MANAGER_MAGIC 0x54534B4DU /* TSKM. */
+ #define VALID_MANAGER(m) ((m) != NULL && \
+ (m)->magic ==
+ TASK_MANAGER_MAGIC)
+
+Unless the memory cost is critical, most objects should have a magic number.
+
+The magic number should be the last field set in a creation routine, so that
+an object will never be stamped with a magic number unless it is valid.
+
+The magic number should be set to zero immediately before the object is
+freed.
+
+Magic values are generally private to the implementation of the type. I.e.
+they are defined in the .c file, not the .h file.
+
+Validation of magic numbers is done by routines that manipulate the type,
+not by users of the type. Indeed, user validation is usually not possible
+because the magic number is not public.
+
+Magic number checking may become a build option in a future release. E.g.
+
+ struct foo {
+ ISC_MAGIC_DECLARATION
+ /* ... */
+ }
+
+ foo_create() {
+ /* ... */
+ ISC_MAGIC_SET(value);
+ }
+
+ foo_destroy() {
+ /* ... */
+ ISC_MAGIC_CLEAR(value);
+ }
+
+ #define FOO_MAGIC 0x00010203U
+ #define VALID_FOO(f) ISC_MAGIC_VALIDATE(f, FOO_MAGIC)
+
+ foo_dosomething(foo *f) {
+ REQUIRE(VALID_FOO(f));
+ }