]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
lib/util: add generate_unique_u64() helper function
authorStefan Metzmacher <metze@samba.org>
Tue, 9 Jun 2020 14:19:50 +0000 (16:19 +0200)
committerVolker Lendecke <vl@samba.org>
Wed, 8 Jul 2020 09:42:39 +0000 (09:42 +0000)
Signed-off-by: Stefan Metzmacher <metze@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
lib/util/genrand_util.c
lib/util/samba_util.h

index 05d1f3ef6e5a340338d61008ebc307344f843849..26b52a1c8140f8fa3d75dbffebba9ac638211af0 100644 (file)
@@ -47,7 +47,30 @@ _PUBLIC_ uint64_t generate_random_u64(void)
        return BVAL(v, 0);
 }
 
+static struct generate_unique_u64_state {
+       uint64_t next_value;
+       int pid;
+} generate_unique_u64_state;
 
+_PUBLIC_ uint64_t generate_unique_u64(uint64_t veto_value)
+{
+       int pid = getpid();
+
+       if (unlikely(pid != generate_unique_u64_state.pid)) {
+               generate_unique_u64_state = (struct generate_unique_u64_state) {
+                       .pid = pid,
+                       .next_value = veto_value,
+               };
+       }
+
+       while (unlikely(generate_unique_u64_state.next_value == veto_value)) {
+               generate_nonce_buffer(
+                               (void *)&generate_unique_u64_state.next_value,
+                               sizeof(generate_unique_u64_state.next_value));
+       }
+
+       return generate_unique_u64_state.next_value++;
+}
 
 /**
   Microsoft composed the following rules (among others) for quality
index f0aa42e7271f4fb3974c2f4e59a45fbb8d6e3903..5a81baa80b633b6f1ae69c830285b7ca7ccd44f9 100644 (file)
@@ -94,10 +94,37 @@ _PUBLIC_ int sys_getnameinfo(const struct sockaddr *psa,
 _PUBLIC_ uint32_t generate_random(void);
 
 /**
-  generate a single random uint64_t
+ * generate a single random uint64_t
+ * @see generate_unique_u64
 **/
 _PUBLIC_ uint64_t generate_random_u64(void);
 
+/**
+ * @brief Generate random nonces usable for re-use detection.
+ *
+ * We have a lot of places which require a unique id that can
+ * be used as a unique identitier for caching states.
+ *
+ * Always using generate_nonce_buffer() has it's performance costs,
+ * it's typically much better than generate_random_buffer(), but
+ * still it's overhead we want to avoid in performance critical
+ * workloads.
+ *
+ * We call generate_nonce_buffer() just once per given state
+ * and process.
+ *
+ * This is much lighter than generate_random_u64() and it's
+ * designed for performance critical code paths.
+ *
+ * @veto_value It is garanteed that the return value if different from
+ *             the veto_value.
+ *
+ * @return a unique value per given state and process
+ *
+ * @see generate_random_u64
+ */
+uint64_t generate_unique_u64(uint64_t veto_value);
+
 /**
   very basic password quality checker
 **/