static _Thread_local fr_randctx fr_rand_pool; //!< A pool of pre-generated random integers
static _Thread_local bool fr_rand_initialized = false;
+void fr_rand_init(void)
+{
+ int fd;
+
+ if (fr_rand_initialized) return;
+
+
+ memset(&fr_rand_pool, 0, sizeof(fr_rand_pool));
+
+ fd = open("/dev/urandom", O_RDONLY);
+ if (fd >= 0) {
+ size_t total;
+ ssize_t this;
+
+ total = 0;
+ while (total < sizeof(fr_rand_pool.randrsl)) {
+ this = read(fd, fr_rand_pool.randrsl,
+ sizeof(fr_rand_pool.randrsl) - total);
+ if ((this < 0) && (errno != EINTR)) break;
+ if (this > 0) total += this;
+ }
+ close(fd);
+ } else {
+ /*
+ * We use unix_time, because fr_time() is
+ * nanoseconds since the server started.
+ * Which is likely a very small number.
+ * Whereas unix time is somewhat more
+ * unknown. If we're not seeding off of
+ * /dev/urandom, then any randomness we
+ * get here is terrible.
+ */
+ int64_t when = fr_unix_time_unwrap(fr_time_to_unix_time(fr_time()));
+
+ memcpy((void *) &fr_rand_pool.randrsl[0], &when, sizeof(when));
+ }
+
+ fr_isaac_init(&fr_rand_pool, 1);
+ fr_rand_pool.randcnt = 0;
+ fr_rand_initialized = true;
+}
+
/** Mix data into the random number generator.
*
* May be called any number of times.
* Ensure that the pool is initialized.
*/
if (!fr_rand_initialized) {
- int fd;
-
- memset(&fr_rand_pool, 0, sizeof(fr_rand_pool));
-
- fd = open("/dev/urandom", O_RDONLY);
- if (fd >= 0) {
- size_t total;
- ssize_t this;
-
- total = 0;
- while (total < sizeof(fr_rand_pool.randrsl)) {
- this = read(fd, fr_rand_pool.randrsl,
- sizeof(fr_rand_pool.randrsl) - total);
- if ((this < 0) && (errno != EINTR)) break;
- if (this > 0) total += this;
- }
- close(fd);
- } else {
- /*
- * We use unix_time, because fr_time() is
- * nanoseconds since the server started.
- * Which is likely a very small number.
- * Whereas unix time is somewhat more
- * unknown. If we're not seeding off of
- * /dev/urandom, then any randomness we
- * get here is terrible.
- */
- int64_t when = fr_unix_time_unwrap(fr_time_to_unix_time(fr_time()));
-
- memcpy((void *) &fr_rand_pool.randrsl[0], &when, sizeof(when));
- }
-
- fr_isaac_init(&fr_rand_pool, 1);
- fr_rand_pool.randcnt = 0;
- fr_rand_initialized = 1;
+ fr_rand_init();
}
- if (!data) return;
-
/*
* Hash the user data
*/
* Ensure that the pool is initialized.
*/
if (!fr_rand_initialized) {
- fr_rand_mixin(NULL, 0);
+ fr_rand_init();
}
num = fr_rand_pool.randrsl[fr_rand_pool.randcnt++];
void fr_isaac_init(fr_randctx *ctx, int flag);
/** @hidecallergraph */
uint32_t fr_rand(void); /* like rand(), but better. */
+
+void fr_rand_init(void);
void fr_rand_buffer(void *start, size_t length) CC_HINT(nonnull);
void fr_rand_str(uint8_t *out, size_t len, char class);
-void fr_rand_mixin(void const *, size_t ); /* seed the random pool */
+void fr_rand_mixin(void const *, size_t ) CC_HINT(nonnull);
uint32_t fr_fast_rand(fr_fast_rand_t *ctx);
#ifdef __cplusplus