Skip to content

Commit

Permalink
core: address several advertised address related issues
Browse files Browse the repository at this point in the history
	* properly duplicate buffers into shared memory when required
	* keep the advertised address of the first branch as a default for
	  future branches
	* also allow set_advertised_port() to receive any kind of parameter
	  (int, string, int pvar, str pvar...)

Credits for reporting and helping with troubleshooting to GitHub user contact2malay
(cherry picked from commit ad92fa6)
  • Loading branch information
liviuchircu committed Apr 30, 2014
1 parent 0c56339 commit 29366c0
Show file tree
Hide file tree
Showing 10 changed files with 225 additions and 67 deletions.
111 changes: 83 additions & 28 deletions action.c
Expand Up @@ -298,6 +298,82 @@ int do_assign(struct sip_msg* msg, struct action* a)
return -1;
}

static int do_action_set_adv_address(struct sip_msg *msg, struct action *a)
{
str adv_addr;
int ret = 1; /* continue processing */

if (a->elem[0].type != STR_ST) {
report_programming_bug("set_advertised_address type %d", a->elem[0].type);
ret = E_BUG;
goto out;
}

if (pv_printf_s(msg, (pv_elem_t *)a->elem[0].u.data, &adv_addr) != 0
|| adv_addr.len <= 0) {

LM_WARN("cannot get string for value\n");
ret = E_BUG;
goto out;
}

LM_DBG("setting adv address = [%.*s]\n", adv_addr.len, adv_addr.s);

/* duplicate the advertised address into private memory */
if (adv_addr.len > msg->set_global_address.len) {
msg->set_global_address.s = pkg_realloc(msg->set_global_address.s,
adv_addr.len);
if (!msg->set_global_address.s) {
LM_ERR("out of pkg mem\n");
ret = E_OUT_OF_MEM;
goto out;
}
}
memcpy(msg->set_global_address.s, adv_addr.s, adv_addr.len);
msg->set_global_address.len = adv_addr.len;

out:
return ret;
}

static int do_action_set_adv_port(struct sip_msg *msg, struct action *a)
{
str adv_port;
int ret = 1;

if (a->elem[0].type != STR_ST) {
report_programming_bug("set_advertised_port type %d", a->elem[0].type);
ret = E_BUG;
goto out;
}

if (pv_printf_s(msg, (pv_elem_t *)a->elem[0].u.data, &adv_port) != 0
|| adv_port.len <= 0) {

LM_WARN("cannot get string for value\n");
ret = E_BUG;
goto out;
}

LM_DBG("setting adv port '%.*s'\n", adv_port.len, adv_port.s);

/* duplicate the advertised port into private memory */
if (adv_port.len > msg->set_global_port.len) {
msg->set_global_port.s = pkg_realloc(msg->set_global_port.s,
adv_port.len);
if (!msg->set_global_port.s) {
LM_ERR("out of pkg mem\n");
ret = E_OUT_OF_MEM;
goto out;
}
}
memcpy(msg->set_global_port.s, adv_port.s, adv_port.len);
msg->set_global_port.len = adv_port.len;

out:
return ret;
}

