Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

nathelper : added new function set_alias_to_pv #2124

Merged
merged 7 commits into from Nov 25, 2019
21 changes: 21 additions & 0 deletions src/modules/nathelper/doc/nathelper_admin.xml
Expand Up @@ -823,6 +823,27 @@ if(is_rfc1918("$rd")) {
</programlisting>
</example>
</section>
<section id="nathelper.set_alias_to_pv">
<title>
<function moreinfo="none">set_alias_to_pv(target_avp)</function>
</title>
<para>
Reads <quote>;alias=ip~port~transport</quote> from Contact header then
writes to target avp as a sip uri.
</para>
<para>
This function can be used from
REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, and FAILURE_ROUTE.
</para>
<example>
<title><function>set_alias_to_pv</function> usage</title>
<programlisting format="linespecific">
...
set_alias_to_pv("$avp(aliasuri)");
...
</programlisting>
</example>
</section>

</section>

Expand Down
199 changes: 199 additions & 0 deletions src/modules/nathelper/nathelper.c
Expand Up @@ -125,6 +125,11 @@ static int add_rcv_param_f(struct sip_msg *, char *, char *);
static int nh_sip_reply_received(sip_msg_t *msg);
static int test_sdp_cline(struct sip_msg *msg);

static int w_set_alias_to_pv(struct sip_msg *msg, char *uri_avp, char *hollow);
static int ki_set_alias_to_pv(struct sip_msg *msg, str *uri_avp);
static int alias_to_uri(str *contact_header, str *alias_uri);
static int write_to_avp(struct sip_msg *msg, str *data, str *uri_avp);

static void nh_timer(unsigned int, void *);
static int mod_init(void);
static int child_init(int);
Expand Down Expand Up @@ -223,6 +228,8 @@ static cmd_export_t cmds[] = {
{"is_rfc1918", (cmd_function)is_rfc1918_f, 1,
fixup_spve_null, 0,
ANY_ROUTE },
{"set_alias_to_pv", (cmd_function)w_set_alias_to_pv, 1,
0, 0, ANY_ROUTE },
{0, 0, 0, 0, 0, 0}
};

Expand Down Expand Up @@ -2445,6 +2452,193 @@ static int sel_rewrite_contact(str *res, select_t *s, struct sip_msg *msg)

return 0;
}
/*!
* @function w_set_alias_to_pv
* @abstract wrapper of set_alias_to_avp_f
* @param msg sip message
* @param uri_avp given avp name
*
* @result 1 successful , -1 fail
*/
static int w_set_alias_to_pv(struct sip_msg *msg, char *uri_avp, char *hollow){
str dest_avp={0,0};

if(!uri_avp)
return -1;

dest_avp.s=uri_avp;
dest_avp.len=strlen(dest_avp.s);

return ki_set_alias_to_pv(msg,&dest_avp);
}

