Skip to content

Commit

Permalink
Merge pull request #115 from kamailio/lazedo/registrar-registered
Browse files Browse the repository at this point in the history
registrar : add optional params to registered function
  • Loading branch information
miconda committed Mar 26, 2015
2 parents da5d414 + 7ba770c commit 4763dfa
Show file tree
Hide file tree
Showing 5 changed files with 169 additions and 42 deletions.
43 changes: 42 additions & 1 deletion modules/registrar/doc/registrar_admin.xml
Expand Up @@ -658,6 +658,11 @@ modparam("registrar", "path_check_local", 1)

<section id="registrar.p.reg_callid_avp">
<title><varname>reg_callid_avp</varname> (string)</title>
<para>
<emphasis>
obsolete. use match_option in registered function
</emphasis>
</para>
<para>
If reg_callid_avp is defined and populated when the
<function>registered()</function> is invoked, the result is
Expand Down Expand Up @@ -1102,7 +1107,7 @@ lookup_branches("location");

<section id="registrar.f.registered">
<title>
<function moreinfo="none">registered(domain [, uri])</function>
<function moreinfo="none">registered(domain [, uri [, match_option [, match_action]]])</function>
</title>
<para>
The function returns true if the AOR in the Request-URI is
Expand All @@ -1124,6 +1129,35 @@ lookup_branches("location");
of R-URI. It can be a dynamic string with pseudo-variables.
</para>
</listitem>
<listitem>
<para>
<emphasis>match_option</emphasis> (optional) - flag parameter to restrict
contact search. use reg_xavp_cfg to set the values to compare to.
</para>
<para>flag values is as follows:</para>
<itemizedlist>
<listitem>
<para>1 - match_callid</para>
</listiem>
<listitem>
<para>2 - match_received</para>
</listiem>
<listitem>
<para>4 - match_contact</para>
</listiem>
</itemizedlist>
</listitem>
<listitem>
<para>
<emphasis>match_action</emphasis> (optional) - actions to perform when match is positive.
</para>
<para>flag values is as follows:</para>
<itemizedlist>
<listitem>
<para>1 - set xavp_rcd with value from matched contact</para>
</listiem>
</itemizedlist>
</listitem>
</itemizedlist>
<para>
This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
Expand All @@ -1137,6 +1171,13 @@ if (registered("location")) {
...
};
...
$xavp(regcfg=>match_received) = $su;
if (registered("location","$rz:$Au", 2)) {
sl_send_reply("100", "Trying");
...
};
...

</programlisting>
</example>
</section>
Expand Down
74 changes: 60 additions & 14 deletions modules/registrar/lookup.c
Expand Up @@ -619,13 +619,24 @@ int lookup_branches(sip_msg_t *msg, udomain_t *d)
* it is similar to lookup but registered neither rewrites
* the Request-URI nor appends branches
*/
int registered(struct sip_msg* _m, udomain_t* _d, str* _uri)
int registered(struct sip_msg* _m, udomain_t* _d, str* _uri) {
return registered4(_m, _d, _uri, 0, 0);
}

int registered3(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag) {
return registered4(_m, _d, _uri, match_flag, 0);
}

