@@ -4110,14 +4110,14 @@ SWITCH_DECLARE(int) switch_split_user_domain(char *in, char **user, char **domai
4110
4110
}
4111
4111
4112
4112
4113
- SWITCH_DECLARE (char * ) switch_uuid_str (char * buf , switch_size_t len )
4113
+ SWITCH_DECLARE (char * ) switch_uuid_str_version (char * buf , switch_size_t len , int version )
4114
4114
{
4115
4115
switch_uuid_t uuid ;
4116
4116
4117
4117
if (len < (SWITCH_UUID_FORMATTED_LENGTH + 1 )) {
4118
4118
switch_snprintf (buf , len , "INVALID" );
4119
4119
} else {
4120
- switch_uuid_get (& uuid );
4120
+ switch_uuid_generate_version (& uuid , version );
4121
4121
switch_uuid_format (buf , & uuid );
4122
4122
}
4123
4123
@@ -4872,6 +4872,100 @@ SWITCH_DECLARE(int) switch_rand(void)
4872
4872
#endif
4873
4873
}
4874
4874
4875
+
4876
+ SWITCH_DECLARE (int ) switch_getentropy (void * buffer , switch_size_t length )
4877
+ {
4878
+ if (!buffer || length > 256 ) { // Enforce same limit as `getentropy`
4879
+ errno = EIO ; // Input/Output error
4880
+ return -1 ;
4881
+ }
4882
+
4883
+ #ifdef WIN32
4884
+ BCRYPT_ALG_HANDLE hAlgorithm = NULL ;
4885
+ NTSTATUS status = BCryptOpenAlgorithmProvider (& hAlgorithm , BCRYPT_RNG_ALGORITHM , NULL , 0 );
4886
+
4887
+ if (!BCRYPT_SUCCESS (status )) {
4888
+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , "BCryptOpenAlgorithmProvider failed with status %d\n" , status );
4889
+ errno = EIO ; // Input/Output error
4890
+ return -1 ;
4891
+ }
4892
+
4893
+ status = BCryptGenRandom (hAlgorithm , (PUCHAR )buffer , (ULONG )length , 0 );
4894
+ if (!BCRYPT_SUCCESS (status )) {
4895
+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , "BCryptGenRandom failed with status %d\n" , status );
4896
+ BCryptCloseAlgorithmProvider (hAlgorithm , 0 );
4897
+ errno = EIO ; // Input/Output error
4898
+ return -1 ;
4899
+ }
4900
+
4901
+ BCryptCloseAlgorithmProvider (hAlgorithm , 0 );
4902
+ return 0 ;
4903
+
4904
+ #elif defined(__unix__ ) || defined(__APPLE__ )
4905
+ int random_fd = open ("/dev/urandom" , O_RDONLY );
4906
+ switch_ssize_t result ;
4907
+ char error_msg [100 ];
4908
+
4909
+ if (random_fd == -1 ) {
4910
+ strncpy (error_msg , strerror (errno ), sizeof (error_msg ) - 1 );
4911
+ error_msg [sizeof (error_msg ) - 1 ] = '\0' ;
4912
+
4913
+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , "open failed: %s\n" , error_msg );
4914
+ errno = EIO ; // Input/Output error
4915
+ return -1 ;
4916
+ }
4917
+
4918
+ result = read (random_fd , buffer , length );
4919
+ if (result < 0 || (switch_size_t )result != length ) {
4920
+ strncpy (error_msg , strerror (errno ), sizeof (error_msg ) - 1 );
4921
+ error_msg [sizeof (error_msg ) - 1 ] = '\0' ;
4922
+
4923
+ switch_log_printf (SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , "read failed: %s\n" , error_msg );
4924
+ close (random_fd );
4925
+ errno = EIO ; // Input/Output error
4926
+ return -1 ;
4927
+ }
4928
+
4929
+ close (random_fd );
4930
+ return 0 ;
4931
+
4932
+ #else
4933
+ // Fallback: Use rand() for platforms that do not support secure randomness
4934
+ unsigned char * buf = (unsigned char * )buffer ;
4935
+ for (switch_size_t i = 0 ; i < length ; i ++ ) {
4936
+ buf [i ] = (unsigned char )(rand () & 0xFF ); // Generate byte-wise randomness
4937
+ }
4938
+ return 0 ;
4939
+ #endif
4940
+ }
4941
+
4942
+
4943
+ SWITCH_DECLARE (switch_status_t ) switch_uuid_generate_v7 (switch_uuid_t * uuid ) {
4944
+ /* random bytes */
4945
+ unsigned char * value = uuid -> data ;
4946
+
4947
+ if (switch_getentropy (value , 16 ) != 0 ) {
4948
+ return -1 ;
4949
+ }
4950
+
4951
+ /* current timestamp in ms */
4952
+ switch_time_t timestamp = switch_time_now () / 1000 ;
4953
+
4954
+ // timestamp
4955
+ value [0 ] = (timestamp >> 40 ) & 0xFF ;
4956
+ value [1 ] = (timestamp >> 32 ) & 0xFF ;
4957
+ value [2 ] = (timestamp >> 24 ) & 0xFF ;
4958
+ value [3 ] = (timestamp >> 16 ) & 0xFF ;
4959
+ value [4 ] = (timestamp >> 8 ) & 0xFF ;
4960
+ value [5 ] = timestamp & 0xFF ;
4961
+
4962
+ // version and variant
4963
+ value [6 ] = (value [6 ] & 0x0F ) | 0x70 ;
4964
+ value [8 ] = (value [8 ] & 0x3F ) | 0x80 ;
4965
+
4966
+ return SWITCH_STATUS_SUCCESS ;
4967
+ }
4968
+
4875
4969
/* For Emacs:
4876
4970
* Local Variables:
4877
4971
* mode:c
0 commit comments