ソースを参照

simplify the API for random values. use a (thread-local) global value in the background

Julius Pfrommer 9 年 前
コミット
27b6c4b30d

+ 9 - 1
doc/datatypes.rst

@@ -89,6 +89,13 @@ An integer value between 0 and 4,294,967,295.
 
   typedef uint32_t UA_UInt32;
 
+The following functions and definitions are used with UA_UInt32.
+
+.. code-block:: c
+
+  /* do not use for cryptographic entropy */
+  UA_EXPORT UA_UInt32 UA_UInt32_random(void);
+
 UA_Int64
 ^^^^^^^^
 
@@ -178,7 +185,8 @@ The following functions and definitions are used with UA_Guid.
 
   UA_Boolean UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2);
 
-  UA_Guid UA_Guid_random(UA_UInt32 *seed);
+  /* do not use for cryptographic entropy */
+  UA_Guid UA_Guid_random();
 
 UA_String
 ^^^^^^^^^

+ 5 - 2
include/ua_types.h

@@ -72,6 +72,9 @@ typedef uint32_t UA_UInt32;
 #define UA_UINT32_MAX 4294967295
 #define UA_UINT32_MIN 0
 
+/* do not use for cryptographic entropy */
+UA_EXPORT UA_UInt32 UA_UInt32_random(void);
+
 /** Int64: An integer value between -10 223 372 036 854 775 808 and 9 223 372 036 854 775 807 */
 typedef int64_t UA_Int64;
 #define UA_INT64_MAX (int64_t)9223372036854775807
@@ -146,7 +149,8 @@ typedef struct {
 
 UA_Boolean UA_EXPORT UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2);
 
-UA_Guid UA_EXPORT UA_Guid_random(UA_UInt32 *seed);
+/* do not use for cryptographic entropy */
+UA_Guid UA_EXPORT UA_Guid_random(void);
 
 /************************************/
 /* ByteString: A sequence of octets */
@@ -651,7 +655,6 @@ typedef enum {
  * initialized for every thread in the server/client.
  */
 UA_EXPORT void UA_random_seed(UA_UInt64 seed);
-UA_EXPORT UA_UInt32 UA_random(void);
 
 #ifdef __cplusplus
 } // extern "C"

+ 2 - 2
src/server/ua_server.c

