diff --git a/src/flt_spoe.c b/src/flt_spoe.c index f0047d4d9..114ecf39b 100644 --- a/src/flt_spoe.c +++ b/src/flt_spoe.c @@ -256,30 +256,32 @@ static const char *spoe_appctx_state_str[SPOE_APPCTX_ST_END+1] = { static char * generate_pseudo_uuid() { - static int init = 0; - - const char uuid_fmt[] = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx"; - const char uuid_chr[] = "0123456789ABCDEF-"; char *uuid; - int i; + 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, sizeof(uuid_fmt))) == NULL) + if ((uuid = calloc(1, 37)) == NULL) return NULL; - if (!init) { - srand(now_ms * pid); - init = 1; - } - - for (i = 0; i < sizeof(uuid_fmt)-1; i++) { - int r = rand () % 16; - - switch (uuid_fmt[i]) { - case 'x' : uuid[i] = uuid_chr[r]; break; - case 'y' : uuid[i] = uuid_chr[(r & 0x03) | 0x08]; break; - default : uuid[i] = uuid_fmt[i]; break; + while (byte < 4) { + while (bits < 32) { + last |= (uint64_t)random() << bits; + bits += rand_max_bits; } + rnd[byte++] = last; + last >>= 32u; + bits -= 32; } + snprintf(uuid, 36, "%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; } @@ -3120,6 +3122,7 @@ spoe_init_per_thread(struct proxy *p, struct flt_conf *fconf) struct spoe_agent *agent = conf->agent; if (agent->engine_id == NULL) { + srandom(now_ms * pid); agent->engine_id = generate_pseudo_uuid(); if (agent->engine_id == NULL) return -1;