/*!
* @function ki_set_alias_to_pv
* @abstract reads from msg then write to given avp uri_avp as sip uri
*
* @param msg sip message
* @param uri_avp given avp name
*
* @result 1 successful , -1 fail
*/
static int ki_set_alias_to_pv(struct sip_msg *msg, str *uri_avp){
str contact;
str alias_uri={0,0};

if(parse_headers(msg,HDR_CONTACT_F,0) < 0 ) {
LM_ERR("Couldn't find Contact Header\n");
return -1;
}

if(!msg->contact)
return -1;

if(parse_contact(msg->contact)<0 || !msg->contact->parsed ||
((contact_body_t *)msg->contact->parsed)->contacts==NULL ||
((contact_body_t *)msg->contact->parsed)->contacts->next!=NULL){
LM_ERR("Couldn't parse Contact Header\n");
return -1;
}

contact.s = ((contact_body_t *)msg->contact->parsed)->contacts->name.s;
contact.len = ((contact_body_t *)msg->contact->parsed)->contacts->len;

if(alias_to_uri(&contact,&alias_uri)<0)
return -1;

if(write_to_avp(msg, &alias_uri, uri_avp)<0)
goto error;

if(alias_uri.s)
pkg_free(alias_uri.s);

return 1;

error :
if(alias_uri.s)
pkg_free(alias_uri.s);

return -1;
}
/*!
* @function write_to_avp
* @abstract write_to_avp function writes data to given avp
* @param data source data
* @param uri_avp destination avp name
* @result 1 successful , -1 fail
*/
static int write_to_avp(struct sip_msg *msg, str *data, str *uri_avp){
pv_spec_t *pvresult = NULL;
pv_value_t valx;
pvresult = pv_cache_get(uri_avp);

if(pvresult == NULL) {
LM_ERR("Failed to malloc destination pseudo-variable \n");
return -1;
}

if(pvresult->setf==NULL) {
LM_ERR("Destination pseudo-variable is not writable: [%.*s] \n",uri_avp->len, uri_avp->s);
return -1;
}
memset(&valx, 0, sizeof(pv_value_t));

if(!data->s){
LM_ERR("There isn't any data to write to avp\n");
return -1;
}

valx.flags = PV_VAL_STR;
valx.rs.s = data->s;
valx.rs.len = data->len;

LM_DBG("result: [%.*s]\n", valx.rs.len, valx.rs.s);
pvresult->setf(msg, &pvresult->pvp, (int)EQ_T, &valx);
return 1;
}
/*!
* @function alias_to_uri
* @abstract select alias paramter from contact_header
* then writes to alias_uri
* @param contact_header Source contact header
* @param alias_uri Destination string
* @result 1 successful , -1 fail
*/
static int alias_to_uri(str *contact_header, str *alias_uri){
int i=0; // index
str host={0,0};
str port={0,0};
str proto={0,0};
char *memchr_pointer=0;

if(!contact_header)
return -1;

LM_DBG("Contact header [%.*s] \r\n",contact_header->len,contact_header->s);

for(i=0; i<contact_header->len ;i++){
if(strncmp(&contact_header->s[i], SALIAS, SALIAS_LEN) == 0){
i=i+SALIAS_LEN;
host.s = &contact_header->s[i];
memchr_pointer = memchr(host.s , 126 /* ~ */,contact_header->len-i);
if(memchr_pointer == NULL || memchr_pointer == 0) {
LM_ERR("No alias parameter found for host\n");
return -1;
} else {
host.len = memchr_pointer - &contact_header->s[i];
i=i+host.len;
}
break;
}
}

if(!memchr_pointer){
LM_ERR("Alias couldn't be found \n");
return -1;
}
if(&memchr_pointer[1]){
port.s=&memchr_pointer[1];
}else{
LM_ERR("Alias sign couldn't be found for port \n");
return -1;
}

memchr_pointer = memchr(port.s , 126 /* ~ */,contact_header->len-i);
if(memchr_pointer == NULL) {
LM_ERR("Alias sign couldn't be found for proto \n");
return -1;
} else {
port.len = memchr_pointer - port.s;
i=i+port.len;
}
//last char is proto 0,1,2,3,4..7
proto.s= &port.s[port.len+1];
proto_type_to_str((unsigned short)atoi(proto.s), &proto);

LM_DBG("Host [%.*s][port: %.*s][proto: %.*s] \r\n",host.len,host.s,port.len,port.s,proto.len,proto.s);

//sip:host:port;transport=udp
alias_uri->s =(char *) pkg_malloc(port.len+host.len+proto.len+16);
ycaner06 marked this conversation as resolved.
Show resolved Hide resolved
if(!alias_uri->s){
LM_ERR("Allocation ERROR\n");
return -1;
}

memset(alias_uri->s,0,16+port.len+host.len);

memcpy(alias_uri->s,"sip:",4);
memcpy(&alias_uri->s[4],host.s,host.len);

memcpy(&alias_uri->s[4+host.len],":",1);
memcpy(&alias_uri->s[4+host.len+1],port.s,port.len);
memcpy(&alias_uri->s[4+host.len+1+port.len],";transport=",11);
memcpy(&alias_uri->s[4+host.len+1+port.len+11],proto.s,proto.len);

alias_uri->len=port.len+host.len+16+proto.len;
LM_DBG("Alias uri [%.*s][len: %d] \r\n",alias_uri->len,alias_uri->s,alias_uri->len);

return 1;
}

/**
*
Expand Down Expand Up @@ -2506,6 +2700,11 @@ static sr_kemi_t sr_kemi_nathelper_exports[] = {
{ SR_KEMIP_INT, SR_KEMIP_STR, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ str_init("nathelper"), str_init("set_alias_to_avp"),
SR_KEMIP_INT, ki_set_alias_to_pv,
{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},

{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
};
Expand Down