int registered4(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag, int match_action_flag)
{
str uri, aor;
urecord_t* r;
ucontact_t* ptr;
int res;
int_str match_callid=(int_str)0;
str match_callid = {0,0};
str match_received = {0,0};
str match_contact = {0,0};
sr_xavp_t *vavp = NULL;

if(_uri!=NULL)
{
Expand All @@ -650,26 +661,61 @@ int registered(struct sip_msg* _m, udomain_t* _d, str* _uri)
}

if (res == 0) {

if (reg_callid_avp_name.n) {
struct usr_avp *avp =
search_first_avp( reg_callid_avp_type, reg_callid_avp_name, &match_callid, 0);
if (!(avp && is_avp_str_val(avp)))
match_callid.n = 0;
match_callid.s.s = NULL;
} else {
match_callid.n = 0;
match_callid.s.s = NULL;
LM_DBG("searching with match flags (%d,%d)\n", match_flag, reg_match_flag_param);
if(reg_xavp_cfg.s!=NULL) {

if((match_flag & 1)
&& (vavp = xavp_get_child_with_sval(&reg_xavp_cfg, &match_callid_name)) != NULL
&& vavp->val.v.s.len > 0) {
match_callid = vavp->val.v.s;
LM_DBG("matching with callid %.*s\n", match_callid.len, match_callid.s);
}

if((match_flag & 2)
&& (vavp = xavp_get_child_with_sval(&reg_xavp_cfg, &match_received_name)) != NULL
&& vavp->val.v.s.len > 0) {
match_received = vavp->val.v.s;
LM_DBG("matching with received %.*s\n", match_received.len, match_received.s);
}

if((match_flag & 4)
&& (vavp = xavp_get_child_with_sval(&reg_xavp_cfg, &match_contact_name)) != NULL
&& vavp->val.v.s.len > 0) {
match_contact = vavp->val.v.s;
LM_DBG("matching with contact %.*s\n", match_contact.len, match_contact.s);
}
}

for (ptr = r->contacts; ptr; ptr = ptr->next) {
if(!VALID_CONTACT(ptr, act_time)) continue;
if (match_callid.s.s && /* optionally enforce tighter matching w/ Call-ID */
memcmp(match_callid.s.s,ptr->callid.s,match_callid.s.len))
if (match_callid.s && /* optionally enforce tighter matching w/ Call-ID */
match_callid.len > 0 &&
(match_callid.len != ptr->callid.len ||
memcmp(match_callid.s, ptr->callid.s, match_callid.len)))
continue;
if (match_received.s && /* optionally enforce tighter matching w/ ip:port */
match_received.len > 0 &&
(match_received.len != ptr->received.len ||
memcmp(match_received.s, ptr->received.s, match_received.len)))
continue;
if (match_contact.s && /* optionally enforce tighter matching w/ Contact */
match_contact.len > 0 &&
(match_contact.len != ptr->c.len ||
memcmp(match_contact.s, ptr->c.s, match_contact.len)))
continue;

if(ptr->xavp!=NULL && match_action_flag == 1) {
sr_xavp_t *xavp = xavp_clone_level_nodata(ptr->xavp);
if(xavp_add(xavp, NULL)<0) {
LM_ERR("error adding xavp for %.*s after successful match\n", aor.len, ZSW(aor.s));
xavp_destroy_list(&xavp);
}
}

ul.release_urecord(r);
ul.unlock_udomain(_d, &aor);
LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s));

return 1;
}
}
Expand Down
3 changes: 2 additions & 1 deletion modules/registrar/lookup.h
Expand Up @@ -67,6 +67,7 @@ int lookup_branches(sip_msg_t *msg, udomain_t *d);
* the Request-URI nor appends branches
*/
int registered(struct sip_msg* _m, udomain_t* _d, str* _uri);

int registered3(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag);
int registered4(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag, int match_action_flag);

#endif /* LOOKUP_H */
85 changes: 61 additions & 24 deletions modules/registrar/reg_mod.c
Expand Up @@ -101,10 +101,9 @@ int reg_outbound_mode = 0;
int reg_regid_mode = 0;
int reg_flow_timer = 0;

/* Populate this AVP if testing for specific registration instance. */
char *reg_callid_avp_param = 0;
unsigned short reg_callid_avp_type = 0;
int_str reg_callid_avp_name;
str match_callid_name = str_init("match_callid");
str match_received_name = str_init("match_received");
str match_contact_name = str_init("match_contact");

