Return to random.c CVS log | Up to [ELWIX - Embedded LightWeight unIX -] / embedaddon / ntp / lib / isc |
1.1 ! misho 1: /* ! 2: * Copyright (C) 2004, 2005, 2007 Internet Systems Consortium, Inc. ("ISC") ! 3: * Copyright (C) 1999-2003 Internet Software Consortium. ! 4: * ! 5: * Permission to use, copy, modify, and/or distribute this software for any ! 6: * purpose with or without fee is hereby granted, provided that the above ! 7: * copyright notice and this permission notice appear in all copies. ! 8: * ! 9: * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH ! 10: * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY ! 11: * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, ! 12: * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM ! 13: * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE ! 14: * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR ! 15: * PERFORMANCE OF THIS SOFTWARE. ! 16: */ ! 17: ! 18: /* $Id: random.c,v 1.25 2007/06/19 23:47:17 tbox Exp $ */ ! 19: ! 20: /*! \file */ ! 21: ! 22: #include <config.h> ! 23: ! 24: #include <stdlib.h> ! 25: #include <time.h> /* Required for time(). */ ! 26: #ifdef HAVE_SYS_TYPES_H ! 27: #include <sys/types.h> ! 28: #endif ! 29: #ifdef HAVE_UNISTD_H ! 30: #include <unistd.h> ! 31: #endif ! 32: ! 33: #include <isc/mutex.h> ! 34: #include <isc/once.h> ! 35: #include <isc/random.h> ! 36: #include <isc/string.h> ! 37: #include <isc/util.h> ! 38: ! 39: static isc_once_t once = ISC_ONCE_INIT; ! 40: ! 41: static void ! 42: initialize_rand(void) ! 43: { ! 44: #ifndef HAVE_ARC4RANDOM ! 45: unsigned int pid = getpid(); ! 46: ! 47: /* ! 48: * The low bits of pid generally change faster. ! 49: * Xor them with the high bits of time which change slowly. ! 50: */ ! 51: pid = ((pid << 16) & 0xffff0000) | ((pid >> 16) & 0xffff); ! 52: ! 53: srand(time(NULL) ^ pid); ! 54: #endif ! 55: } ! 56: ! 57: static void ! 58: initialize(void) ! 59: { ! 60: RUNTIME_CHECK(isc_once_do(&once, initialize_rand) == ISC_R_SUCCESS); ! 61: } ! 62: ! 63: void ! 64: isc_random_seed(isc_uint32_t seed) ! 65: { ! 66: initialize(); ! 67: ! 68: #ifndef HAVE_ARC4RANDOM ! 69: srand(seed); ! 70: #else ! 71: arc4random_addrandom((u_char *) &seed, sizeof(isc_uint32_t)); ! 72: #endif ! 73: } ! 74: ! 75: void ! 76: isc_random_get(isc_uint32_t *val) ! 77: { ! 78: REQUIRE(val != NULL); ! 79: ! 80: initialize(); ! 81: ! 82: #ifndef HAVE_ARC4RANDOM ! 83: /* ! 84: * rand()'s lower bits are not random. ! 85: * rand()'s upper bit is zero. ! 86: */ ! 87: *val = ((rand() >> 4) & 0xffff) | ((rand() << 12) & 0xffff0000); ! 88: #else ! 89: *val = arc4random(); ! 90: #endif ! 91: } ! 92: ! 93: isc_uint32_t ! 94: isc_random_jitter(isc_uint32_t max, isc_uint32_t jitter) { ! 95: REQUIRE(jitter < max); ! 96: if (jitter == 0) ! 97: return (max); ! 98: else ! 99: #ifndef HAVE_ARC4RANDOM ! 100: return (max - rand() % jitter); ! 101: #else ! 102: return (max - arc4random() % jitter); ! 103: #endif ! 104: }