#define update_longest_action() do { \
if (execmsgthreshold) { \
end_time = get_time_diff(&start); \
Expand Down Expand Up @@ -1759,38 +1835,17 @@ int do_action(struct action* a, struct sip_msg* msg)
msg->msg_flags|=FL_FORCE_LOCAL_RPORT;
ret=1; /* continue processing */
break;

case SET_ADV_ADDR_T:
script_trace("core", "set_adv_addr", msg, a->line) ;
if (a->elem[0].type!=STR_ST){
LM_ALERT("BUG in set_advertised_address() "
"type %d\n", a->elem[0].type);
ret=E_BUG;
break;
}
str adv_addr;
pve = (pv_elem_t *)a->elem[0].u.data;
if ( pv_printf_s(msg, pve, &adv_addr)!=0 ||
adv_addr.len == 0 || adv_addr.s == NULL) {
LM_WARN("cannot get string for value\n");
ret=E_BUG;
break;
}
LM_DBG("adv address = [%.*s]\n",adv_addr.len,adv_addr.s);
msg->set_global_address=adv_addr;
ret=1; /* continue processing */
script_trace("core", "set_adv_addr", msg, a->line);
ret = do_action_set_adv_address(msg, a);
break;
case SET_ADV_PORT_T:
script_trace("core", "set_adv_port", msg, a->line) ;
if (a->elem[0].type!=STR_ST){
LM_ALERT("BUG in set_advertised_port() "
"type %d\n", a->elem[0].type);
ret=E_BUG;
break;
}

msg->set_global_port=*((str*)a->elem[0].u.data);
ret=1; /* continue processing */
case SET_ADV_PORT_T:
script_trace("core", "set_adv_port", msg, a->line);
ret = do_action_set_adv_port(msg, a);
break;

#ifdef USE_TCP
case FORCE_TCP_ALIAS_T:
script_trace("core", "force_tcp_alias", msg, a->line) ;
Expand Down
29 changes: 15 additions & 14 deletions cfg.y
Expand Up @@ -2835,23 +2835,24 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T,
"string expected"); }
| SET_ADV_ADDRESS error {$$=0; yyerror("missing '(' or ')' ?"); }
| SET_ADV_PORT LPAREN NUMBER RPAREN {
$$=0;
tmp=int2str($3, &i_tmp);
if ((str_tmp=pkg_malloc(sizeof(str)))==0){
LM_CRIT("cfg. parser: out of memory.\n");
}else{
if ((str_tmp->s=pkg_malloc(i_tmp))==0){
tstr.s = int2str($3, &tstr.len);
if (!(tmp = pkg_malloc(tstr.len + 1))) {
LM_CRIT("cfg. parser: out of memory.\n");
}else{
memcpy(str_tmp->s, tmp, i_tmp);
str_tmp->len=i_tmp;
mk_action2( $$, SET_ADV_PORT_T, STR_ST,
0, str_tmp, 0);
}
$$ = 0;
} else {
memcpy(tmp, tstr.s, tstr.len);
tmp[tstr.len] = '\0';
mk_action2($$, SET_ADV_PORT_T, STR_ST,
0, tmp, 0);
}
}
| SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, "
"string expected"); }
| SET_ADV_PORT LPAREN STRING RPAREN {
mk_action2($$, SET_ADV_PORT_T,
STR_ST, NOSUBTYPE,
$3, NULL);
}
| SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument "
"(string or integer expected)"); }
| SET_ADV_PORT error {$$=0; yyerror("missing '(' or ')' ?"); }
| FORCE_SEND_SOCKET LPAREN phostport RPAREN {
mk_action2( $$, FORCE_SEND_SOCKET_T,
Expand Down
30 changes: 29 additions & 1 deletion modules/tm/sip_msg.c
Expand Up @@ -323,9 +323,21 @@ struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len )
len = ROUND4(sizeof( struct sip_msg ));
/*we will keep only the original msg +ZT */
len += ROUND4(org_msg->len + 1);

/*the new uri (if any)*/
if (org_msg->new_uri.s && org_msg->new_uri.len)
len+= ROUND4(org_msg->new_uri.len);
len += ROUND4(org_msg->new_uri.len);

if (org_msg->set_global_address.s) {
LM_DBG("XXX - have address\n");
len += ROUND4(org_msg->set_global_address.len);
}

if (org_msg->set_global_port.s) {
LM_DBG("XXX - have port\n");
len += ROUND4(org_msg->set_global_port.len);
}

/*all the headers*/
for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )
{
Expand Down Expand Up @@ -465,13 +477,29 @@ do { \
p += ROUND4(sizeof(struct sip_msg));
new_msg->add_rm = 0;
new_msg->body_lumps = 0;

/* new_uri */
if (org_msg->new_uri.s && org_msg->new_uri.len)
{
new_msg->new_uri.s = p;
memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);
p += ROUND4(org_msg->new_uri.len);
}

/* advertised address and port */
if (org_msg->set_global_address.s)
{
new_msg->set_global_address.s = p;
memcpy(p, org_msg->set_global_address.s, org_msg->set_global_address.len);
p += ROUND4(org_msg->set_global_address.len);
}
if (org_msg->set_global_port.s)
{
new_msg->set_global_port.s = p;
memcpy(p, org_msg->set_global_port.s, org_msg->set_global_port.len);
p += ROUND4(org_msg->set_global_port.len);
}

/* dst_uri to zero */
new_msg->dst_uri.s = 0;
new_msg->dst_uri.len = 0;
Expand Down
2 changes: 0 additions & 2 deletions modules/tm/t_msgbuilder.h
Expand Up @@ -93,8 +93,6 @@ static inline struct sip_msg* buf_to_sip_msg(char *buf, unsigned int len,
return NULL;
}
/* populate some special fields in sip_msg */
req.set_global_address=default_global_address;
req.set_global_port=default_global_port;
req.force_send_socket = dialog->send_sock;
if (set_dst_uri(&req, dialog->hooks.next_hop)) {
LM_ERR("failed to set dst_uri");
Expand Down
49 changes: 43 additions & 6 deletions modules/tm/t_reply.c
Expand Up @@ -554,13 +554,37 @@ static inline int fake_req(struct sip_msg *faked_req, struct sip_msg *shm_msg,
faked_req->new_uri.s=pkg_malloc( uac->uri.len+1 );
if (!faked_req->new_uri.s) {
LM_ERR("no uri/pkg mem\n");
goto error;
return 0;
}
faked_req->new_uri.len = uac->uri.len;
memcpy( faked_req->new_uri.s, uac->uri.s, uac->uri.len);
faked_req->new_uri.s[faked_req->new_uri.len]=0;
faked_req->parsed_uri_ok = 0;

/*
* duplicate the advertised address and port into private mem
* so that they can be changed at script level
*/
if (shm_msg->set_global_address.s) {
faked_req->set_global_address.s = pkg_malloc(shm_msg->set_global_address.len);
if (!faked_req->set_global_address.s) {
LM_ERR("out of pkg mem\n");
goto out;
}
memcpy(faked_req->set_global_address.s, shm_msg->set_global_address.s,
shm_msg->set_global_address.len);
}

if (shm_msg->set_global_port.s) {
faked_req->set_global_port.s = pkg_malloc(shm_msg->set_global_port.len);
if (!faked_req->set_global_port.s) {
LM_ERR("out of pkg mem\n");
goto out1;
}
memcpy(faked_req->set_global_port.s, shm_msg->set_global_port.s,
shm_msg->set_global_port.len);
}

/* we could also restore dst_uri, but will be confusing from script,
* so let it set to NULL */

Expand All @@ -570,7 +594,12 @@ static inline int fake_req(struct sip_msg *faked_req, struct sip_msg *shm_msg,
setb0flags( uac->br_flags);

return 1;
error:

out1:
pkg_free(faked_req->set_global_address.s);
out:
pkg_free(faked_req->new_uri.s);

return 0;
}

Expand All @@ -579,15 +608,23 @@ inline static void free_faked_req(struct sip_msg *faked_req, struct cell *t)
{
if (faked_req->new_uri.s) {
pkg_free(faked_req->new_uri.s);
faked_req->new_uri.s = 0;
faked_req->new_uri.s = NULL;
}
if (faked_req->dst_uri.s) {
pkg_free(faked_req->dst_uri.s);
faked_req->dst_uri.s = 0;
faked_req->dst_uri.s = NULL;
}
if (faked_req->path_vec.s) {
pkg_free(faked_req->path_vec.s);
faked_req->path_vec.s = 0;
faked_req->path_vec.s = NULL;
}
if (faked_req->set_global_address.s) {
pkg_free(faked_req->set_global_address.s);
faked_req->set_global_address.s = NULL;
}
if (faked_req->set_global_port.s) {
pkg_free(faked_req->set_global_port.s);
faked_req->set_global_port.s = NULL;
}

/* SDP in not cloned into SHM, so if we have one, it means the SDP
Expand All @@ -597,7 +634,7 @@ inline static void free_faked_req(struct sip_msg *faked_req, struct cell *t)

if (faked_req->multi) {
free_multi_body(faked_req->multi);
faked_req->multi = 0;
faked_req->multi = NULL;
}

if (faked_req->msg_cb) {
Expand Down
18 changes: 14 additions & 4 deletions msg_translator.c
Expand Up @@ -592,17 +592,23 @@ int lumps_len(struct sip_msg* msg, struct lump* lumps,
s_offset=0;
new_len=0;
last_del=0;

/* init send_address_str & send_port_str */
if(send_sock && send_sock->adv_name_str.len)
send_address_str=&(send_sock->adv_name_str);
else if (msg->set_global_address.len)
else if (msg->set_global_address.s)
send_address_str=&(msg->set_global_address);
else if (default_global_address.s)
send_address_str=&default_global_address;
else
send_address_str=&(send_sock->address_str);

if(send_sock && send_sock->adv_port_str.len)
send_port_str=&(send_sock->adv_port_str);
else if (msg->set_global_port.len)
else if (msg->set_global_port.s)
send_port_str=&(msg->set_global_port);
else if (default_global_port.s)
send_port_str=&default_global_port;
else
send_port_str=&(send_sock->port_no_str);

Expand Down Expand Up @@ -937,12 +943,16 @@ void process_lumps( struct sip_msg* msg,
send_address_str=&(send_sock->adv_name_str);
else if (msg->set_global_address.len)
send_address_str=&(msg->set_global_address);
else if (default_global_address.s)
send_address_str=&default_global_address;
else
send_address_str=&(send_sock->address_str);
if(send_sock && send_sock->adv_port_str.len)
send_port_str=&(send_sock->adv_port_str);
else if (msg->set_global_port.len)
send_port_str=&(msg->set_global_port);
else if (default_global_port.s)
send_port_str=&default_global_port;
else
send_port_str=&(send_sock->port_no_str);

Expand Down Expand Up @@ -1975,7 +1985,7 @@ char* via_builder( unsigned int *len,
address_str=hp->host;
else if(send_sock->adv_name_str.len)
address_str=&(send_sock->adv_name_str);
else if (default_global_address.len)
else if (default_global_address.s)
address_str=&default_global_address;
else
address_str=&(send_sock->address_str);
Expand All @@ -1984,7 +1994,7 @@ char* via_builder( unsigned int *len,
port_str=hp->port;
else if(send_sock->adv_port_str.len)
port_str=&(send_sock->adv_port_str);
else if (default_global_port.len)
else if (default_global_port.s)
port_str=&default_global_port;
else
port_str=&(send_sock->port_no_str);
Expand Down

0 comments on commit 29366c0

Please sign in to comment.