Fix inconsistencies in random number generation.

The srand()/rand() interface was being intermixed with the
srandom()/random() one.  The later is now used throughout.

Changed the srand() and rand() BIFs to work deterministically if Bro
was given a seed file (addresses #825).  They also now wrap the
system's srandom() and random() instead of srand() and rand() as per
the above.
This commit is contained in:
Jon Siwek 2012-06-29 16:24:31 -05:00
parent 0e48fda6ff
commit 34ead91f99
7 changed files with 45 additions and 22 deletions

View file

@ -972,12 +972,12 @@ function sha256_hash_finish%(index: any%): string
##
## .. note::
##
## This function is a wrapper about the function ``rand`` provided by
## the OS.
## This function is a wrapper about the function ``random``
## provided by the OS.
function rand%(max: count%): count
%{
int result;
result = bro_uint_t(double(max) * double(rand()) / (RAND_MAX + 1.0));
result = bro_uint_t(double(max) * double(bro_random()) / (RAND_MAX + 1.0));
return new Val(result, TYPE_COUNT);
%}
@ -989,11 +989,11 @@ function rand%(max: count%): count
##
## .. note::
##
## This function is a wrapper about the function ``srand`` provided
## by the OS.
## This function is a wrapper about the function ``srandom``
## provided by the OS.
function srand%(seed: count%): any
%{
srand(seed);
bro_srandom(seed);
return 0;
%}

View file

@ -59,7 +59,7 @@ string Benchmark::RandomString(const int len)
"abcdefghijklmnopqrstuvwxyz";
for (int i = 0; i < len; ++i)
s[i] = values[rand() / (RAND_MAX / sizeof(values))];
s[i] = values[random() / (RAND_MAX / sizeof(values))];
return s;
}
@ -134,7 +134,7 @@ threading::Value* Benchmark::EntryToVal(TypeTag type, TypeTag subtype)
break;
case TYPE_INT:
val->val.int_val = rand();
val->val.int_val = random();
break;
case TYPE_TIME:
@ -148,11 +148,11 @@ threading::Value* Benchmark::EntryToVal(TypeTag type, TypeTag subtype)
case TYPE_COUNT:
case TYPE_COUNTER:
val->val.uint_val = rand();
val->val.uint_val = random();
break;
case TYPE_PORT:
val->val.port_val.port = rand() / (RAND_MAX / 60000);
val->val.port_val.port = random() / (RAND_MAX / 60000);
val->val.port_val.proto = TRANSPORT_UNKNOWN;
break;
@ -175,7 +175,7 @@ threading::Value* Benchmark::EntryToVal(TypeTag type, TypeTag subtype)
// Then - common stuff
{
// how many entries do we have...
unsigned int length = rand() / (RAND_MAX / 15);
unsigned int length = random() / (RAND_MAX / 15);
Value** lvals = new Value* [length];

View file

@ -633,12 +633,20 @@ static bool write_random_seeds(const char* write_file, uint32 seed,
static bool bro_rand_determistic = false;
static unsigned int bro_rand_state = 0;
static void bro_srand(unsigned int seed, bool deterministic)
static void bro_srandom(unsigned int seed, bool deterministic)
{
bro_rand_state = seed;
bro_rand_determistic = deterministic;
srand(seed);
srandom(seed);
}
void bro_srandom(unsigned int seed)
{
if ( bro_rand_determistic )
bro_rand_state = seed;
else
srandom(seed);
}
void init_random_seed(uint32 seed, const char* read_file, const char* write_file)
@ -705,7 +713,7 @@ void init_random_seed(uint32 seed, const char* read_file, const char* write_file
seeds_done = true;
}
bro_srand(seed, seeds_done);
bro_srandom(seed, seeds_done);
if ( ! hmac_key_set )
{

View file

@ -159,6 +159,10 @@ extern bool have_random_seed();
// predictable PRNG.
long int bro_random();
// Calls the system srandom() function with the given seed if not running
// in deterministic mode, else it updates the state of the deterministic PRNG
void bro_srandom(unsigned int seed);
extern uint64 rand64bit();
// Each event source that may generate events gets an internally unique ID.

View file

@ -1,6 +1,6 @@
185
236
805
47
996
498
985
474
738
4
634
473

View file

@ -0,0 +1,6 @@
985
474
738
974
371
638

View file

@ -1,6 +1,10 @@
#
# @TEST-EXEC: bro %INPUT >out
# @TEST-EXEC: bro -b %INPUT >out
# @TEST-EXEC: bro -b %INPUT do_seed=F >out.2
# @TEST-EXEC: btest-diff out
# @TEST-EXEC: btest-diff out.2
const do_seed = T &redef;
event bro_init()
{
@ -12,6 +16,7 @@ event bro_init()
print b;
print c;
if ( do_seed )
srand(575);
local d = rand(1000);