diff --git a/modules/enum/doc/enum_admin.xml b/modules/enum/doc/enum_admin.xml index f8ef2fc9347..01553e5673b 100644 --- a/modules/enum/doc/enum_admin.xml +++ b/modules/enum/doc/enum_admin.xml @@ -261,49 +261,29 @@ modparam("enum", "bl_algorithm", "txt") Exported Functions
- <function moreinfo="none">enum_query(["suffix"[,"service"]])</function> + <function moreinfo="none">enum_query([number], [suffix], [service])</function> - The function performs an enum query and rewrites the Request-URI with + The function performs an ENUM query on a given E.164 "number" (or R-URI + username if "number" is missing) and rewrites the Request-URI with the result of the query. See for more information. Meaning of the parameters is as follows: - suffix - Suffix to be appended to the - domain name. The suffix parameter can have the - following types: + number (string, optional) - an E.164 number + packed as a string on which the ENUM query is performed - - - string - the suffix is statically - assigned - - - - pvar - the suffix is the value of an - existing pseudo-variable (as string value) - - - - service - Service string to be used in - the service field. + suffix (string, optional) - suffix to be appended to the + domain name, if missing + + + service (string, optional) - service string to be used in + the service field - - - string - the service is statically - assigned - - - - pvar - the service is the value of an - existing pseudo-variable (as string value) - - - @@ -314,106 +294,59 @@ modparam("enum", "bl_algorithm", "txt") ... # search for "e2u+sip" in freenum.org -enum_query("freenum.org."); +enum_query($avp(number), "freenum.org."); ... # search for "e2u+sip" in default tree (configured as parameter) enum_query(); ... # search for "e2u+voice:sip" in e164.arpa -enum_query("e164.arpa.","voice"); +enum_query(, "e164.arpa.", "voice"); ... # search for service type "sip" or "voice:sip" or "video:sip" # note the '+' sign in front of the second parameter -enum_query("e164.arpa.","+sip+voice:sip+video:sip"); +enum_query($avp(number), "e164.arpa.", "+sip+voice:sip+video:sip"); ... # quering for service sip and voice:sip -enum_query("e164.arpa."); -enum_query("e164.arpa.","voice"); +enum_query(, "e164.arpa."); +enum_query(, "e164.arpa.", "voice"); # or use instead -enum_query("e164.arpa.","+sip+voice:sip"); +enum_query(, "e164.arpa.", "+sip+voice:sip"); ...
-
- - <function moreinfo="none">enum_pv_query("pvar"[,"suffix"[,"service"]])</function> - - - The function performs an enum query on E.164 number stored - in its pseudo variable argument and rewrites the Request-URI with - the result of the query. See for more - information. - +
+ + <function moreinfo="none">i_enum_query([suffix], [service])</function> + + + The function performs an enum query and rewrites the Request-URI with + the result of the query. This the Infrastructure-ENUM version of enum_query(). + The only difference to enum_query() is in the calculation of the + FQDN where NAPTR records are looked for. + Meaning of the parameters is as follows: - pvar - Pseudo - variable that holds an E.164 number on which enum - query is performed. - + suffix (string, optional) - suffix to be appended to the + domain name, if missing - suffix - Suffix to be appended to the - domain name. - - - - service - Service string to be used in - the service field. + service (string, optional) - service string to be used in + the service field - - This function can be used from REQUEST_ROUTE. - - - <function moreinfo="none">enum_pv_query</function> usage - -... -# search for "e2u+sip" in freenum.org -enum_pv_query("$avp(100)", "freenum.org."); -... -# search for "e2u+sip" in default tree (configured as parameter) -enum_pv_query("$fU"); -... -# search for "e2u+voice:sip" in e164.arpa -enum_pv_query("$avp(100)","e164.arpa.","voice"); -... -# search for service type "sip" or "voice:sip" or "video:sip" -# note the '+' sign in front of the second parameter -enum_pv_query("$fU","e164.arpa.","+sip+voice:sip+video:sip"); -... -# quering for service sip and voice:sip -enum_pv_query("$avp(100)","e164.arpa."); -enum_pv_query("$avp(100)","e164.arpa.","voice"); -# or use instead -enum_pv_query("$avp(100)","e164.arpa.","+sip+voice:sip"); -... - - -
- -
- - <function moreinfo="none">i_enum_query(["suffix"[,"service"]])</function> - - - The function performs an enum query and rewrites the Request-URI with - the result of the query. This the Infrastructure-ENUM version of enum_query(). - The only difference to enum_query() is in the calculation of the - FQDN where NAPTR records are looked for. - - - See ftp://ftp.rfc-editor.org/in-notes/internet-drafts/draft-haberler-carrier-enum-01.txt - for the rationale behind this function. - + + See ftp://ftp.rfc-editor.org/in-notes/internet-drafts/draft-haberler-carrier-enum-01.txt + for the rationale behind this function. +
- <function moreinfo="none">isn_query(["suffix"[,"service"]])</function> + <function moreinfo="none">isn_query([suffix], [service])</function> The function performs a ISN query and rewrites the Request-URI with @@ -423,13 +356,13 @@ enum_pv_query("$avp(100)","e164.arpa.","+sip+voice:sip"); Meaning of the parameters is as follows: - suffix - Suffix to be appended to the - domain name. + suffix (string, optional) - suffix to be appended to the + domain name, if missing - service - Service string to be used in - the service field. + service (string, optional) - service string to be used in + the service field @@ -452,19 +385,31 @@ isn_query("freenum.org."); isn_query(); ... # search for "e2u+voice:sip" in freenum.org -isn_query("freenum.org.","voice"); +isn_query("freenum.org.", "voice"); ...
- <function moreinfo="none">is_from_user_enum()</function> + <function moreinfo="none">is_from_user_enum([suffix], [service])</function> Checks if the user part of from URI is found in an enum lookup. Returns 1 if yes and -1 if not. + Meaning of the parameters is as follows: + + + suffix (string, optional) - suffix to be appended to the + domain name, if missing + + + service (string, optional) - service string to be used in + the service field + + + This function can be used from REQUEST_ROUTE. diff --git a/modules/enum/enum.c b/modules/enum/enum.c index 12a2c279ba4..c4880b68cbb 100644 --- a/modules/enum/enum.c +++ b/modules/enum/enum.c @@ -660,39 +660,29 @@ int do_query(struct sip_msg* _msg, char *user, char *name, str *service) { /* * See documentation in README file. */ -int enum_query(struct sip_msg* _msg, str* _suffix, str* _service) +int enum_query(struct sip_msg* _msg, str* _num, str* _suffix, str* _service) { char *user_s; int user_len, i, j; char name[MAX_DOMAIN_SIZE]; char string[17]; - str *__suffix, *__service; - - /* Use the suffix module parameter */ - if (_suffix == NULL) - __suffix = &suffix; - else - __suffix = _suffix; - - /* Use the internal service */ - if (_service == NULL) - __service = &service; - else - __service = _service; + if (!_num) { + if (parse_sip_msg_uri(_msg) < 0) { + LM_ERR("Parsing of R-URI failed\n"); + return -1; + } - if (parse_sip_msg_uri(_msg) < 0) { - LM_ERR("Parsing of R-URI failed\n"); - return -1; + _num = &_msg->parsed_uri.user; } - if (is_e164(&(_msg->parsed_uri.user)) == -1) { - LM_ERR("R-URI user is not an E164 number\n"); + if (is_e164(_num) == -1) { + LM_ERR("number is not in E164 format\n"); return -1; } - user_s = _msg->parsed_uri.user.s; - user_len = _msg->parsed_uri.user.len; + user_s = _num->s; + user_len = _num->len; memcpy(&(string[0]), user_s, user_len); string[user_len] = (char)0; @@ -704,9 +694,9 @@ int enum_query(struct sip_msg* _msg, str* _suffix, str* _service) j = j + 2; } - memcpy(name + j, __suffix->s, __suffix->len + 1); + memcpy(name + j, _suffix->s, _suffix->len + 1); - return do_query(_msg, string, name, __service); + return do_query(_msg, string, name, _service); } @@ -920,159 +910,3 @@ int i_enum_query(struct sip_msg* _msg, str* suffix, str* service) return do_query(_msg, string, name, service); } - - - -/******************* FQUERY *******************/ - -/* - * See documentation in README file. - */ - -int enum_pv_query(struct sip_msg* _msg, str* num, str* suffix, - str* service) -{ - char *user_s; - int user_len, i, j, first; - char name[MAX_DOMAIN_SIZE]; - char uri[MAX_URI_SIZE]; - char new_uri[MAX_URI_SIZE]; - unsigned int priority, curr_prio; - qvalue_t q; - char tostring[17]; - struct rdata* head; - struct rdata* l; - struct naptr_rdata* naptr; - str pattern, replacement, result, new_result; - char string[17]; - - /* - * Get R-URI user to tostring - */ - if (parse_sip_msg_uri(_msg) < 0) { - LM_ERR("R-URI parsing failed\n"); - return -1; - } - - user_s = _msg->parsed_uri.user.s; - user_len = _msg->parsed_uri.user.len; - - memcpy(&(tostring[0]), user_s, user_len); - tostring[user_len] = (char)0; - - if (is_e164(num) == -1) { - LM_ERR("pseudo variable does not contain an E164 number\n"); - return -1; - } - - user_s = num->s; - user_len = num->len; - - memcpy(&(string[0]), user_s, user_len); - string[user_len] = (char)0; - - j = 0; - for (i = user_len - 1; i > 0; i--) { - name[j] = user_s[i]; - name[j + 1] = '.'; - j = j + 2; - } - - memcpy(name + j, suffix->s, suffix->len + 1); - - head = get_record(name, T_NAPTR); - - if (head == 0) { - LM_DBG("No NAPTR record found for %s.\n", name); - return -1; - } - - naptr_sort(&head); - - q = MAX_Q - 10; - curr_prio = 0; - first = 1; - - for (l = head; l; l = l->next) { - - if (l->type != T_NAPTR) continue; /*should never happen*/ - naptr = (struct naptr_rdata*)l->rdata; - if (naptr == 0) { - LM_ERR("Null rdata in DNS response\n"); - continue; - } - - LM_DBG("ENUM query on %s: order %u, pref %u, flen %u, flags " - "'%.*s', slen %u, services '%.*s', rlen %u, " - "regexp '%.*s'\n", - name, naptr->order, naptr->pref, - naptr->flags_len, (int)(naptr->flags_len), ZSW(naptr->flags), - naptr->services_len, - (int)(naptr->services_len), ZSW(naptr->services), naptr->regexp_len, - (int)(naptr->regexp_len), ZSW(naptr->regexp)); - - if (sip_match(naptr, service) == 0) continue; - - if (parse_naptr_regexp(&(naptr->regexp[0]), naptr->regexp_len, - &pattern, &replacement) < 0) { - LM_ERR("Parsing of NAPTR regexp failed\n"); - continue; - } - result.s = &(uri[0]); - result.len = MAX_URI_SIZE; - /* Avoid making copies of pattern and replacement */ - pattern.s[pattern.len] = (char)0; - replacement.s[replacement.len] = (char)0; - if (reg_replace(pattern.s, replacement.s, &(tostring[0]), - &result) < 0) { - pattern.s[pattern.len] = '!'; - replacement.s[replacement.len] = '!'; - LM_ERR("Regexp replace failed\n"); - continue; - } - LM_DBG("Resulted in replacement: '%.*s'\n", - result.len, ZSW(result.s)); - pattern.s[pattern.len] = '!'; - replacement.s[replacement.len] = '!'; - - if (param.len > 0) { - if (result.len + param.len > MAX_URI_SIZE - 1) { - LM_ERR("URI is too long\n"); - continue; - } - new_result.s = &(new_uri[0]); - new_result.len = MAX_URI_SIZE; - if (add_uri_param(&result, ¶m, &new_result) == 0) { - LM_ERR("Parsing of URI <%.*s> failed\n", - result.len, result.s); - continue; - } - if (new_result.len > 0) { - result = new_result; - } - } - - if (first) { - if (set_ruri(_msg, &result) == -1) { - goto done; - } - set_ruri_q(_msg, q); - first = 0; - curr_prio = ((naptr->order) << 16) + naptr->pref; - } else { - priority = ((naptr->order) << 16) + naptr->pref; - if (priority > curr_prio) { - q = q - 10; - curr_prio = priority; - } - if (append_branch(_msg, &result, 0, 0, q, 0, 0) == -1) { - goto done; - } - } - } - -done: - free_rdata_list(head); - return first ? -1 : 1; -} - diff --git a/modules/enum/enum.h b/modules/enum/enum.h index 64e4691aa07..9032a4b2640 100644 --- a/modules/enum/enum.h +++ b/modules/enum/enum.h @@ -37,19 +37,11 @@ */ int is_from_user_enum(struct sip_msg* _msg, str* _suffix, str* _service); -/* - * do source number destination routing. - * that is, make the ruri based on the from number - * this is like source ip policy routing - */ -int enum_pv_query(struct sip_msg* _msg, str* _sp, str* _suffix, - str* _service); - /* * Make enum query and if query succeeds, replace current uri with the * result of the query */ -int enum_query(struct sip_msg* _msg, str* _suffix, str* _service); +int enum_query(struct sip_msg* _msg, str* _num, str* _suffix, str* _service); /* * Infrastructure ENUM versions. diff --git a/modules/enum/enum_mod.c b/modules/enum/enum_mod.c index fb3045ac7a8..1d5955545b1 100644 --- a/modules/enum/enum_mod.c +++ b/modules/enum/enum_mod.c @@ -41,7 +41,10 @@ * Module initialization function prototype */ static int mod_init(void); - +static int fixup_enum_suffix(void **param); +static int fixup_enum_i_suffix(void **param); +static int fixup_enum_isn_suffix(void **param); +static int fixup_enum_service(void **param); /* * Module parameter variables @@ -77,24 +80,28 @@ str isnsuffix; static cmd_export_t cmds[] = { {"enum_query", (cmd_function)enum_query, { {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, - {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, {0,0,0}}, - REQUEST_ROUTE}, - {"enum_pv_query", (cmd_function)enum_pv_query, { - {CMD_PARAM_STR, 0, 0}, - {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, - {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, {0,0,0}}, - REQUEST_ROUTE}, - {"is_from_user_enum", (cmd_function)is_from_user_enum, { - {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, - {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + {CMD_PARAM_STR | CMD_PARAM_OPT | CMD_PARAM_FIX_NULL, + fixup_enum_suffix, 0}, + {CMD_PARAM_STR | CMD_PARAM_OPT | CMD_PARAM_FIX_NULL, + fixup_enum_service, 0}, {0,0,0}}, REQUEST_ROUTE}, {"i_enum_query", (cmd_function)i_enum_query, { - {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, - {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + {CMD_PARAM_STR | CMD_PARAM_OPT | CMD_PARAM_FIX_NULL, + fixup_enum_i_suffix, 0}, + {CMD_PARAM_STR | CMD_PARAM_OPT | CMD_PARAM_FIX_NULL, + fixup_enum_service, 0}, {0,0,0}}, REQUEST_ROUTE}, {"isn_query", (cmd_function)isn_query, { - {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, - {CMD_PARAM_STR | CMD_PARAM_OPT, 0, 0}, {0,0,0}}, + {CMD_PARAM_STR | CMD_PARAM_OPT | CMD_PARAM_FIX_NULL, + fixup_enum_isn_suffix, 0}, + {CMD_PARAM_STR | CMD_PARAM_OPT | CMD_PARAM_FIX_NULL, + fixup_enum_service, 0}, {0,0,0}}, + REQUEST_ROUTE}, + {"is_from_user_enum", (cmd_function)is_from_user_enum, { + {CMD_PARAM_STR | CMD_PARAM_OPT | CMD_PARAM_FIX_NULL, + fixup_enum_suffix, 0}, + {CMD_PARAM_STR | CMD_PARAM_OPT | CMD_PARAM_FIX_NULL, + fixup_enum_suffix, 0}, {0,0,0}}, REQUEST_ROUTE}, {0,0,{{0,0,0}},0} }; @@ -165,3 +172,34 @@ static int mod_init(void) return 0; } +static int fixup_enum_suffix(void **param) +{ + if (!*param) + *param = (void *)&suffix; + + return 0; +} + +static int fixup_enum_i_suffix(void **param) +{ + if (!*param) + *param = (void *)&i_suffix; + + return 0; +} + +static int fixup_enum_isn_suffix(void **param) +{ + if (!*param) + *param = (void *)&isnsuffix; + + return 0; +} + +static int fixup_enum_service(void **param) +{ + if (!*param) + *param = (void *)&service; + + return 0; +}