diff --git a/modules/uuid/doc/uuid_admin.xml b/modules/uuid/doc/uuid_admin.xml index 8898a58c6da..606db29b3d8 100644 --- a/modules/uuid/doc/uuid_admin.xml +++ b/modules/uuid/doc/uuid_admin.xml @@ -116,6 +116,10 @@ xlog("generated uuid: $uuid\n"); generated by hashing a namespace identifier and name via SHA-1. + + 7 - version 7 UUID + generated by timestamp and randomness. + diff --git a/modules/uuid/uuid.c b/modules/uuid/uuid.c index 5eeec99e2b0..593a512cab5 100644 --- a/modules/uuid/uuid.c +++ b/modules/uuid/uuid.c @@ -23,6 +23,7 @@ #include "../../mod_fix.h" #include "../../dprint.h" +#include #include #define UUID_STR_BUFSIZE 37 @@ -37,6 +38,7 @@ enum uuid_gen_vers { UUID_VERS_3 = 3, UUID_VERS_4 = 4, UUID_VERS_5 = 5, + UUID_VERS_7 = 7, }; static uuid_t uuid; @@ -86,6 +88,34 @@ struct module_exports exports= { 0 }; +static int gen_uuidv7(uuid_t value) { + // random bytes + if (getentropy(value, 16) != 0) { + return -1; + } + + // current timestamp in ms + struct timeval tv; + if (gettimeofday(&tv, NULL) != 0) + return -1; + + uint64_t timestamp = (uint64_t)tv.tv_sec * 1000 + tv.tv_usec / 1000; + + // timestamp + value[0] = (timestamp >> 40) & 0xFF; + value[1] = (timestamp >> 32) & 0xFF; + value[2] = (timestamp >> 24) & 0xFF; + value[3] = (timestamp >> 16) & 0xFF; + value[4] = (timestamp >> 8) & 0xFF; + value[5] = timestamp & 0xFF; + + // version and variant + value[6] = (value[6] & 0x0F) | 0x70; + value[8] = (value[8] & 0x3F) | 0x80; + + return RET_OK; +} + static int gen_uuid(enum uuid_gen_vers vers, str *ns, str *n, pv_value_t *res) { int rc = RET_OK; @@ -133,6 +163,9 @@ static int gen_uuid(enum uuid_gen_vers vers, str *ns, str *n, pv_value_t *res) case UUID_VERS_4: uuid_generate_random(uuid); break; + case UUID_VERS_7: + rc = gen_uuidv7(uuid); + break; default: LM_BUG("Bad UUID generation algorithm selected\n"); return RET_ERR; @@ -193,6 +226,7 @@ static int w_uuid(struct sip_msg *msg, pv_spec_t *out_var, int *vers_param, str case UUID_VERS_3: #endif case UUID_VERS_4: + case UUID_VERS_7: #ifdef UUID_TYPE_DCE_SHA1 case UUID_VERS_5: #endif