diff --git a/CHANGES b/CHANGES index 470a2403e9..a06a8afdf2 100644 --- a/CHANGES +++ b/CHANGES @@ -1,4 +1,10 @@ + 422. [func] get rid of isc_random_t, and make isc_random_get() + and isc_random_jitter() use rand() internally + instead of local state. Note that isc_random_*() + functions are only for weak, non-critical "randomness" + such as timing jitter and such. + 421. [bug] nslookup would exit when given a blank line as input. 420. [bug] nslookup failed to implement the "exit" command. diff --git a/lib/dns/adb.c b/lib/dns/adb.c index 28d04bb794..ae860c9780 100644 --- a/lib/dns/adb.c +++ b/lib/dns/adb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: adb.c,v 1.149 2000/08/26 02:21:44 explorer Exp $ */ +/* $Id: adb.c,v 1.150 2000/09/06 02:39:56 explorer Exp $ */ /* * Implementation notes @@ -144,8 +144,6 @@ struct dns_adb { isc_mempool_t *afmp; /* dns_adbfetch_t */ isc_mempool_t *af6mp; /* dns_adbfetch6_t */ - isc_random_t rand; - /* * Bucketized locks and lists for names. * @@ -1405,7 +1403,7 @@ new_adbentry(dns_adb_t *adb) { e->flags = 0; e->edns_level = -1; e->goodness = 0; - isc_random_get(&adb->rand, &r); + isc_random_get(&r); e->srtt = (r & 0x1f) + 1; e->expires = 0; e->avoid_bitstring = 0; @@ -2141,8 +2139,6 @@ destroy(dns_adb_t *adb) { DESTROYLOCK(&adb->lock); DESTROYLOCK(&adb->mplock); - isc_random_invalidate(&adb->rand); - isc_mem_put(adb->mctx, adb, sizeof (dns_adb_t)); } @@ -2198,10 +2194,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, adb->shutting_down = ISC_FALSE; ISC_LIST_INIT(adb->whenshutdown); - result = isc_random_init(&adb->rand); - if (result != ISC_R_SUCCESS) - goto fail0a; - result = isc_mutex_init(&adb->lock); if (result != ISC_R_SUCCESS) goto fail0b; @@ -2326,8 +2318,6 @@ dns_adb_create(isc_mem_t *mem, dns_view_t *view, isc_timermgr_t *timermgr, fail0c: DESTROYLOCK(&adb->lock); fail0b: - isc_random_invalidate(&adb->rand); - fail0a: isc_mem_put(mem, adb, sizeof (dns_adb_t)); return (result); diff --git a/lib/dns/rbtdb.c b/lib/dns/rbtdb.c index 7a93853f49..42211c53e3 100644 --- a/lib/dns/rbtdb.c +++ b/lib/dns/rbtdb.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: rbtdb.c,v 1.122 2000/08/31 12:15:11 marka Exp $ */ +/* $Id: rbtdb.c,v 1.123 2000/09/06 02:39:57 explorer Exp $ */ /* * Principal Author: Bob Halley @@ -166,7 +166,6 @@ typedef struct { rbtdb_version_t * future_version; rbtdb_versionlist_t open_versions; isc_boolean_t overmem; - isc_random_t random; /* Locked by tree_lock. */ dns_rbt_t * tree; isc_boolean_t secure; @@ -330,7 +329,6 @@ free_rbtdb(dns_rbtdb_t *rbtdb) { REQUIRE(EMPTY(rbtdb->open_versions)); REQUIRE(rbtdb->future_version == NULL); - isc_random_invalidate(&rbtdb->random); if (rbtdb->current_version != NULL) isc_mem_put(rbtdb->common.mctx, rbtdb->current_version, sizeof (rbtdb_version_t)); @@ -2736,7 +2734,7 @@ expirenode(dns_db_t *db, dns_dbnode_t *node, isc_stdtime_t now) { if (rbtdb->overmem) fprintf(stderr, "overmem stale\n"); } else if (rbtdb->overmem) { - isc_random_get(&rbtdb->random, &val); + isc_random_get(&val); if ((val % 7) == 0) { fprintf(stderr, "overmem expire\n"); header->ttl = 0; @@ -4031,7 +4029,6 @@ dns_rbtdb_create rbtdb->attributes = 0; rbtdb->secure = ISC_FALSE; rbtdb->overmem = ISC_FALSE; - isc_random_init(&rbtdb->random); /* * Version Initialization. diff --git a/lib/isc/include/isc/random.h b/lib/isc/include/isc/random.h index 65a318d170..992fb7d798 100644 --- a/lib/isc/include/isc/random.h +++ b/lib/isc/include/isc/random.h @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: random.h,v 1.7 2000/08/01 01:30:37 tale Exp $ */ +/* $Id: random.h,v 1.8 2000/09/06 02:40:00 explorer Exp $ */ #ifndef ISC_RANDOM_H #define ISC_RANDOM_H 1 @@ -27,65 +27,35 @@ * Implements a random state pool which will let the caller return a * series of possibly non-reproducable random values. Note that the * strength of these numbers is not all that high, and should not be - * used in cryptography functions. + * used in cryptography functions. It is useful to jitter values a bit + * here and there, such as timeouts, etc. */ ISC_LANG_BEGINDECLS -struct isc_random { - unsigned int magic; -#if 0 - isc_mutex_t lock; -#endif -}; - -#define ISC_RANDOM_MAGIC 0x52416e64 /* RAnd. */ -#define ISC_RANDOM_VALID(x) ((x) != NULL && (x->magic) == ISC_RANDOM_MAGIC) - -isc_result_t -isc_random_init(isc_random_t *r); +void +isc_random_seed(isc_uint32_t seed); /* - * Initialize a random state. - * - * This function must be called before using any of the following functions. - * - * Requires: - * r != NULL. - */ - -isc_result_t -isc_random_invalidate(isc_random_t *r); -/* - * Invalidate a random state. This will wipe any information contained in - * the state and make it unusable. - * - * Requires: - * r be a valid pool. + * Set the initial seed of the random state. */ void -isc_random_seed(isc_random_t *r, isc_uint32_t seed); +isc_random_get(isc_uint32_t *val); /* - * Set the initial seed of the random state. Note that on some systems - * the private state isn't all that private, and setting the seed may - * alter numbers returned to other state pools. + * Get a random value. * * Requires: - * r be a valid pool. - */ - -void -isc_random_get(isc_random_t *r, isc_uint32_t *val); -/* - * Get a random value. Note that on some systems the private state isn't - * all that private, and getting a value may alter what other state pools - * would have returned. - * - * Requires: - * r be a valid pool. * val != NULL. */ +isc_uint32_t +isc_random_jitter(isc_uint32_t max, isc_uint32_t min, isc_uint32_t jitter); +/* + * Return a value between (max - jitter) and (max). + * + * If (max - min) < jitter, the maximum jitter becomes (max - min) instead. + */ + ISC_LANG_ENDDECLS #endif /* ISC_RANDOM_H */ diff --git a/lib/isc/random.c b/lib/isc/random.c index 613e153f7b..51da3d5892 100644 --- a/lib/isc/random.c +++ b/lib/isc/random.c @@ -15,7 +15,7 @@ * WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ -/* $Id: random.c,v 1.10 2000/08/26 01:23:14 bwelling Exp $ */ +/* $Id: random.c,v 1.11 2000/09/06 02:39:59 explorer Exp $ */ #include @@ -28,12 +28,11 @@ #include static isc_once_t once = ISC_ONCE_INIT; -static isc_mutex_t rand_lock; static void initialize_rand(void) { - RUNTIME_CHECK(isc_mutex_init(&rand_lock) == ISC_R_SUCCESS); + srand(time(NULL)); } static void @@ -42,75 +41,36 @@ initialize(void) RUNTIME_CHECK(isc_once_do(&once, initialize_rand) == ISC_R_SUCCESS); } -isc_result_t -isc_random_init(isc_random_t *r) -{ - REQUIRE(r != NULL); - - r->magic = ISC_RANDOM_MAGIC; -#if 0 - return (isc_mutex_init(&r->lock)); -#else - return (ISC_R_SUCCESS); -#endif -} - -isc_result_t -isc_random_invalidate(isc_random_t *r) -{ - isc_result_t result; - - REQUIRE(ISC_RANDOM_VALID(r)); - -#if 0 - DESTROYLOCK(&r->lock); - result = ISC_R_SUCCESS; -#else - result = ISC_R_SUCCESS; -#endif - - memset(r, 0, sizeof(isc_random_t)); - - return (result); -} - void -isc_random_seed(isc_random_t *r, isc_uint32_t seed) +isc_random_seed(isc_uint32_t seed) { - REQUIRE(ISC_RANDOM_VALID(r)); - - UNUSED(r); - initialize(); -#if 0 - LOCK(&r->lock); -#endif - LOCK(&rand_lock); srand(seed); - UNLOCK(&rand_lock); -#if 0 - UNLOCK(&r->lock); -#endif } void -isc_random_get(isc_random_t *r, isc_uint32_t *val) +isc_random_get(isc_uint32_t *val) { - REQUIRE(ISC_RANDOM_VALID(r)); REQUIRE(val != NULL); - UNUSED(r); - initialize(); -#if 0 - LOCK(&r->lock); -#endif - LOCK(&rand_lock); *val = rand(); - UNLOCK(&rand_lock); -#if 0 - UNLOCK(&r->lock); -#endif +} + +isc_uint32_t +isc_random_jitter(isc_uint32_t max, isc_uint32_t min, isc_uint32_t jitter) { + isc_uint32_t val; + + REQUIRE(jitter > 0); + + /* + * Don't allow jitter to be more than max - min. + */ + if (jitter > max - min) + jitter = max - min; + + val = rand() % jitter; + return (max - val); }