]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: tools: add a generic function to generate UUIDs
authorWilly Tarreau <w@1wt.eu>
Sun, 8 Mar 2020 16:48:17 +0000 (17:48 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 8 Mar 2020 17:04:16 +0000 (18:04 +0100)
We currently have two UUID generation functions, one for the sample
fetch and the other one in the SPOE filter. Both were a bit complicated
since they were made to support random() implementations returning an
arbitrary number of bits, and were throwing away 33 bits every 64. Now
we don't need this anymore, so let's have a generic function consuming
64 bits at once and use it as appropriate.

include/common/standard.h
src/flt_spoe.c
src/sample.c
src/standard.c

index d8bccbafb65366d7b9b0417161b055b143dd36a9..6e1e840b796a975dc00b3e5bbc7b290f1a0cb84b 100644 (file)
@@ -1551,6 +1551,7 @@ static inline void *my_realloc2(void *ptr, size_t size)
 int parse_dotted_uints(const char *s, unsigned int **nums, size_t *sz);
 
 /* PRNG */
+void ha_generate_uuid(struct buffer *output);
 void ha_random_seed(const unsigned char *seed, size_t len);
 void ha_random_jump96(uint32_t dist);
 uint64_t ha_random64();
index bcdec08e7861f1dfea31ca204aef4385a981b6c7..df080d81666a8fbb0b5d400a5c3081b71d211f22 100644 (file)
@@ -257,33 +257,8 @@ static const char *spoe_appctx_state_str[SPOE_APPCTX_ST_END+1] = {
 static char *
 generate_pseudo_uuid()
 {
-       char *uuid;
-       uint32_t rnd[4] = { 0, 0, 0, 0 };
-       uint64_t last = 0;
-       int byte = 0;
-       uint8_t bits = 0;
-       unsigned int rand_max_bits = my_flsl(RAND_MAX);
-
-       if ((uuid = calloc(1, 37)) == NULL)
-               return NULL;
-
-       while (byte < 4) {
-               while (bits < 32) {
-                       last |= (uint64_t)ha_random() << bits;
-                       bits += rand_max_bits;
-               }
-               rnd[byte++] = last;
-               last >>= 32u;
-               bits  -= 32;
-       }
-       snprintf(uuid, 37, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12llx",
-                            rnd[0],
-                            rnd[1] & 0xFFFF,
-                            ((rnd[1] >> 16u) & 0xFFF) | 0x4000,  // highest 4 bits indicate the uuid version
-                            (rnd[2] & 0x3FFF) | 0x8000,  // the highest 2 bits indicate the UUID variant (10),
-                            (long long)((rnd[2] >> 14u) | ((uint64_t) rnd[3] << 18u)) & 0xFFFFFFFFFFFFull
-                       );
-       return uuid;
+       ha_generate_uuid(&trash);
+       return trash.area;
 }
 
 
index 088da418b8ca609cb1350a832e9855a67616048f..d602887b8fc370740c6acc07e38af9fba61f5034 100644 (file)
@@ -3328,30 +3328,7 @@ static int smp_check_uuid(struct arg *args, char **err)
 static int smp_fetch_uuid(const struct arg *args, struct sample *smp, const char *kw, void *private)
 {
        if (args[0].data.sint == 4 || !args[0].type) {
-               uint32_t rnd[4] = { 0, 0, 0, 0 };
-               uint64_t last = 0;
-               int byte = 0;
-               uint8_t bits = 0;
-               unsigned int rand_max_bits = my_flsl(RAND_MAX);
-
-               while (byte < 4) {
-                       while (bits < 32) {
-                               last |= (uint64_t)ha_random() << bits;
-                               bits += rand_max_bits;
-                       }
-                       rnd[byte++] = last;
-                       last >>= 32u;
-                       bits  -= 32;
-               }
-
-               chunk_printf(&trash, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12llx",
-                            rnd[0],
-                            rnd[1] & 0xFFFF,
-                            ((rnd[1] >> 16u) & 0xFFF) | 0x4000,  // highest 4 bits indicate the uuid version
-                            (rnd[2] & 0x3FFF) | 0x8000,  // the highest 2 bits indicate the UUID variant (10),
-                            (long long)((rnd[2] >> 14u) | ((uint64_t) rnd[3] << 18u)) & 0xFFFFFFFFFFFFull
-                       );
-
+               ha_generate_uuid(&trash);
                smp->data.type = SMP_T_STR;
                smp->flags = SMP_F_VOL_TEST | SMP_F_MAY_CHANGE;
                smp->data.u.str = trash;
index 5ccf44776a66a07b1d0db9bf7ac958ae508449ee..e0ea8328efd04ca6c8a51f5773fca0492ad92a1d 100644 (file)
@@ -4640,6 +4640,31 @@ void ha_random_jump96(uint32_t dist)
        }
 }
 
+/* Generates an RFC4122 UUID into chunk <output> which must be at least 37
+ * bytes large.
+ */
+void ha_generate_uuid(struct buffer *output)
+{
+       uint32_t rnd[4];
+       uint64_t last;
+
+       last = ha_random64();
+       rnd[0] = last;
+       rnd[1] = last >> 32;
+
+       last = ha_random64();
+       rnd[2] = last;
+       rnd[3] = last >> 32;
+
+       chunk_printf(output, "%8.8x-%4.4x-%4.4x-%4.4x-%12.12llx",
+                    rnd[0],
+                    rnd[1] & 0xFFFF,
+                    ((rnd[1] >> 16u) & 0xFFF) | 0x4000,  // highest 4 bits indicate the uuid version
+                    (rnd[2] & 0x3FFF) | 0x8000,  // the highest 2 bits indicate the UUID variant (10),
+                    (long long)((rnd[2] >> 14u) | ((uint64_t) rnd[3] << 18u)) & 0xFFFFFFFFFFFFull);
+}
+
+
 /*
  * Local variables:
  *  c-indent-level: 8