@@ -461,8 +461,8 @@ UA_Server * UA_Server_new(UA_ServerConfig config) {
     UA_RCU_LOCK();
 #endif
 
-    // random seed
-    server->random_seed = (UA_UInt32)UA_DateTime_now();
+    /* uncomment for non-reproducible server runs */
+    //UA_random_seed(UA_DateTime_now());
 
     // mockup application description
     UA_ApplicationDescription_init(&server->description);

+ 0 - 1
src/server/ua_server_internal.h

@@ -30,7 +30,6 @@ struct UA_Server {
     /* Config */
     UA_ServerConfig config;
     UA_Logger logger;
-    UA_UInt32 random_seed;
 
     /* Meta */
     UA_DateTime startTime;

+ 2 - 2
src/server/ua_server_worker.c

@@ -291,7 +291,7 @@ UA_StatusCode UA_Server_addRepeatedJob(UA_Server *server, UA_Job job, UA_UInt32
     arw->interval = interval;
     arw->job.job = job;
     if(jobId) {
-        arw->job.id = UA_Guid_random(&server->random_seed);
+        arw->job.id = UA_Guid_random();
         *jobId = arw->job.id;
     } else
         UA_Guid_init(&arw->job.id);
@@ -310,7 +310,7 @@ UA_StatusCode UA_Server_addRepeatedJob(UA_Server *server, UA_Job job, UA_UInt32
     arw.interval = interval;
     arw.job.job = job;
     if(jobId) {
-        arw.job.id = UA_Guid_random(&server->random_seed);
+        arw.job.id = UA_Guid_random();
         *jobId = arw.job.id;
     } else
         UA_Guid_init(&arw.job.id);

+ 1 - 2
src/server/ua_services_view.c

@@ -350,8 +350,7 @@ Service_Browse_single(UA_Server *server, UA_Session *session, struct Continuatio
         cp->maxReferences = maxrefs;
         cp->continuationIndex = referencesCount;
         UA_Guid *ident = UA_Guid_new();
-        UA_UInt32 seed = (uintptr_t)cp;
-        *ident = UA_Guid_random(&seed);
+        *ident = UA_Guid_random();
         cp->identifier.data = (UA_Byte*)ident;
         cp->identifier.length = sizeof(UA_Guid);
         UA_ByteString_copy(&cp->identifier, &result->continuationPoint);

+ 1 - 2
src/server/ua_session_manager.c

@@ -62,8 +62,7 @@ UA_SessionManager_createSession(UA_SessionManager *sessionManager, UA_SecureChan
     sessionManager->currentSessionCount++;
     UA_Session_init(&newentry->session);
     newentry->session.sessionId = UA_NODEID_NUMERIC(1, sessionManager->lastSessionId++);
-    UA_UInt32 randSeed = (UA_UInt32)(sessionManager->lastSessionId + UA_DateTime_now());
-    newentry->session.authenticationToken = UA_NODEID_GUID(1, UA_Guid_random(&randSeed));
+    newentry->session.authenticationToken = UA_NODEID_GUID(1, UA_Guid_random());
 
     if(request->requestedSessionTimeout <= sessionManager->maxSessionLifeTime &&
        request->requestedSessionTimeout > 0)

+ 1 - 28
src/server/ua_subscription_manager.c

@@ -16,34 +16,7 @@ void SubscriptionManager_init(UA_Session *session) {
     manager->globalQueueSize = (UA_UInt32_BoundedValue) { .maxValue = 100, .minValue = 0, .currentValue=0 };
     LIST_INIT(&manager->serverSubscriptions);
     manager->lastSessionID = (UA_UInt32) UA_DateTime_now();
-    
-    // Initialize a GUID with a 2^64 time dependant part, then fold the time in on itself to provide a more randomish
-    // Counter
-    // NOTE: On a 32 bit plattform, assigning 64 bit (2 regs) is allowed by the compiler, but shifting though multiple
-    //       regs is usually not. To support both 32 and 64bit, the struct splits the 64Bit timestamp into two parts.
-    typedef union {
-        struct {
-            UA_UInt32 ui32h;
-            UA_UInt32 ui32l;
-        } individual;
-        UA_UInt64 ui64;
-    } guidInit;
-    guidInit guidInitH;
-    guidInitH.ui64 = (UA_UInt64) UA_DateTime_now();
-    manager->lastJobGuid.data1 = guidInitH.individual.ui32h;
-    manager->lastJobGuid.data2 = (UA_UInt16) (guidInitH.individual.ui32l >> 16);
-    manager->lastJobGuid.data3 = (UA_UInt16) (guidInitH.individual.ui32l);
-
-    guidInit guidInitL;
-    guidInitL.ui64 = (UA_UInt64) UA_DateTime_now();
-    manager->lastJobGuid.data4[0] = (UA_Byte) guidInitL.individual.ui32l;
-    manager->lastJobGuid.data4[1] = (UA_Byte) (guidInitL.individual.ui32l >> 8);
-    manager->lastJobGuid.data4[2] = (UA_Byte) (guidInitL.individual.ui32l >> 16);
-    manager->lastJobGuid.data4[3] = (UA_Byte) (guidInitL.individual.ui32l >> 24);
-    manager->lastJobGuid.data4[4] = (UA_Byte) (manager->lastJobGuid.data4[0]) ^ (guidInitL.individual.ui32h);
-    manager->lastJobGuid.data4[5] = (UA_Byte) (manager->lastJobGuid.data4[0]) ^ (guidInitL.individual.ui32h >> 8);
-    manager->lastJobGuid.data4[6] = (UA_Byte) (manager->lastJobGuid.data4[1]) ^ (guidInitL.individual.ui32h >> 16);
-    manager->lastJobGuid.data4[7] = (UA_Byte) (manager->lastJobGuid.data4[0]) ^ (guidInitL.individual.ui32h >> 24);
+    manager->lastJobGuid = UA_Guid_random();
 }
 
 void SubscriptionManager_deleteMembers(UA_Session *session, UA_Server *server) {

+ 6 - 5
src/ua_types.c

@@ -23,13 +23,14 @@ UA_EXPORT void UA_random_seed(UA_UInt64 seed) {
     pcg32_srandom_r(&UA_rng, seed, UA_DateTime_now());
 }
 
-UA_EXPORT UA_UInt32 UA_random(void) {
-    return (UA_UInt32)pcg32_random_r(&UA_rng);
-}
-
 /*****************/
 /* Builtin Types */
 /*****************/
+
+UA_EXPORT UA_UInt32 UA_UInt32_random(void) {
+    return (UA_UInt32)pcg32_random_r(&UA_rng);
+}
+
 UA_String UA_String_fromChars(char const src[]) {
     UA_String str = UA_STRING_NULL;
     size_t length = strlen(src);
@@ -149,7 +150,7 @@ UA_Boolean UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2) {
     return UA_FALSE;
 }
 
-UA_Guid UA_Guid_random(UA_UInt32 *seed) {
+UA_Guid UA_Guid_random(void) {
     UA_Guid result;
     result.data1 = (UA_UInt32)pcg32_random_r(&UA_rng);
     UA_UInt32 r = (UA_UInt32)pcg32_random_r(&UA_rng);