72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntCopyright (C) 1999-2002, 2004, 2016 Internet Systems Consortium, Inc. ("ISC")
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntThis Source Code Form is subject to the terms of the Mozilla Public
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntLicense, v. 2.0. If a copy of the MPL was not distributed with this
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntfile, You can obtain one at http://mozilla.org/MPL/2.0/.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt$Id: magic_numbers,v 1.7 2004/03/05 05:04:50 marka Exp $
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntMagic Numbers
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntA number of data structures in the ISC and DNS libraries have an unsigned int
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntmagic number as the first field. The purpose of the magic number is
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntprincipally to validate that a pointer a subroutine has gotten really points
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntto the type it claims to be. This helps detect problems caused by resources
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntbeing freed prematurely, that have been corrupted, or that have not been
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntproperly initialized. It can also be handy in debugging.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntMagic numbers should always be the first field. They never require locking
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntto access. As to the actual value to be used, something mnemonic is good:
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt #define TASK_MAGIC 0x5441534BU /* TASK. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt #define VALID_TASK(t) ((t) != NULL && \
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt (t)->magic == TASK_MAGIC)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt #define TASK_MANAGER_MAGIC 0x54534B4DU /* TSKM. */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt #define VALID_MANAGER(m) ((m) != NULL && \
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt (m)->magic ==
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt TASK_MANAGER_MAGIC)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntUnless the memory cost is critical, most objects should have a magic number.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntThe magic number should be the last field set in a creation routine, so that
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntan object will never be stamped with a magic number unless it is valid.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntThe magic number should be set to zero immediately before the object is
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntfreed.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntMagic values are generally private to the implementation of the type. I.e.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntthey are defined in the .c file, not the .h file.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntValidation of magic numbers is done by routines that manipulate the type,
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntnot by users of the type. Indeed, user validation is usually not possible
72c86c105a7cf315036d7131a4ef408bc6227639Evan Huntbecause the magic number is not public.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan HuntMagic number checking may become a build option in a future release. E.g.
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt struct foo {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt ISC_MAGIC_DECLARATION
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* ... */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt foo_create() {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* ... */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt ISC_MAGIC_SET(value);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt foo_destroy() {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt /* ... */
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt ISC_MAGIC_CLEAR(value);
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt #define FOO_MAGIC 0x00010203U
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt #define VALID_FOO(f) ISC_MAGIC_VALIDATE(f, FOO_MAGIC)
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt foo_dosomething(foo *f) {
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt REQUIRE(VALID_FOO(f));
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt }
72c86c105a7cf315036d7131a4ef408bc6227639Evan Hunt