|
16 | 16 |
|
17 | 17 | #include "random.hpp" |
18 | 18 |
|
| 19 | +#include "cassconfig.hpp" |
19 | 20 | #include "cassandra.h" |
20 | 21 | #include "logger.hpp" |
21 | 22 | #include "scoped_lock.hpp" |
|
27 | 28 | #include <Windows.h> |
28 | 29 | #include <WinCrypt.h> |
29 | 30 | #else |
| 31 | +#if defined(HAVE_GETRANDOM) |
| 32 | +#include <syscall.h> |
| 33 | +#include <linux/random.h> |
| 34 | +#endif |
30 | 35 | #include <errno.h> |
31 | 36 | #include <fcntl.h> |
32 | 37 | #include <unistd.h> |
| 38 | +#include <stdlib.h> |
33 | 39 | #include <string.h> |
34 | 40 | #include <sys/types.h> |
35 | 41 | #include <sys/uio.h> |
@@ -84,33 +90,54 @@ uint64_t Random::next(uint64_t max) { |
84 | 90 | #endif |
85 | 91 |
|
86 | 92 | uint64_t get_random_seed(uint64_t seed) { |
| 93 | +#if defined(HAVE_ARC4RANDOM) |
| 94 | + arc4random_buf(&seed, sizeof(seed)); |
| 95 | +#else |
87 | 96 | static const char* device = "/dev/urandom"; |
88 | | - |
89 | | - int fd = open(device, O_RDONLY); |
90 | | - |
91 | | - if (fd < 0) { |
| 97 | + ssize_t num_bytes; |
| 98 | + bool readurandom = true; |
| 99 | +#if defined(HAVE_GETRANDOM) |
| 100 | + num_bytes = static_cast<ssize_t>(syscall(SYS_getrandom, &seed, |
| 101 | + sizeof(seed), GRND_NONBLOCK)); |
| 102 | + if (num_bytes < static_cast<ssize_t>(sizeof(seed))) { |
92 | 103 | char buf[STRERROR_BUFSIZE_]; |
93 | 104 | char* err = STRERROR_R_(errno, buf, sizeof(buf)); |
94 | | - LOG_CRITICAL("Unable to open random device (%s): %s", device, err); |
95 | | - return seed; |
| 105 | + LOG_WARN("Unable to read %u random bytes (%s): %u read", |
| 106 | + static_cast<unsigned int>(sizeof(seed)), err, |
| 107 | + static_cast<unsigned int>(num_bytes)); |
| 108 | + } else { |
| 109 | + readurandom = false; |
96 | 110 | } |
97 | | - |
98 | | - ssize_t num_bytes = read(fd, reinterpret_cast<char*>(&seed), sizeof(seed)); |
99 | | - if (num_bytes < 0) { |
100 | | - char buf[STRERROR_BUFSIZE_]; |
101 | | - char* err = STRERROR_R_(errno, buf, sizeof(buf)); |
102 | | - LOG_CRITICAL("Unable to read from random device (%s): %s", device, err); |
103 | | - } else if (num_bytes != sizeof(seed)) { |
104 | | - char buf[STRERROR_BUFSIZE_]; |
105 | | - char* err = STRERROR_R_(errno, buf, sizeof(buf)); |
106 | | - LOG_CRITICAL("Unable to read full seed value (expected: %u read: %u) " |
107 | | - "from random device (%s): %s", |
108 | | - static_cast<unsigned int>(sizeof(seed)), |
109 | | - static_cast<unsigned int>(num_bytes), |
110 | | - device, err); |
| 111 | +#endif // defined(HAVE_GETRANDOM) |
| 112 | + |
| 113 | + if (readurandom) { |
| 114 | + int fd = open(device, O_RDONLY); |
| 115 | + |
| 116 | + if (fd < 0) { |
| 117 | + char buf[STRERROR_BUFSIZE_]; |
| 118 | + char* err = STRERROR_R_(errno, buf, sizeof(buf)); |
| 119 | + LOG_CRITICAL("Unable to open random device (%s): %s", device, err); |
| 120 | + return seed; |
| 121 | + } |
| 122 | + |
| 123 | + num_bytes = read(fd, reinterpret_cast<char*>(&seed), sizeof(seed)); |
| 124 | + if (num_bytes < 0) { |
| 125 | + char buf[STRERROR_BUFSIZE_]; |
| 126 | + char* err = STRERROR_R_(errno, buf, sizeof(buf)); |
| 127 | + LOG_CRITICAL("Unable to read from random device (%s): %s", device, err); |
| 128 | + } else if (num_bytes != sizeof(seed)) { |
| 129 | + char buf[STRERROR_BUFSIZE_]; |
| 130 | + char* err = STRERROR_R_(errno, buf, sizeof(buf)); |
| 131 | + LOG_CRITICAL("Unable to read full seed value (expected: %u read: %u) " |
| 132 | + "from random device (%s): %s", |
| 133 | + static_cast<unsigned int>(sizeof(seed)), |
| 134 | + static_cast<unsigned int>(num_bytes), |
| 135 | + device, err); |
| 136 | + } |
| 137 | + |
| 138 | + close(fd); |
111 | 139 | } |
112 | | - |
113 | | - close(fd); |
| 140 | +#endif // defined(HAVE_ARC4RANDOM) |
114 | 141 |
|
115 | 142 | return seed; |
116 | 143 | } |
|
0 commit comments