Skip to content

Commit ad92fa6

Browse files
committed
core: address several advertised address related issues
* 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
1 parent 70d2823 commit ad92fa6

File tree

10 files changed

+225
-67
lines changed

10 files changed

+225
-67
lines changed

action.c

Lines changed: 83 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,82 @@ int do_assign(struct sip_msg* msg, struct action* a)
298298
return -1;
299299
}
300300

301+
static int do_action_set_adv_address(struct sip_msg *msg, struct action *a)
302+
{
303+
str adv_addr;
304+
int ret = 1; /* continue processing */
305+
306+
if (a->elem[0].type != STR_ST) {
307+
report_programming_bug("set_advertised_address type %d", a->elem[0].type);
308+
ret = E_BUG;
309+
goto out;
310+
}
311+
312+
if (pv_printf_s(msg, (pv_elem_t *)a->elem[0].u.data, &adv_addr) != 0
313+
|| adv_addr.len <= 0) {
314+
315+
LM_WARN("cannot get string for value\n");
316+
ret = E_BUG;
317+
goto out;
318+
}
319+
320+
LM_DBG("setting adv address = [%.*s]\n", adv_addr.len, adv_addr.s);
321+
322+
/* duplicate the advertised address into private memory */
323+
if (adv_addr.len > msg->set_global_address.len) {
324+
msg->set_global_address.s = pkg_realloc(msg->set_global_address.s,
325+
adv_addr.len);
326+
if (!msg->set_global_address.s) {
327+
LM_ERR("out of pkg mem\n");
328+
ret = E_OUT_OF_MEM;
329+
goto out;
330+
}
331+
}
332+
memcpy(msg->set_global_address.s, adv_addr.s, adv_addr.len);
333+
msg->set_global_address.len = adv_addr.len;
334+
335+
out:
336+
return ret;
337+
}
338+
339+
static int do_action_set_adv_port(struct sip_msg *msg, struct action *a)
340+
{
341+
str adv_port;
342+
int ret = 1;
343+
344+
if (a->elem[0].type != STR_ST) {
345+
report_programming_bug("set_advertised_port type %d", a->elem[0].type);
346+
ret = E_BUG;
347+
goto out;
348+
}
349+
350+
if (pv_printf_s(msg, (pv_elem_t *)a->elem[0].u.data, &adv_port) != 0
351+
|| adv_port.len <= 0) {
352+
353+
LM_WARN("cannot get string for value\n");
354+
ret = E_BUG;
355+
goto out;
356+
}
357+
358+
LM_DBG("setting adv port '%.*s'\n", adv_port.len, adv_port.s);
359+
360+
/* duplicate the advertised port into private memory */
361+
if (adv_port.len > msg->set_global_port.len) {
362+
msg->set_global_port.s = pkg_realloc(msg->set_global_port.s,
363+
adv_port.len);
364+
if (!msg->set_global_port.s) {
365+
LM_ERR("out of pkg mem\n");
366+
ret = E_OUT_OF_MEM;
367+
goto out;
368+
}
369+
}
370+
memcpy(msg->set_global_port.s, adv_port.s, adv_port.len);
371+
msg->set_global_port.len = adv_port.len;
372+
373+
out:
374+
return ret;
375+
}
376+
301377
#define update_longest_action() do { \
302378
if (execmsgthreshold) { \
303379
end_time = get_time_diff(&start); \
@@ -1759,38 +1835,17 @@ int do_action(struct action* a, struct sip_msg* msg)
17591835
msg->msg_flags|=FL_FORCE_LOCAL_RPORT;
17601836
ret=1; /* continue processing */
17611837
break;
1838+
17621839
case SET_ADV_ADDR_T:
1763-
script_trace("core", "set_adv_addr", msg, a->line) ;
1764-
if (a->elem[0].type!=STR_ST){
1765-
LM_ALERT("BUG in set_advertised_address() "
1766-
"type %d\n", a->elem[0].type);
1767-
ret=E_BUG;
1768-
break;
1769-
}
1770-
str adv_addr;
1771-
pve = (pv_elem_t *)a->elem[0].u.data;
1772-
if ( pv_printf_s(msg, pve, &adv_addr)!=0 ||
1773-
adv_addr.len == 0 || adv_addr.s == NULL) {
1774-
LM_WARN("cannot get string for value\n");
1775-
ret=E_BUG;
1776-
break;
1777-
}
1778-
LM_DBG("adv address = [%.*s]\n",adv_addr.len,adv_addr.s);
1779-
msg->set_global_address=adv_addr;
1780-
ret=1; /* continue processing */
1840+
script_trace("core", "set_adv_addr", msg, a->line);
1841+
ret = do_action_set_adv_address(msg, a);
17811842
break;
1782-
case SET_ADV_PORT_T:
1783-
script_trace("core", "set_adv_port", msg, a->line) ;
1784-
if (a->elem[0].type!=STR_ST){
1785-
LM_ALERT("BUG in set_advertised_port() "
1786-
"type %d\n", a->elem[0].type);
1787-
ret=E_BUG;
1788-
break;
1789-
}
17901843

1791-
msg->set_global_port=*((str*)a->elem[0].u.data);
1792-
ret=1; /* continue processing */
1844+
case SET_ADV_PORT_T:
1845+
script_trace("core", "set_adv_port", msg, a->line);
1846+
ret = do_action_set_adv_port(msg, a);
17931847
break;
1848+
17941849
#ifdef USE_TCP
17951850
case FORCE_TCP_ALIAS_T:
17961851
script_trace("core", "force_tcp_alias", msg, a->line) ;

cfg.y

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2835,23 +2835,24 @@ cmd: FORWARD LPAREN STRING RPAREN { mk_action2( $$, FORWARD_T,
28352835
"string expected"); }
28362836
| SET_ADV_ADDRESS error {$$=0; yyerror("missing '(' or ')' ?"); }
28372837
| SET_ADV_PORT LPAREN NUMBER RPAREN {
2838-
$$=0;
2839-
tmp=int2str($3, &i_tmp);
2840-
if ((str_tmp=pkg_malloc(sizeof(str)))==0){
2841-
LM_CRIT("cfg. parser: out of memory.\n");
2842-
}else{
2843-
if ((str_tmp->s=pkg_malloc(i_tmp))==0){
2838+
tstr.s = int2str($3, &tstr.len);
2839+
if (!(tmp = pkg_malloc(tstr.len + 1))) {
28442840
LM_CRIT("cfg. parser: out of memory.\n");
2845-
}else{
2846-
memcpy(str_tmp->s, tmp, i_tmp);
2847-
str_tmp->len=i_tmp;
2848-
mk_action2( $$, SET_ADV_PORT_T, STR_ST,
2849-
0, str_tmp, 0);
2850-
}
2841+
$$ = 0;
2842+
} else {
2843+
memcpy(tmp, tstr.s, tstr.len);
2844+
tmp[tstr.len] = '\0';
2845+
mk_action2($$, SET_ADV_PORT_T, STR_ST,
2846+
0, tmp, 0);
28512847
}
28522848
}
2853-
| SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, "
2854-
"string expected"); }
2849+
| SET_ADV_PORT LPAREN STRING RPAREN {
2850+
mk_action2($$, SET_ADV_PORT_T,
2851+
STR_ST, NOSUBTYPE,
2852+
$3, NULL);
2853+
}
2854+
| SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument "
2855+
"(string or integer expected)"); }
28552856
| SET_ADV_PORT error {$$=0; yyerror("missing '(' or ')' ?"); }
28562857
| FORCE_SEND_SOCKET LPAREN phostport RPAREN {
28572858
mk_action2( $$, FORCE_SEND_SOCKET_T,

modules/tm/sip_msg.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,9 +323,21 @@ struct sip_msg* sip_msg_cloner( struct sip_msg *org_msg, int *sip_msg_len )
323323
len = ROUND4(sizeof( struct sip_msg ));
324324
/*we will keep only the original msg +ZT */
325325
len += ROUND4(org_msg->len + 1);
326+
326327
/*the new uri (if any)*/
327328
if (org_msg->new_uri.s && org_msg->new_uri.len)
328-
len+= ROUND4(org_msg->new_uri.len);
329+
len += ROUND4(org_msg->new_uri.len);
330+
331+
if (org_msg->set_global_address.s) {
332+
LM_DBG("XXX - have address\n");
333+
len += ROUND4(org_msg->set_global_address.len);
334+
}
335+
336+
if (org_msg->set_global_port.s) {
337+
LM_DBG("XXX - have port\n");
338+
len += ROUND4(org_msg->set_global_port.len);
339+
}
340+
329341
/*all the headers*/
330342
for( hdr=org_msg->headers ; hdr ; hdr=hdr->next )
331343
{
@@ -465,13 +477,29 @@ do { \
465477
p += ROUND4(sizeof(struct sip_msg));
466478
new_msg->add_rm = 0;
467479
new_msg->body_lumps = 0;
480+
468481
/* new_uri */
469482
if (org_msg->new_uri.s && org_msg->new_uri.len)
470483
{
471484
new_msg->new_uri.s = p;
472485
memcpy( p , org_msg->new_uri.s , org_msg->new_uri.len);
473486
p += ROUND4(org_msg->new_uri.len);
474487
}
488+
489+
/* advertised address and port */
490+
if (org_msg->set_global_address.s)
491+
{
492+
new_msg->set_global_address.s = p;
493+
memcpy(p, org_msg->set_global_address.s, org_msg->set_global_address.len);
494+
p += ROUND4(org_msg->set_global_address.len);
495+
}
496+
if (org_msg->set_global_port.s)
497+
{
498+
new_msg->set_global_port.s = p;
499+
memcpy(p, org_msg->set_global_port.s, org_msg->set_global_port.len);
500+
p += ROUND4(org_msg->set_global_port.len);
501+
}
502+
475503
/* dst_uri to zero */
476504
new_msg->dst_uri.s = 0;
477505
new_msg->dst_uri.len = 0;

modules/tm/t_msgbuilder.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,6 @@ static inline struct sip_msg* buf_to_sip_msg(char *buf, unsigned int len,
9393
return NULL;
9494
}
9595
/* populate some special fields in sip_msg */
96-
req.set_global_address=default_global_address;
97-
req.set_global_port=default_global_port;
9896
req.force_send_socket = dialog->send_sock;
9997
if (set_dst_uri(&req, dialog->hooks.next_hop)) {
10098
LM_ERR("failed to set dst_uri");

modules/tm/t_reply.c

Lines changed: 43 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -554,13 +554,37 @@ static inline int fake_req(struct sip_msg *faked_req, struct sip_msg *shm_msg,
554554
faked_req->new_uri.s=pkg_malloc( uac->uri.len+1 );
555555
if (!faked_req->new_uri.s) {
556556
LM_ERR("no uri/pkg mem\n");
557-
goto error;
557+
return 0;
558558
}
559559
faked_req->new_uri.len = uac->uri.len;
560560
memcpy( faked_req->new_uri.s, uac->uri.s, uac->uri.len);
561561
faked_req->new_uri.s[faked_req->new_uri.len]=0;
562562
faked_req->parsed_uri_ok = 0;
563563

564+
/*
565+
* duplicate the advertised address and port into private mem
566+
* so that they can be changed at script level
567+
*/
568+
if (shm_msg->set_global_address.s) {
569+
faked_req->set_global_address.s = pkg_malloc(shm_msg->set_global_address.len);
570+
if (!faked_req->set_global_address.s) {
571+
LM_ERR("out of pkg mem\n");
572+
goto out;
573+
}
574+
memcpy(faked_req->set_global_address.s, shm_msg->set_global_address.s,
575+
shm_msg->set_global_address.len);
576+
}
577+
578+
if (shm_msg->set_global_port.s) {
579+
faked_req->set_global_port.s = pkg_malloc(shm_msg->set_global_port.len);
580+
if (!faked_req->set_global_port.s) {
581+
LM_ERR("out of pkg mem\n");
582+
goto out1;
583+
}
584+
memcpy(faked_req->set_global_port.s, shm_msg->set_global_port.s,
585+
shm_msg->set_global_port.len);
586+
}
587+
564588
/* we could also restore dst_uri, but will be confusing from script,
565589
* so let it set to NULL */
566590

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

572596
return 1;
573-
error:
597+
598+
out1:
599+
pkg_free(faked_req->set_global_address.s);
600+
out:
601+
pkg_free(faked_req->new_uri.s);
602+
574603
return 0;
575604
}
576605

@@ -579,15 +608,23 @@ inline static void free_faked_req(struct sip_msg *faked_req, struct cell *t)
579608
{
580609
if (faked_req->new_uri.s) {
581610
pkg_free(faked_req->new_uri.s);
582-
faked_req->new_uri.s = 0;
611+
faked_req->new_uri.s = NULL;
583612
}
584613
if (faked_req->dst_uri.s) {
585614
pkg_free(faked_req->dst_uri.s);
586-
faked_req->dst_uri.s = 0;
615+
faked_req->dst_uri.s = NULL;
587616
}
588617
if (faked_req->path_vec.s) {
589618
pkg_free(faked_req->path_vec.s);
590-
faked_req->path_vec.s = 0;
619+
faked_req->path_vec.s = NULL;
620+
}
621+
if (faked_req->set_global_address.s) {
622+
pkg_free(faked_req->set_global_address.s);
623+
faked_req->set_global_address.s = NULL;
624+
}
625+
if (faked_req->set_global_port.s) {
626+
pkg_free(faked_req->set_global_port.s);
627+
faked_req->set_global_port.s = NULL;
591628
}
592629

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

598635
if (faked_req->multi) {
599636
free_multi_body(faked_req->multi);
600-
faked_req->multi = 0;
637+
faked_req->multi = NULL;
601638
}
602639

603640
if (faked_req->msg_cb) {

msg_translator.c

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -575,17 +575,23 @@ int lumps_len(struct sip_msg* msg, struct lump* lumps,
575575
s_offset=0;
576576
new_len=0;
577577
last_del=0;
578+
578579
/* init send_address_str & send_port_str */
579580
if(send_sock && send_sock->adv_name_str.len)
580581
send_address_str=&(send_sock->adv_name_str);
581-
else if (msg->set_global_address.len)
582+
else if (msg->set_global_address.s)
582583
send_address_str=&(msg->set_global_address);
584+
else if (default_global_address.s)
585+
send_address_str=&default_global_address;
583586
else
584587
send_address_str=&(send_sock->address_str);
588+
585589
if(send_sock && send_sock->adv_port_str.len)
586590
send_port_str=&(send_sock->adv_port_str);
587-
else if (msg->set_global_port.len)
591+
else if (msg->set_global_port.s)
588592
send_port_str=&(msg->set_global_port);
593+
else if (default_global_port.s)
594+
send_port_str=&default_global_port;
589595
else
590596
send_port_str=&(send_sock->port_no_str);
591597

@@ -935,12 +941,16 @@ void process_lumps( struct sip_msg* msg,
935941
send_address_str=&(send_sock->adv_name_str);
936942
else if (msg->set_global_address.len)
937943
send_address_str=&(msg->set_global_address);
944+
else if (default_global_address.s)
945+
send_address_str=&default_global_address;
938946
else
939947
send_address_str=&(send_sock->address_str);
940948
if(send_sock && send_sock->adv_port_str.len)
941949
send_port_str=&(send_sock->adv_port_str);
942950
else if (msg->set_global_port.len)
943951
send_port_str=&(msg->set_global_port);
952+
else if (default_global_port.s)
953+
send_port_str=&default_global_port;
944954
else
945955
send_port_str=&(send_sock->port_no_str);
946956

@@ -1987,7 +1997,7 @@ char* via_builder( unsigned int *len,
19871997
address_str=hp->host;
19881998
else if(send_sock->adv_name_str.len)
19891999
address_str=&(send_sock->adv_name_str);
1990-
else if (default_global_address.len)
2000+
else if (default_global_address.s)
19912001
address_str=&default_global_address;
19922002
else
19932003
address_str=&(send_sock->address_str);
@@ -1996,7 +2006,7 @@ char* via_builder( unsigned int *len,
19962006
port_str=hp->port;
19972007
else if(send_sock->adv_port_str.len)
19982008
port_str=&(send_sock->adv_port_str);
1999-
else if (default_global_port.len)
2009+
else if (default_global_port.s)
20002010
port_str=&default_global_port;
20012011
else
20022012
port_str=&(send_sock->port_no_str);

0 commit comments

Comments
 (0)