return status;
}
+SWITCH_DECLARE(int) switch_rand(void)
+{
+ uint32_t random_number = 0;
+#ifdef WIN32
+ BCRYPT_ALG_HANDLE hAlgorithm = NULL;
+ NTSTATUS status = BCryptOpenAlgorithmProvider(&hAlgorithm, BCRYPT_RNG_ALGORITHM, NULL, 0);
+
+ if (!BCRYPT_SUCCESS(status)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "BCryptOpenAlgorithmProvider failed with status %d\n", status);
+
+ return 1;
+ }
+
+ status = BCryptGenRandom(hAlgorithm, (PUCHAR)&random_number, sizeof(random_number), 0);
+ if (!BCRYPT_SUCCESS(status)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "BCryptGenRandom failed with status %d\n", status);
+
+ return 1;
+ }
+
+ BCryptCloseAlgorithmProvider(hAlgorithm, 0);
+
+ /* Make sure we return from 0 to RAND_MAX */
+ return (random_number & 0x7FFF);
+#elif defined(__unix__) || defined(__APPLE__)
+ int random_fd = open("/dev/urandom", O_RDONLY);
+ ssize_t result;
+ char error_msg[100];
+
+ if (random_fd == -1) {
+ strncpy(error_msg, strerror(errno), sizeof(error_msg) - 1);
+ error_msg[sizeof(error_msg) - 1] = '\0';
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open failed: %s\n", error_msg);
+
+ return 1;
+ }
+
+ result = read(random_fd, &random_number, sizeof(random_number));
+ if (result < 0) {
+ strncpy(error_msg, strerror(errno), sizeof(error_msg) - 1);
+ error_msg[sizeof(error_msg) - 1] = '\0';
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read failed: %s\n", error_msg);
+
+ return 1;
+ }
+
+ close(random_fd);
+
+ /* Make sure we return from 0 to RAND_MAX */
+ return (random_number & 0x7FFF);
+#else
+ return rand();
+#endif
+}
+
/* For Emacs:
* Local Variables:
* mode:c
}
FST_TEARDOWN_END()
+ FST_TEST_BEGIN(test_switch_rand)
+ {
+ int i, c = 0;
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "\nLet's generate a few random numbers.\n");
+
+ for (i = 0; i < 10; i++) {
+ uint32_t rnd = switch_rand();
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Random number %d\n", rnd);
+
+ if (rnd == 1) {
+ c++;
+ }
+ }
+
+ /* We do not expect all random numbers to be 1 all 10 times. That would mean we have an error OR we are lucky to have 10 random ones! */
+ fst_check(c < 10);
+ }
+ FST_TEST_END()
+
FST_TEST_BEGIN(test_switch_uint31_t_overflow)
{
switch_uint31_t x;