char* rcv_avp_param = 0;
unsigned short rcv_avp_type = 0;
Expand Down Expand Up @@ -164,6 +163,10 @@ static cmd_export_t cmds[] = {
REQUEST_ROUTE | FAILURE_ROUTE },
{"registered", (cmd_function)w_registered, 2, domain_uri_fixup, 0,
REQUEST_ROUTE | FAILURE_ROUTE },
{"registered", (cmd_function)w_registered3, 3, registered_fixup, 0,
REQUEST_ROUTE | FAILURE_ROUTE },
{"registered", (cmd_function)w_registered4, 4, registered_fixup, 0,
REQUEST_ROUTE | FAILURE_ROUTE },
{"add_sock_hdr", (cmd_function)add_sock_hdr, 1, fixup_str_null, 0,
REQUEST_ROUTE },
{"unregister", (cmd_function)w_unregister, 2, unreg_fixup, 0,
Expand Down Expand Up @@ -200,7 +203,6 @@ static param_export_t params[] = {
{"max_expires", INT_PARAM, &default_registrar_cfg.max_expires },
{"received_param", PARAM_STR, &rcv_param },
{"received_avp", PARAM_STRING, &rcv_avp_param },
{"reg_callid_avp", PARAM_STRING, &reg_callid_avp_param },
{"max_contacts", INT_PARAM, &default_registrar_cfg.max_contacts },
{"retry_after", INT_PARAM, &default_registrar_cfg.retry_after },
{"sock_flag", INT_PARAM, &sock_flag },
Expand All @@ -209,7 +211,7 @@ static param_export_t params[] = {
{"use_path", INT_PARAM, &path_enabled },
{"path_mode", INT_PARAM, &path_mode },
{"path_use_received", INT_PARAM, &path_use_params },
{"path_check_local", INT_PARAM, &path_check_local },
{"path_check_local", INT_PARAM, &path_check_local },
{"xavp_cfg", PARAM_STR, &reg_xavp_cfg },
{"xavp_rcd", PARAM_STR, &reg_xavp_rcd },
{"gruu_enabled", INT_PARAM, &reg_gruu_enabled },
Expand Down Expand Up @@ -306,24 +308,6 @@ static int mod_init(void)
rcv_avp_type = 0;
}

if (reg_callid_avp_param && *reg_callid_avp_param) {
s.s = reg_callid_avp_param; s.len = strlen(s.s);
if (pv_parse_spec(&s, &avp_spec)==0
|| avp_spec.type!=PVT_AVP) {
LM_ERR("malformed or non AVP %s AVP definition\n", reg_callid_avp_param);
return -1;
}

if(pv_get_avp_name(0, &avp_spec.pvp, &reg_callid_avp_name, &reg_callid_avp_type)!=0)
{
LM_ERR("[%s]- invalid AVP definition\n", reg_callid_avp_param);
return -1;
}
} else {
reg_callid_avp_name.n = 0;
reg_callid_avp_type = 0;
}

bind_usrloc = (bind_usrloc_t)find_export("ul_bind_usrloc", 1, 0);
if (!bind_usrloc) {
LM_ERR("can't bind usrloc\n");
Expand Down Expand Up @@ -488,6 +472,46 @@ static int w_registered(struct sip_msg* _m, char* _d, char* _uri)
return registered(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL);
}

static int w_registered3(struct sip_msg* _m, char* _d, char* _uri, char* _flags)
{
str uri = {0};
int flags = 0;
if(_uri!=NULL && (fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0))
{
LM_ERR("invalid uri parameter\n");
return -1;
}
if(_flags!=NULL && (fixup_get_ivalue(_m, (fparam_t*)_flags, &flags)) < 0)
{
LM_ERR("invalid flags parameter\n");
return -1;
}
return registered3(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL, flags);
}

static int w_registered4(struct sip_msg* _m, char* _d, char* _uri, char* _flags, char* _actionflags)
{
str uri = {0};
int flags = 0;
int actionflags = 0;
if(_uri!=NULL && (fixup_get_svalue(_m, (gparam_p)_uri, &uri)!=0 || uri.len<=0))
{
LM_ERR("invalid uri parameter\n");
return -1;
}
if(_flags!=NULL && (fixup_get_ivalue(_m, (fparam_t*)_flags, &flags)) < 0)
{
LM_ERR("invalid flags parameter\n");
return -1;
}
if(_actionflags!=NULL && (fixup_get_ivalue(_m, (fparam_t*)_actionflags, &actionflags)) < 0)
{
LM_ERR("invalid action flag parameter\n");
return -1;
}
return registered4(_m, (udomain_t*)_d, (uri.len>0)?&uri:NULL, flags, actionflags);
}

static int w_unregister(struct sip_msg* _m, char* _d, char* _uri)
{
str uri = {0};
Expand Down Expand Up @@ -550,6 +574,19 @@ static int domain_uri_fixup(void** param, int param_no)
return 0;
}

static int registered_fixup(void** param, int param_no)
{
if (param_no == 1) {
return domain_fixup(param, 1);
} else if (param_no == 2) {
return fixup_spve_null(param, 1);
} else if (param_no == 3) {
return fixup_igp_null(param, 1);
} else if (param_no == 4) {
return fixup_igp_null(param, 1);
}
return 0;
}

/*! \brief
* Convert char* parameter to udomain_t* pointer
Expand Down
6 changes: 4 additions & 2 deletions modules/registrar/reg_mod.h
Expand Up @@ -74,8 +74,10 @@ extern float def_q;

extern unsigned short rcv_avp_type;
extern int_str rcv_avp_name;
extern unsigned short reg_callid_avp_type;
extern int_str reg_callid_avp_name;

extern str match_callid_name;
extern str match_received_name;
extern str match_contact_name;

extern str rcv_param;
extern int method_filtering;
Expand Down

0 comments on commit 4763dfa

Please sign in to comment.