LCOV - code coverage report
Current view: top level - datadog - random.cpp (source / functions) Hit Total Coverage
Test: filtered.info Lines: 30 31 96.8 %
Date: 2024-01-03 20:30:12 Functions: 5 6 83.3 %

          Line data    Source code
       1             : #include "random.h"
       2             : 
       3             : #include <bitset>
       4             : #include <random>
       5             : 
       6             : #include "hex.h"
       7             : #include "platform_util.h"
       8             : 
       9             : namespace datadog {
      10             : namespace tracing {
      11             : namespace {
      12             : 
      13             : extern "C" void on_fork();
      14             : 
      15             : class Uint64Generator {
      16             :   std::mt19937_64 generator_;
      17             :   std::uniform_int_distribution<std::uint64_t> distribution_;
      18             : 
      19             :  public:
      20           1 :   Uint64Generator() {
      21           1 :     seed_with_random();
      22             :     // If a process links to this library and then calls `fork`, the
      23             :     // `generator_` in the parent and child processes will produce the exact
      24             :     // same sequence of values, which is bad.
      25             :     // A subsequent call to `exec` would remedy this, but nginx in particular
      26             :     // does not call `exec` after forking its worker processes.
      27             :     // So, we use `at_fork_in_child` to re-seed `generator_` in the child
      28             :     // process after `fork`.
      29           1 :     (void)at_fork_in_child(&on_fork);
      30           1 :   }
      31             : 
      32       85054 :   std::uint64_t operator()() { return distribution_(generator_); }
      33             : 
      34           1 :   void seed_with_random() { generator_.seed(std::random_device{}()); }
      35             : };
      36             : 
      37             : thread_local Uint64Generator thread_local_generator;
      38             : 
      39           0 : void on_fork() { thread_local_generator.seed_with_random(); }
      40             : 
      41             : }  // namespace
      42             : 
      43       85054 : std::uint64_t random_uint64() { return thread_local_generator(); }
      44             : 
      45        1072 : std::string uuid() {
      46             :   // clang-format off
      47             :   // It's not all random.  From most significant to least significant, the
      48             :   // bits look like this:
      49             :   //
      50             :   //     xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx 0100xxxx xxxxxxxx 10xxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx xxxxxxxx
      51             :   //
      52             :   // where the "0" and "1" are hard-coded bits, and all of the "x" are random.
      53             :   // See RFC 4122 for more information.
      54             :   // clang-format on
      55        1072 :   std::bitset<64> high = random_uint64();
      56        1072 :   std::bitset<64> low = random_uint64();
      57             : 
      58             :   // Set "0100" for the most significant bits of the
      59             :   // second-to-least-significant byte of `high`.
      60        1072 :   high[15] = 0;
      61        1072 :   high[14] = 1;
      62        1072 :   high[13] = 0;
      63        1072 :   high[12] = 0;
      64             : 
      65             :   // Set "10" for the most significant bits of `low`.
      66        1072 :   low[63] = 1;
      67        1072 :   low[62] = 0;
      68             : 
      69        1072 :   std::string result;
      70        1072 :   std::string hexed = hex_padded(high.to_ullong());
      71        1072 :   result += hexed.substr(0, 8);
      72        1072 :   result += '-';
      73        1072 :   result += hexed.substr(8, 4);
      74        1072 :   result += '-';
      75        1072 :   result += hexed.substr(12);
      76        1072 :   result += '-';
      77        1072 :   hexed = hex_padded(low.to_ullong());
      78        1072 :   result += hexed.substr(0, 4);
      79        1072 :   result += '-';
      80        1072 :   result += hexed.substr(4);
      81             : 
      82        2144 :   return result;
      83        1072 : }
      84             : 
      85             : }  // namespace tracing
      86             : }  // namespace datadog

Generated by: LCOV version 1.16