diff --git a/modules/uuid/uuid.c b/modules/uuid/uuid.c index 409bf1f1bf1..4e7a71e7fc9 100644 --- a/modules/uuid/uuid.c +++ b/modules/uuid/uuid.c @@ -27,20 +27,23 @@ #define UUID_STR_BUFSIZE 37 +#define RET_ERR -1 #define RET_OK 1 #define RET_UNSAFE 2 enum uuid_gen_vers { UUID_VERS_0 = 0, /* generate either RFC verison 1 or 4 */ UUID_VERS_1 = 1, + UUID_VERS_3 = 3, UUID_VERS_4 = 4, + UUID_VERS_5 = 5, }; static uuid_t uuid; static char uuid_str[UUID_STR_BUFSIZE]; static int fixup_check_var(void** param); -static int w_uuid(struct sip_msg *msg, pv_spec_t *out_var, int *vers_param); +static int w_uuid(struct sip_msg *msg, pv_spec_t *out_var, int *vers_param, str *namespace_param, str *name_param); static int pv_get_uuid(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); @@ -52,8 +55,10 @@ static pv_export_t mod_items[] = { static cmd_export_t cmds[] = { {"uuid", (cmd_function)w_uuid, { - {CMD_PARAM_VAR, fixup_check_var, 0}, - {CMD_PARAM_INT | CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + {CMD_PARAM_VAR, fixup_check_var,0}, + {CMD_PARAM_INT|CMD_PARAM_OPT,0,0}, + {CMD_PARAM_STR|CMD_PARAM_OPT,0,0}, + {CMD_PARAM_STR|CMD_PARAM_OPT,0,0}, {0,0,0}}, ALL_ROUTES}, {0,0,{{0,0,0}},0} }; @@ -81,9 +86,10 @@ struct module_exports exports= { 0 }; -static int gen_uuid(enum uuid_gen_vers vers, pv_value_t *res) +static int gen_uuid(enum uuid_gen_vers vers, str *ns, str *n, pv_value_t *res) { int rc = RET_OK; + uuid_t ns_uuid; switch (vers) { case UUID_VERS_0: @@ -92,12 +98,31 @@ static int gen_uuid(enum uuid_gen_vers vers, pv_value_t *res) case UUID_VERS_1: rc = uuid_generate_time_safe(uuid) ? RET_UNSAFE : RET_OK; break; + case UUID_VERS_3: + case UUID_VERS_5: + if (!ns) { + LM_ERR("Namespace required for UUID version: %d\n", vers); + return RET_ERR; + } + if (!n) { + LM_ERR("Name required for UUID version: %d\n", vers); + return RET_ERR; + } + if (uuid_parse(ns->s, ns_uuid)) { + LM_ERR("Invalid UUID for namespace: %s\n", ns->s); + return RET_ERR; + } + if (vers == UUID_VERS_3) + uuid_generate_md5(uuid, ns_uuid, n->s, n->len); + else + uuid_generate_sha1(uuid, ns_uuid, n->s, n->len); + break; case UUID_VERS_4: uuid_generate_random(uuid); break; default: LM_BUG("Bad UUID generation algorithm selected\n"); - return -1; + return RET_ERR; } LM_DBG("Generated UUID version: %d\n", uuid_type(uuid)); @@ -128,7 +153,7 @@ static int fixup_check_var(void** param) return 0; } -static int w_uuid(struct sip_msg *msg, pv_spec_t *out_var, int *vers_param) +static int w_uuid(struct sip_msg *msg, pv_spec_t *out_var, int *vers_param, str *namespace_param, str *name_param) { int vers = UUID_VERS_0; int rc; @@ -139,25 +164,26 @@ static int w_uuid(struct sip_msg *msg, pv_spec_t *out_var, int *vers_param) switch (vers) { case 2: - case 3: - case 5: LM_WARN("UUID version: %d not supported! Using default algorithm\n", vers); vers = UUID_VERS_0; break; case UUID_VERS_0: case UUID_VERS_1: + case UUID_VERS_3: case UUID_VERS_4: + case UUID_VERS_5: break; default: LM_ERR("Bad UUID version: %d\n", vers); return -1; } - if ((rc = gen_uuid(vers, &out_val)) == RET_UNSAFE) + rc = gen_uuid(vers, namespace_param, name_param, &out_val); + if (rc == RET_UNSAFE) LM_DBG("Version 1 UUID generated unsafely\n"); - if (pv_set_value(msg, (pv_spec_t*)out_var, 0, &out_val) != 0) { + if (rc != RET_ERR && pv_set_value(msg, (pv_spec_t*)out_var, 0, &out_val) != 0) { LM_ERR("failed to set the output variable!\n"); return -1; }