diff --git a/src/PacketFilter.cc b/src/PacketFilter.cc index 7b0ef0fbee..c1c496235d 100644 --- a/src/PacketFilter.cc +++ b/src/PacketFilter.cc @@ -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(zeek::max_random()); auto prev = static_cast(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(zeek::max_random()); auto prev = static_cast(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(zeek::max_random()); auto prev = static_cast(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(zeek::max_random()); auto prev = static_cast(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; } diff --git a/src/PacketFilter.h b/src/PacketFilter.h index a485b604e8..c450120ee4 100644 --- a/src/PacketFilter.h +++ b/src/PacketFilter.h @@ -34,7 +34,7 @@ public: private: struct Filter { uint32_t tcp_flags; - uint32_t probability; + double probability; }; static void DeleteFilter(void* data); diff --git a/src/util.cc b/src/util.cc index cccc65db8c..ff488226c3 100644 --- a/src/util.cc +++ b/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; diff --git a/src/util.h b/src/util.h index e30b7650e5..c699204915 100644 --- a/src/util.h +++ b/src/util.h @@ -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 diff --git a/src/zeek.bif b/src/zeek.bif index 253e2d8822..1d09e4bddf 100644 --- a/src/zeek.bif +++ b/src/zeek.bif @@ -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); %} diff --git a/testing/btest/plugins/reader-plugin/src/Foo.cc b/testing/btest/plugins/reader-plugin/src/Foo.cc index 6cae03ca18..a7e5021932 100644 --- a/testing/btest/plugins/reader-plugin/src/Foo.cc +++ b/testing/btest/plugins/reader-plugin/src/Foo.cc @@ -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; }