mirror of
https://github.com/zeek/zeek.git
synced 2025-10-03 23:28:20 +00:00
Add zeek::max_random() & fix misuse of RAND_MAX w/ zeek::random_number()
In deterministic mode, RAND_MAX is not related to the result of zeek::random_number() (formerly bro_random()), but some logic was using RAND_MAX as indication of the possible range of values. The new zeek::max_random() will give the correct upper-bound regardless of whether deterministic-mode is used.
This commit is contained in:
parent
bde38893ce
commit
d486af06b1
6 changed files with 24 additions and 9 deletions
|
@ -18,7 +18,7 @@ void PacketFilter::AddSrc(const IPAddr& src, uint32_t tcp_flags, double probabil
|
|||
{
|
||||
Filter* f = new Filter;
|
||||
f->tcp_flags = tcp_flags;
|
||||
f->probability = uint32_t(probability * RAND_MAX);
|
||||
f->probability = probability * static_cast<double>(zeek::max_random());
|
||||
auto prev = static_cast<Filter*>(src_filter.Insert(src, 128, f));
|
||||
delete prev;
|
||||
}
|
||||
|
@ -27,7 +27,7 @@ void PacketFilter::AddSrc(zeek::Val* src, uint32_t tcp_flags, double probability
|
|||
{
|
||||
Filter* f = new Filter;
|
||||
f->tcp_flags = tcp_flags;
|
||||
f->probability = uint32_t(probability * RAND_MAX);
|
||||
f->probability = probability * static_cast<double>(zeek::max_random());
|
||||
auto prev = static_cast<Filter*>(src_filter.Insert(src, f));
|
||||
delete prev;
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ void PacketFilter::AddDst(const IPAddr& dst, uint32_t tcp_flags, double probabil
|
|||
{
|
||||
Filter* f = new Filter;
|
||||
f->tcp_flags = tcp_flags;
|
||||
f->probability = uint32_t(probability * RAND_MAX);
|
||||
f->probability = probability * static_cast<double>(zeek::max_random());
|
||||
auto prev = static_cast<Filter*>(dst_filter.Insert(dst, 128, f));
|
||||
delete prev;
|
||||
}
|
||||
|
@ -45,7 +45,7 @@ void PacketFilter::AddDst(zeek::Val* dst, uint32_t tcp_flags, double probability
|
|||
{
|
||||
Filter* f = new Filter;
|
||||
f->tcp_flags = tcp_flags;
|
||||
f->probability = uint32_t(probability * RAND_MAX);
|
||||
f->probability = probability * static_cast<double>(zeek::max_random());
|
||||
auto prev = static_cast<Filter*>(dst_filter.Insert(dst, f));
|
||||
delete prev;
|
||||
}
|
||||
|
@ -113,5 +113,5 @@ bool PacketFilter::MatchFilter(const Filter& f, const IP_Hdr& ip,
|
|||
return false;
|
||||
}
|
||||
|
||||
return uint32_t(zeek::random_number()) < f.probability;
|
||||
return zeek::random_number() < f.probability;
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ public:
|
|||
private:
|
||||
struct Filter {
|
||||
uint32_t tcp_flags;
|
||||
uint32_t probability;
|
||||
double probability;
|
||||
};
|
||||
|
||||
static void DeleteFilter(void* data);
|
||||
|
|
10
src/util.cc
10
src/util.cc
|
@ -1183,13 +1183,21 @@ bool have_random_seed()
|
|||
return bro_rand_determistic;
|
||||
}
|
||||
|
||||
constexpr uint32_t zeek_prng_mod = 2147483647;
|
||||
constexpr uint32_t zeek_prng_max = zeek_prng_mod - 1;
|
||||
|
||||
long int zeek::max_random()
|
||||
{
|
||||
return bro_rand_determistic ? zeek_prng_max : RAND_MAX;
|
||||
}
|
||||
|
||||
long int zeek::prng(long int state)
|
||||
{
|
||||
// Use our own simple linear congruence PRNG to make sure we are
|
||||
// predictable across platforms. (Lehmer RNG, Schrage's method)
|
||||
// Note: the choice of "long int" storage type for the state is mostly
|
||||
// for parity with the possible return values of random().
|
||||
constexpr uint32_t m = 2147483647;
|
||||
constexpr uint32_t m = zeek_prng_mod;
|
||||
constexpr uint32_t a = 16807;
|
||||
constexpr uint32_t q = m / a;
|
||||
constexpr uint32_t r = m % a;
|
||||
|
|
|
@ -604,7 +604,14 @@ long int prng(long int state);
|
|||
* Wrapper for system random() in the default case, but when running in
|
||||
* deterministic mode, uses the platform-independent zeek::prng()
|
||||
* to obtain consistent results since implementations of rand() may vary.
|
||||
* @return A value in the range [0, zeek::max_random()].
|
||||
*/
|
||||
long int random_number();
|
||||
|
||||
/**
|
||||
* @return The maximum value that can be returned from zeek::random_number().
|
||||
* When not using deterministic-mode, this is always equivalent to RAND_MAX.
|
||||
*/
|
||||
long int max_random();
|
||||
|
||||
} // namespace zeek
|
||||
|
|
|
@ -930,7 +930,7 @@ function hrw_weight%(key_digest: count, site_id: count%): count
|
|||
## provided by the OS.
|
||||
function rand%(max: count%): count
|
||||
%{
|
||||
auto result = bro_uint_t(double(max) * double(zeek::random_number()) / (RAND_MAX + 1.0));
|
||||
auto result = bro_uint_t(double(max) * double(zeek::random_number()) / (zeek::max_random() + 1.0));
|
||||
return zeek::val_mgr->Count(result);
|
||||
%}
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ std::string Foo::RandomString(const int len)
|
|||
// zeek::random_number() is not thread-safe; as we are only using one simultaneous thread
|
||||
// here, this should not matter in this case. If this test ever starts showing
|
||||
// random errors, this might be the culprit.
|
||||
s[i] = values[zeek::random_number() / (RAND_MAX / sizeof(values))];
|
||||
s[i] = values[zeek::random_number() / (zeek::max_random() / sizeof(values))];
|
||||
|
||||
return s;
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue