New upstream version 4.4.6

changes/30/14430/1 upstream/4.4.6
Victor Seva 8 years ago
parent e0fd465da5
commit 78c035c816

@ -6,11 +6,10 @@ compiler:
services:
- docker
before_install:
- docker pull linuxmaniac/pkg-kamailio-docker:stretch
script: docker run -v $TRAVIS_BUILD_DIR:/code:rw linuxmaniac/pkg-kamailio-docker:stretch /bin/bash -c "export CC=$CC; cd /code; ./test/travis/build_travis.sh"
- docker pull kamailio/pkg-kamailio-docker:4.4-jessie
script: docker run -v $TRAVIS_BUILD_DIR:/code:rw kamailio/pkg-kamailio-docker:4.4-jessie /bin/bash -c "export DIST=jessie CC=$CC; cd /code; ./test/travis/build_travis.sh"
branches:
only:
- 'master'
- '/^4\.[0-9]+$/'
notifications:
irc:
@ -20,6 +19,6 @@ notifications:
on_failure: always
email:
recipients:
- sr-dev@lists.sip-router.org
- sr-dev@lists.kamailio.org
on_success: never
on_failure: always

File diff suppressed because it is too large Load Diff

@ -101,7 +101,7 @@ INSTALL_FLAVOUR=$(FLAVOUR)
# version number
VERSION = 4
PATCHLEVEL = 4
SUBLEVEL = 5
SUBLEVEL = 6
# memory manager switcher
# 0 - f_malloc (fast malloc)
@ -304,6 +304,8 @@ sparc64_macros= __sparcv9 __sparc_v9__
arm_macros= __arm__ __thumb__
arm6_macros= __ARM_ARCH_6__
aarch64_macros= __aarch64__
ppc_macros= __powerpc __powerpc__ __POWERPC__ __ppc__ _ARCH_PPC
ppc64_macros= __ppc64__ _ARCH_PPC64
@ -368,6 +370,12 @@ ARCH:=$(CC_ARCH)
else
ARCH:=$(HOST_ARCH)
endif
# retarget amd64 to x86_64
ifeq ($(ARCH), amd64)
override ARCH=x86_64
endif
$(info target architecture <$(ARCH)>, host architecture <$(HOST_ARCH)>)
LIBDIR ?=
@ -802,6 +810,11 @@ ifeq ($(ARCH), arm6)
C_DEFS+=-DNOSMP # very unlikely to have an smp arm
endif
ifeq ($(ARCH), aarch64)
use_fast_lock=yes
C_DEFS+=-DNOSMP
endif
ifeq ($(ARCH), ppc)
use_fast_lock=yes
endif
@ -1835,7 +1848,7 @@ ifeq ($(OS), solaris)
#LDFLAGS=-g $(PROFILE)
#MOD_LDFLAGS=-g -G
endif
YACC=yacc
#YACC=yacc
ifeq ($(CC_NAME), suncc)
LIBS= -ldl -lresolv

@ -207,7 +207,7 @@ static: $(objs)
# (it's usefull to have it separated from clean for speeding up make proper)
.PHONY: local-clean
local-clean:
-@rm -f $(objs) $(NAME) $(objs:.o=.il) librpath.lst 2>/dev/null
-@rm -f $(objs) $(NAME) $(objs:.o=.il) *.a librpath.lst 2>/dev/null
.PHONY: clean
clean: local-clean

@ -2,6 +2,6 @@
* DO NOT EDIT IT
*/
#define REPO_VER "f98162"
#define REPO_HASH "f98162"
#define REPO_VER "becbde"
#define REPO_HASH "becbde"
#define REPO_STATE ""

@ -123,7 +123,7 @@
%}
/* start conditions */
%x STRING1 STRING2 STR_BETWEEN COMMENT COMMENT_LN ATTR SELECT AVP_PVAR PVAR_P
%x STRING1 STRING2 STR_BETWEEN COMMENT COMMENT_LN ATTR SELECT AVP_PVAR PVAR_P
%x PVARID INCLF IMPTF EVRTNAME
%x LINECOMMENT DEFINE_ID DEFINE_EOL DEFINE_DATA IFDEF_ID IFDEF_EOL IFDEF_SKIP
@ -1055,7 +1055,7 @@ IMPORTFILE "import_file"
yymore();
break;
case SR_COMPAT_MAX:
default:
default:
state=AVP_PVAR_S; BEGIN(AVP_PVAR);
yymore();
break;
@ -1121,14 +1121,14 @@ IMPORTFILE "import_file"
<INITIAL>{CR} { count();/* return CR;*/ }
<INITIAL,SELECT>{QUOTES} { count(); old_initial = YY_START;
<INITIAL,SELECT>{QUOTES} { count(); old_initial = YY_START;
old_state = state; state=STRING_S;
BEGIN(STRING1); }
<INITIAL>{TICK} { count(); old_initial = YY_START; old_state = state;
state=STRING_S; BEGIN(STRING2); }
<STRING1>{QUOTES} { count_more();
<STRING1>{QUOTES} { count_more();
yytext[yyleng-1]=0; yyleng--;
addstr(&s_buf, yytext, yyleng);
state=STR_BETWEEN_S;
@ -1162,7 +1162,7 @@ IMPORTFILE "import_file"
<STR_BETWEEN>{EAT_ABLE}|{CR} { count_ignore(); }
<STR_BETWEEN>{QUOTES} { count_more(); state=STRING_S;
BEGIN(STRING1);}
<STR_BETWEEN>. {
<STR_BETWEEN>. {
yyless(0); /* reparse it */
/* ignore the whitespace now that is
counted, return saved string value */
@ -1197,7 +1197,7 @@ IMPORTFILE "import_file"
<INITIAL>{PREP_START}{REDEF}{EAT_ABLE}+ { count(); pp_define_set_type(2);
state = DEFINE_S; BEGIN(DEFINE_ID); }
<DEFINE_ID>{ID}{MINUS} { count();
LOG(L_CRIT,
LM_CRIT(
"error at %s line %d: '-' not allowed\n",
(finame)?finame:"cfg", line);
exit(-1);
@ -1230,7 +1230,7 @@ IMPORTFILE "import_file"
if (pp_ifdef_type(0)) return 1;
state = IFDEF_S; BEGIN(IFDEF_ID); }
<IFDEF_ID>{ID}{MINUS} { count();
LOG(L_CRIT,
LM_CRIT(
"error at %s line %d: '-' not allowed\n",
(finame)?finame:"cfg", line);
exit(-1);
@ -1292,7 +1292,7 @@ IMPORTFILE "import_file"
r = pp_subst_run(&s_buf.s);
if(sr_push_yy_state(s_buf.s, 1)<0)
{
LOG(L_CRIT, "error at %s line %d\n", (finame)?finame:"cfg", line);
LM_CRIT("error at %s line %d\n", (finame)?finame:"cfg", line);
exit(-1);
}
memset(&s_buf, 0, sizeof(s_buf));
@ -1310,7 +1310,7 @@ IMPORTFILE "import_file"
memset(&s_buf, 0, sizeof(s_buf));
return STRING;
case STRING_S:
LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF in"
LM_CRIT("cfg. parser: unexpected EOF in"
" unclosed string\n");
if (s_buf.s){
pkg_free(s_buf.s);
@ -1319,28 +1319,28 @@ IMPORTFILE "import_file"
}
break;
case COMMENT_S:
LOG(L_CRIT, "ERROR: cfg. parser: unexpected EOF:"
LM_CRIT("cfg. parser: unexpected EOF:"
" %d comments open\n", comment_nest);
break;
case COMMENT_LN_S:
LOG(L_CRIT, "ERROR: unexpected EOF:"
LM_CRIT("unexpected EOF:"
"comment line open\n");
break;
case ATTR_S:
LOG(L_CRIT, "ERROR: unexpected EOF"
LM_CRIT("unexpected EOF"
" while parsing"
" avp name\n");
break;
case PVARID_S:
p_nest=0;
case PVAR_P_S:
LOG(L_CRIT, "ERROR: unexpected EOF"
case PVAR_P_S:
LM_CRIT("unexpected EOF"
" while parsing pvar name"
" (%d paranthesis open)\n",
p_nest);
break;
case AVP_PVAR_S:
LOG(L_CRIT, "ERROR: unexpected EOF"
LM_CRIT("unexpected EOF"
" while parsing"
" avp or pvar name\n");
}
@ -1386,9 +1386,8 @@ static char* addstr(struct str_buf* dst_b, char* src, int len)
return dst_b->s;
error:
LOG(L_CRIT, "ERROR:lex:addstr: memory allocation error\n");
LOG(L_CRIT, "ERROR:lex:addstr: try to increase pkg size with"
" -M parameter\n");
LM_CRIT("lex: memory allocation error\n");
LM_CRIT("lex: try to increase pkg size with -M parameter\n");
exit(-1);
}
@ -1473,18 +1472,18 @@ static int sr_push_yy_state(char *fin, int mode)
if ( include_stack_ptr >= MAX_INCLUDE_DEPTH )
{
LOG(L_CRIT, "too many includes\n");
LM_CRIT("too many includes\n");
return -1;
}
l = strlen(fin);
if(l>=MAX_INCLUDE_FNAME)
{
LOG(L_CRIT, "included file name too long: %s\n", fin);
LM_CRIT("included file name too long: %s\n", fin);
return -1;
}
if(fin[0]!='"' || fin[l-1]!='"')
{
LOG(L_CRIT, "included file name must be between quotes: %s\n", fin);
LM_CRIT("included file name must be between quotes: %s\n", fin);
return -1;
}
j = 0;
@ -1494,7 +1493,7 @@ static int sr_push_yy_state(char *fin, int mode)
case '\\':
if(i+1==l-1)
{
LOG(L_CRIT, "invalid escape at %d in included file name: %s\n", i, fin);
LM_CRIT("invalid escape at %d in included file name: %s\n", i, fin);
return -1;
}
i++;
@ -1518,7 +1517,7 @@ static int sr_push_yy_state(char *fin, int mode)
}
if(j==0)
{
LOG(L_CRIT, "invalid included file name: %s\n", fin);
LM_CRIT("invalid included file name: %s\n", fin);
return -1;
}
fbuf[j] = '\0';
@ -1532,10 +1531,10 @@ static int sr_push_yy_state(char *fin, int mode)
{
if(mode==0)
{
LOG(L_CRIT, "cannot open included file: %s\n", fin);
LM_CRIT("cannot open included file: %s\n", fin);
return -1;
} else {
LOG(L_DBG, "importing file ignored: %s\n", fin);
LM_DBG("importing file ignored: %s\n", fin);
return 0;
}
}
@ -1545,10 +1544,10 @@ static int sr_push_yy_state(char *fin, int mode)
/* nothing else to try */
if(mode==0)
{
LOG(L_CRIT, "cannot open included file: %s\n", fin);
LM_CRIT("cannot open included file: %s\n", fin);
return -1;
} else {
LOG(L_DBG, "importing file ignored: %s\n", fin);
LM_DBG("importing file ignored: %s\n", fin);
return 0;
}
}
@ -1556,7 +1555,7 @@ static int sr_push_yy_state(char *fin, int mode)
newf = (char*)pkg_malloc(x-tmpfiname+strlen(fbuf)+2);
if(newf==0)
{
LOG(L_CRIT, "no more pkg\n");
LM_CRIT("no more pkg\n");
return -1;
}
newf[0] = '\0';
@ -1570,14 +1569,14 @@ static int sr_push_yy_state(char *fin, int mode)
pkg_free(newf);
if(mode==0)
{
LOG(L_CRIT, "cannot open included file: %s (%s)\n", fbuf, newf);
LM_CRIT("cannot open included file: %s (%s)\n", fbuf, newf);
return -1;
} else {
LOG(L_DBG, "importing file ignored: %s (%s)\n", fbuf, newf);
LM_DBG("importing file ignored: %s (%s)\n", fbuf, newf);
return 0;
}
}
LOG(L_DBG, "including file: %s (%s)\n", fbuf, newf);
LM_DBG("including file: %s (%s)\n", fbuf, newf);
} else {
newf = fbuf;
}
@ -1618,7 +1617,7 @@ static int sr_push_yy_state(char *fin, int mode)
{
if(newf!=fbuf)
pkg_free(newf);
LOG(L_CRIT, "no more pkg\n");
LM_CRIT("no more pkg\n");
return -1;
}
if(newf==fbuf)
@ -1627,7 +1626,7 @@ static int sr_push_yy_state(char *fin, int mode)
if(fn->fname==0)
{
pkg_free(fn);
LOG(L_CRIT, "no more pkg!\n");
LM_CRIT("no more pkg!\n");
return -1;
}
strcpy(fn->fname, fbuf);
@ -1703,7 +1702,7 @@ int pp_define(int len, const char * text)
LM_DBG("defining id: %.*s\n", len, text);
if (pp_num_defines == MAX_DEFINES) {
LOG(L_CRIT, "ERROR: too many defines -- adjust MAX_DEFINES\n");
LM_CRIT("too many defines -- adjust MAX_DEFINES\n");
return -1;
}
@ -1711,11 +1710,11 @@ int pp_define(int len, const char * text)
ppos = pp_lookup(len, text);
if(ppos >= 0) {
if(pp_define_type==1) {
LOG(L_DBG, "ignoring - already defined: %.*s\n", len, text);
LM_DBG("ignoring - already defined: %.*s\n", len, text);
pp_define_index = -2;
return 0;
} else if(pp_define_type==2) {
LOG(L_DBG, "redefining: %.*s\n", len, text);
LM_DBG("redefining: %.*s\n", len, text);
pp_define_index = ppos;
if(pp_defines[ppos][1].s != NULL) {
pkg_free(pp_defines[ppos][1].s);
@ -1724,7 +1723,7 @@ int pp_define(int len, const char * text)
}
return 0;
} else {
LOG(L_CRIT, "ERROR: already defined: %.*s\n", len, text);
LM_CRIT("already defined: %.*s\n", len, text);
return -1;
}
}
@ -1732,7 +1731,7 @@ int pp_define(int len, const char * text)
pp_defines[pp_num_defines][0].len = len;
pp_defines[pp_num_defines][0].s = (char*)pkg_malloc(len+1);
if(pp_defines[pp_num_defines][0].s==NULL) {
LOG(L_CRIT, "no more memory to define: %.*s\n", len, text);
LM_CRIT("no more memory to define: %.*s\n", len, text);
return -1;
}
memcpy(pp_defines[pp_num_defines][0].s, text, len);
@ -1755,30 +1754,30 @@ int pp_define_set(int len, char *text)
if(pp_define_index < 0) {
/* invalid position in define table */
LOG(L_BUG, "BUG: the index in define table not set yet\n");
LM_BUG("BUG: the index in define table not set yet\n");
return -1;
}
if(len<=0) {
LOG(L_DBG, "no define value - ignoring\n");
LM_DBG("no define value - ignoring\n");
return 0;
}
if (pp_num_defines == MAX_DEFINES) {
LOG(L_CRIT, "ERROR: too many defines -- adjust MAX_DEFINES\n");
LM_CRIT("too many defines -- adjust MAX_DEFINES\n");
return -1;
}
if (pp_num_defines == 0) {
LOG(L_BUG, "BUG: setting define value, but no define id yet\n");
LM_BUG("BUG: setting define value, but no define id yet\n");
return -1;
}
ppos = pp_define_index;
if (pp_defines[ppos][0].s == NULL) {
LOG(L_BUG, "BUG: last define ID is null\n");
LM_BUG("BUG: last define ID is null\n");
return -1;
}
if (pp_defines[ppos][1].s != NULL) {
LOG(L_BUG, "BUG: ID %.*s [%d] overwritten\n",
LM_BUG("BUG: ID %.*s [%d] overwritten\n",
pp_defines[ppos][0].len,
pp_defines[ppos][0].s, ppos);
return -1;
@ -1821,7 +1820,7 @@ static str *pp_define_get(int len, const char * text)
static int pp_ifdef_type(int type)
{
if (pp_sptr == MAX_IFDEFS) {
LOG(L_CRIT, "ERROR: too many nested ifdefs -- adjust MAX_IFDEFS\n");
LM_CRIT("too many nested ifdefs -- adjust MAX_IFDEFS\n");
return -1;
}

186
cfg.y

@ -587,6 +587,7 @@ extern char *default_routename;
%type <intval> avpflag_oper
%type <intval> rve_un_op
%type <strval> cfg_var_id
%type <strval> cfg_var_idn
/* %type <intval> rve_op */
/*%type <route_el> rules;
@ -624,14 +625,12 @@ listen_id:
if ($1){
tmp=ip_addr2a($1);
if (tmp==0) {
LOG(L_CRIT, "ERROR: cfg. parser: bad ip "
"address.\n");
LM_CRIT("cfg. parser: bad ip address.\n");
$$=0;
} else {
$$=pkg_malloc(strlen(tmp)+1);
if ($$==0) {
LOG(L_CRIT, "ERROR: cfg. parser: out of "
"memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
strncpy($$, tmp, strlen(tmp)+1);
}
@ -641,8 +640,7 @@ listen_id:
| STRING {
$$=pkg_malloc(strlen($1)+1);
if ($$==0) {
LOG(L_CRIT, "ERROR: cfg. parser: out of "
"memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
strncpy($$, $1, strlen($1)+1);
}
@ -651,8 +649,7 @@ listen_id:
if ($1){
$$=pkg_malloc(strlen($1)+1);
if ($$==0) {
LOG(L_CRIT, "ERROR: cfg. parser: out of "
"memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
strncpy($$, $1, strlen($1)+1);
}
@ -663,7 +660,7 @@ listen_id:
listen_id_lst:
listen_id { $$=mk_name_lst($1, SI_IS_MHOMED); }
| listen_id COMMA listen_id_lst { $$=mk_name_lst($1, SI_IS_MHOMED);
| listen_id COMMA listen_id_lst { $$=mk_name_lst($1, SI_IS_MHOMED);
if ($$) $$->next=$3;
}
;
@ -698,7 +695,7 @@ phostport:
| listen_id COLON port { $$=mk_listen_id($1, 0, $3); }
| proto COLON listen_id { $$=mk_listen_id($3, $1, 0); }
| proto COLON listen_id COLON port { $$=mk_listen_id($3, $1, $5);}
| listen_id COLON error { $$=0; yyerror(" port number expected"); }
| listen_id COLON error { $$=0; yyerror("port number expected"); }
;
listen_phostport:
@ -706,7 +703,7 @@ listen_phostport:
| listen_id2 COLON port { $$=mk_listen_id2($1, 0, $3); }
| proto COLON listen_id2 { $$=mk_listen_id2($3, $1, 0); }
| proto COLON listen_id2 COLON port { $$=mk_listen_id2($3, $1, $5);}
| listen_id2 COLON error { $$=0; yyerror(" port number expected"); }
| listen_id2 COLON error { $$=0; yyerror("port number expected"); }
;
id_lst:
@ -761,8 +758,8 @@ assign_stm:
| FORK_DELAY EQUAL error { yyerror("number expected"); }
| MODINIT_DELAY EQUAL NUMBER { set_modinit_delay($3); }
| MODINIT_DELAY EQUAL error { yyerror("number expected"); }
| LOGSTDERROR EQUAL NUMBER { if (!config_check) /* if set from cmd line, don't overwrite from yyparse()*/
if(log_stderr == 0) log_stderr=$3;
| LOGSTDERROR EQUAL NUMBER { if (!config_check) /* if set from cmd line, don't overwrite from yyparse()*/
if(log_stderr == 0) log_stderr=$3;
}
| LOGSTDERROR EQUAL error { yyerror("boolean value expected"); }
| LOGFACILITY EQUAL ID {
@ -798,7 +795,7 @@ assign_stm:
| DNS_TCP_PREF error { yyerror("number expected"); }
| DNS_TLS_PREF EQUAL intno { IF_NAPTR(default_core_cfg.dns_tls_pref=$3);}
| DNS_TLS_PREF error { yyerror("number expected"); }
| DNS_SCTP_PREF EQUAL intno {
| DNS_SCTP_PREF EQUAL intno {
IF_NAPTR(default_core_cfg.dns_sctp_pref=$3); }
| DNS_SCTP_PREF error { yyerror("number expected"); }
| DNS_RETR_TIME EQUAL NUMBER { default_core_cfg.dns_retr_time=$3; }
@ -844,7 +841,7 @@ assign_stm:
}
| USE_DST_BLST error { yyerror("boolean value expected"); }
| DST_BLST_MEM EQUAL NUMBER {
IF_DST_BLACKLIST(default_core_cfg.blst_max_mem=$3);
IF_DST_BLACKLIST(default_core_cfg.blst_max_mem=$3);
}
| DST_BLST_MEM error { yyerror("boolean value expected"); }
| DST_BLST_TTL EQUAL NUMBER {
@ -917,7 +914,7 @@ assign_stm:
yyerror("user must be before any modparam or the"
" route blocks");
else if (user==0)
user=$3;
user=$3;
}
| USER EQUAL ID {
if (shm_initialized())
@ -1366,8 +1363,7 @@ assign_stm:
lst_tmp->addr_lst->next,
lst_tmp->port, lst_tmp->proto,
lst_tmp->flags)!=0) {
LOG(L_CRIT, "ERROR: cfg. parser: failed to add listen"
" address\n");
LM_CRIT("cfg. parser: failed to add listen address\n");
break;
}
}
@ -1380,8 +1376,7 @@ assign_stm:
lst_tmp->port, lst_tmp->proto,
$5, $7,
lst_tmp->flags)!=0) {
LOG(L_CRIT, "ERROR: cfg. parser: failed to add listen"
" address\n");
LM_CRIT("cfg. parser: failed to add listen address\n");
break;
}
}
@ -1400,7 +1395,7 @@ assign_stm:
}
free_socket_id_lst($3);
}
| ALIAS EQUAL error { yyerror(" hostname expected"); }
| ALIAS EQUAL error { yyerror("hostname expected"); }
| SR_AUTO_ALIASES EQUAL NUMBER { sr_auto_aliases=$3; }
| SR_AUTO_ALIASES EQUAL error { yyerror("boolean value expected"); }
| ADVERTISED_ADDRESS EQUAL listen_id {
@ -1413,7 +1408,7 @@ assign_stm:
| ADVERTISED_PORT EQUAL NUMBER {
tmp=int2str($3, &i_tmp);
if ((default_global_port.s=pkg_malloc(i_tmp))==0) {
LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
default_global_port.len=0;
} else {
default_global_port.len=i_tmp;
@ -1549,41 +1544,50 @@ assign_stm:
| cfg_var
| error EQUAL { yyerror("unknown config variable"); }
;
cfg_var_id: ID
cfg_var_id: ID
| DEFAULT { $$="default" ; } /*needed to allow default as cfg var. name*/
;
cfg_var_idn: ID
| DEFAULT { $$="default" ; } /*needed to allow default as cfg var. name*/
| NUMBER {
yyerror("cfg var field name - use of number or reserved token not allowed: %s",
yy_number_str);
YYERROR;
}
;
cfg_var:
cfg_var_id DOT cfg_var_id EQUAL NUMBER {
cfg_var_id DOT cfg_var_idn EQUAL NUMBER {
if (cfg_declare_int($1, $3, $5, 0, 0, NULL)) {
yyerror("variable cannot be declared");
}
}
| cfg_var_id DOT cfg_var_id EQUAL STRING {
| cfg_var_id DOT cfg_var_idn EQUAL STRING {
if (cfg_declare_str($1, $3, $5, NULL)) {
yyerror("variable cannot be declared");
}
}
| cfg_var_id DOT cfg_var_id EQUAL NUMBER CFG_DESCRIPTION STRING {
| cfg_var_id DOT cfg_var_idn EQUAL NUMBER CFG_DESCRIPTION STRING {
if (cfg_declare_int($1, $3, $5, 0, 0, $7)) {
yyerror("variable cannot be declared");
}
}
| cfg_var_id DOT cfg_var_id EQUAL STRING CFG_DESCRIPTION STRING {
| cfg_var_id DOT cfg_var_idn EQUAL STRING CFG_DESCRIPTION STRING {
if (cfg_declare_str($1, $3, $5, $7)) {
yyerror("variable cannot be declared");
}
}
| cfg_var_id DOT cfg_var_id EQUAL error {
yyerror("number or string expected");
| cfg_var_id DOT cfg_var_idn EQUAL error {
yyerror("number or string expected");
}
| cfg_var_id LBRACK NUMBER RBRACK DOT cfg_var_id EQUAL NUMBER {
| cfg_var_id LBRACK NUMBER RBRACK DOT cfg_var_idn EQUAL NUMBER {
if (cfg_ginst_var_int($1, $3, $6, $8)) {
yyerror("variable cannot be added to the group instance");
}
}
| cfg_var_id LBRACK NUMBER RBRACK DOT cfg_var_id EQUAL STRING {
| cfg_var_id LBRACK NUMBER RBRACK DOT cfg_var_idn EQUAL STRING {
if (cfg_ginst_var_string($1, $3, $6, $8)) {
yyerror("variable cannot be added to the group instance");
}
@ -1592,7 +1596,7 @@ cfg_var:
module_stm:
LOADMODULE STRING {
DBG("loading module %s\n", $2);
LM_DBG("loading module %s\n", $2);
if (load_module($2)!=0) {
yyerror("failed to load module");
}
@ -1600,22 +1604,22 @@ module_stm:
| LOADMODULE error { yyerror("string expected"); }
| LOADPATH STRING {
if(mods_dir_cmd==0) {
DBG("loading modules under %s\n", $2);
LM_DBG("loading modules under %s\n", $2);
printf("loading modules under config path: %s\n", $2);
mods_dir = $2;
} else {
DBG("ignoring mod path given in config: %s\n", $2);
LM_DBG("ignoring mod path given in config: %s\n", $2);
printf("loading modules under command line path: %s\n", mods_dir);
}
}
| LOADPATH error { yyerror("string expected"); }
| LOADPATH EQUAL STRING {
if(mods_dir_cmd==0) {
DBG("loading modules under %s\n", $3);
LM_DBG("loading modules under %s\n", $3);
printf("loading modules under config path: %s\n", $3);
mods_dir = $3;
} else {
DBG("ignoring mod path given in config: %s\n", $3);
LM_DBG("ignoring mod path given in config: %s\n", $3);
printf("loading modules under command line path: %s\n", mods_dir);
}
}
@ -1652,7 +1656,7 @@ ipv4:
NUMBER DOT NUMBER DOT NUMBER DOT NUMBER {
$$=pkg_malloc(sizeof(struct ip_addr));
if ($$==0) {
LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
memset($$, 0, sizeof(struct ip_addr));
$$->af=AF_INET;
@ -1681,7 +1685,7 @@ ipv6addr:
IPV6ADDR {
$$=pkg_malloc(sizeof(struct ip_addr));
if ($$==0) {
LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
memset($$, 0, sizeof(struct ip_addr));
$$->af=AF_INET6;
@ -1798,7 +1802,7 @@ onreply_route_stm:
}
| ROUTE_ONREPLY error { yyerror("invalid onreply_route statement"); }
| ROUTE_REPLY error { yyerror("invalid onreply_route statement"); }
| ROUTE_ONREPLY LBRACK route_name RBRACK
| ROUTE_ONREPLY LBRACK route_name RBRACK
{rt=(*$3=='0' && $3[1]==0)?CORE_ONREPLY_ROUTE:TM_ONREPLY_ROUTE;}
LBRACE actions RBRACE {
#ifdef SHM_MEM
@ -2014,7 +2018,7 @@ exp_elem:
| METHOD strop ID %prec EQUAL_T
{$$ = mk_elem($2, METHOD_O, 0, STRING_ST,$3); }
| METHOD strop error { $$=0; yyerror("string expected"); }
| METHOD error
| METHOD error
{ $$=0; yyerror("invalid operator,== , !=, or =~ expected"); }
| uri_type strop rval_expr %prec EQUAL_T
{$$ = mk_elem($2, $1, 0, RVE_ST, $3); }
@ -2070,7 +2074,7 @@ exp_elem:
ip_tmp=str2ip6(&s_tmp);
pkg_free(s_tmp.s);
if (ip_tmp) {
$$=mk_elem($2, $1, 0, NET_ST,
$$=mk_elem($2, $1, 0, NET_ST,
mk_new_net_bitlen(ip_tmp, ip_tmp->len*8) );
} else {
$$=mk_elem($2, $1, 0, RVE_ST, $3);
@ -2087,13 +2091,13 @@ exp_elem:
{ $$=0; yyerror( "ip address or hostname expected" ); }
| eip_op error
{ $$=0; yyerror("invalid operator, ==, != or =~ expected");}
| MYSELF equalop uri_type %prec EQUAL_T
{ $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
| MYSELF equalop eip_op %prec EQUAL_T
{ $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
| MYSELF equalop error %prec EQUAL_T
{ $$=0; yyerror(" URI, SRCIP or DSTIP expected"); }
{ $$=0; yyerror("URI, SRCIP or DSTIP expected"); }
| MYSELF error { $$=0; yyerror ("invalid operator, == or != expected"); }
;
@ -2120,7 +2124,7 @@ host:
if ($1){
$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
if ($$==0) {
LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
LM_CRIT("cfg. parser: memory allocation"
" failure while parsing host\n");
} else {
memcpy($$, $1, strlen($1));
@ -2136,7 +2140,7 @@ host:
if ($1){
$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
if ($$==0) {
LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
LM_CRIT("cfg. parser: memory allocation"
" failure while parsing host\n");
} else {
memcpy($$, $1, strlen($1));
@ -2168,7 +2172,7 @@ host_or_if:
if ($1){
$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
if ($$==0) {
LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
LM_CRIT("cfg. parser: memory allocation"
" failure while parsing host/interface name\n");
} else {
memcpy($$, $1, strlen($1));
@ -2184,7 +2188,7 @@ host_or_if:
if ($1){
$$=(char*)pkg_malloc(strlen($1)+1+strlen($3)+1);
if ($$==0) {
LOG(L_CRIT, "ERROR: cfg. parser: memory allocation"
LM_CRIT("cfg. parser: memory allocation"
" failure while parsing host/interface name\n");
} else {
memcpy($$, $1, strlen($1));
@ -2274,7 +2278,7 @@ if_cmd:
}else
YYERROR;
}
| IF rval_expr stm ELSE stm {
| IF rval_expr stm ELSE stm {
if ($2 && rval_expr_int_check($2)>=0){
warn_ct_rve($2, "if");
$$=mk_action( IF_T, 3, RVE_ST, $2, ACTIONS_ST, $3, ACTIONS_ST, $5);
@ -2362,7 +2366,7 @@ case_stms:
}
;
switch_cmd:
SWITCH rval_expr LBRACE case_stms RBRACE {
SWITCH rval_expr LBRACE case_stms RBRACE {
$$=0;
if ($2==0){
yyerror("bad expression in switch(...)");
@ -2404,7 +2408,7 @@ switch_cmd:
}
}
| SWITCH error { $$=0; yyerror ("bad expression in switch(...)"); }
| SWITCH rval_expr LBRACE error RBRACE
| SWITCH rval_expr LBRACE error RBRACE
{$$=0; yyerror ("bad switch body"); }
;
@ -2762,7 +2766,7 @@ rval_expr: rval { $$=$1;
| DEFINED error { $$=0; yyerror("bad expression"); }
;
assign_action: lval assign_op rval_expr { $$=mk_action($2, 2, LVAL_ST, $1,
assign_action: lval assign_op rval_expr { $$=mk_action($2, 2, LVAL_ST, $1,
RVE_ST, $3);
set_cfg_pos($$);
}
@ -2892,7 +2896,7 @@ cmd:
#endif
}
| FORWARD_TLS error { $$=0; yyerror("missing '(' or ')' ?"); }
| FORWARD_TLS LPAREN error RPAREN { $$=0;
| FORWARD_TLS LPAREN error RPAREN { $$=0;
yyerror("bad forward_tls argument"); }
| FORWARD_SCTP LPAREN host RPAREN {
#ifdef USE_SCTP
@ -2938,7 +2942,7 @@ cmd:
}
| FORWARD_SCTP LPAREN ip COMMA NUMBER RPAREN {
#ifdef USE_SCTP
$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST,
$$=mk_action(FORWARD_SCTP_T, 2, IP_ST, (void*)$3, NUMBER_ST,
(void*)$5); set_cfg_pos($$);
#else
$$=0;
@ -2971,7 +2975,7 @@ cmd:
#endif
}
| FORWARD_SCTP error { $$=0; yyerror("missing '(' or ')' ?"); }
| FORWARD_SCTP LPAREN error RPAREN { $$=0;
| FORWARD_SCTP LPAREN error RPAREN { $$=0;
yyerror("bad forward_sctp argument"); }
| LOG_TOK LPAREN STRING RPAREN {$$=mk_action(LOG_T, 2, NUMBER_ST,
(void*)(L_DBG+1), STRING_ST, $3);
@ -3143,7 +3147,7 @@ cmd:
| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
$$=0;
if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
str_tmp->s=$3;
str_tmp->len=$3?strlen($3):0;
@ -3157,10 +3161,10 @@ cmd:
$$=0;
tmp=int2str($3, &i_tmp);
if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
if ((str_tmp->s=pkg_malloc(i_tmp))==0) {
LOG(L_CRIT, "ERROR: cfg. parser: out of memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
memcpy(str_tmp->s, tmp, i_tmp);
str_tmp->len=i_tmp;
@ -3171,7 +3175,7 @@ cmd:
}
| SET_ADV_PORT LPAREN error RPAREN { $$=0; yyerror("bad argument, string expected"); }
| SET_ADV_PORT error {$$=0; yyerror("missing '(' or ')' ?"); }
| FORCE_SEND_SOCKET LPAREN phostport RPAREN {
| FORCE_SEND_SOCKET LPAREN phostport RPAREN {
$$=mk_action(FORCE_SEND_SOCKET_T, 1, SOCKID_ST, $3);
set_cfg_pos($$);
}
@ -3224,10 +3228,10 @@ cmd:
if (mod_func_action->val[0].u.data == 0) {
if (find_export_record($1, mod_func_action->val[1].u.number, 0,
&u_tmp) ) {
LOG(L_ERR, "misused command %s\n", $1);
LM_ERR("misused command %s\n", $1);
yyerror("Command cannot be used in the block\n");
} else {
LOG(L_ERR, "cfg. parser: failed to find command %s (params %ld)\n",
LM_ERR("cfg. parser: failed to find command %s (params %ld)\n",
$1, mod_func_action->val[1].u.number);
yyerror("unknown command, missing loadmodule?\n");
}
@ -3278,7 +3282,7 @@ ret_cmd:
(void*)(DROP_R_F|EXIT_R_F)); set_cfg_pos($$);
}
| DROP {
$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST,
$$=mk_action(DROP_T, 2, NUMBER_ST, 0, NUMBER_ST,
(void*)(DROP_R_F|EXIT_R_F)); set_cfg_pos($$);
}
| EXIT LPAREN RPAREN {
@ -3332,19 +3336,19 @@ static void warn_at(struct cfg_pos* p, char* format, ...)
{
va_list ap;
char s[256];
va_start(ap, format);
vsnprintf(s, sizeof(s), format, ap);
va_end(ap);
if (p->e_line!=p->s_line)
LOG(L_WARN, "warning in config file %s, from line %d, column %d to"
LM_WARN("warning in config file %s, from line %d, column %d to"
" line %d, column %d: %s\n",
p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
else if (p->s_col!=p->e_col)
LOG(L_WARN, "warning in config file %s, line %d, column %d-%d: %s\n",
LM_WARN("warning in config file %s, line %d, column %d-%d: %s\n",
p->fname, p->s_line, p->s_col, p->e_col, s);
else
LOG(L_WARN, "warning in config file %s, line %d, column %d: %s\n",
LM_WARN("warning in config file %s, line %d, column %d: %s\n",
p->fname, p->s_line, p->s_col, s);
cfg_warnings++;
}
@ -3355,19 +3359,19 @@ static void yyerror_at(struct cfg_pos* p, char* format, ...)
{
va_list ap;
char s[256];
va_start(ap, format);
vsnprintf(s, sizeof(s), format, ap);
va_end(ap);
if (p->e_line!=p->s_line)
LOG(L_CRIT, "parse error in config file %s, from line %d, column %d"
LM_CRIT("parse error in config file %s, from line %d, column %d"
" to line %d, column %d: %s\n",
p->fname, p->s_line, p->s_col, p->e_line, p->e_col, s);
else if (p->s_col!=p->e_col)
LOG(L_CRIT,"parse error in config file %s, line %d, column %d-%d: %s\n",
LM_CRIT("parse error in config file %s, line %d, column %d-%d: %s\n",
p->fname, p->s_line, p->s_col, p->e_col, s);
else
LOG(L_CRIT, "parse error in config file %s, line %d, column %d: %s\n",
LM_CRIT("parse error in config file %s, line %d, column %d: %s\n",
p->fname, p->s_line, p->s_col, s);
cfg_errors++;
}
@ -3379,7 +3383,7 @@ static void warn(char* format, ...)
va_list ap;
char s[256];
struct cfg_pos pos;
get_cpos(&pos);
va_start(ap, format);
vsnprintf(s, sizeof(s), format, ap);
@ -3394,7 +3398,7 @@ static void yyerror(char* format, ...)
va_list ap;
char s[256];
struct cfg_pos pos;
get_cpos(&pos);
va_start(ap, format);
vsnprintf(s, sizeof(s), format, ap);
@ -3433,7 +3437,7 @@ static struct rval_expr* mk_rve1(enum rval_expr_op op, struct rval_expr* rve1)
struct rval_expr* ret;
struct rval_expr* bad_rve;
enum rval_type type, bad_t, exp_t;
if (rve1==0)
return 0;
ret=mk_rval_expr1(op, rve1, &rve1->fpos);
@ -3459,7 +3463,7 @@ static struct rval_expr* mk_rve2(enum rval_expr_op op, struct rval_expr* rve1,
struct rval_expr* bad_rve;
enum rval_type type, bad_t, exp_t;
struct cfg_pos pos;
if ((rve1==0) || (rve2==0))
return 0;
bad_rve=0;
@ -3490,7 +3494,7 @@ static int rval_expr_int_check(struct rval_expr *rve)
{
struct rval_expr* bad_rve;
enum rval_type type, bad_t, exp_t;
if (rve==0){
yyerror("invalid expression");
return -1;
@ -3531,7 +3535,7 @@ static struct name_lst* mk_name_lst(char* host, int flags)
if (host==0) return 0;
l=pkg_malloc(sizeof(struct name_lst));
if (l==0) {
LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
l->name=host;
l->flags=flags;
@ -3547,7 +3551,7 @@ static struct socket_id* mk_listen_id(char* host, int proto, int port)
if (host==0) return 0;
l=pkg_malloc(sizeof(struct socket_id));
if (l==0) {
LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
l->addr_lst=mk_name_lst(host, 0);
if (l->addr_lst==0){
@ -3566,7 +3570,7 @@ static struct socket_id* mk_listen_id(char* host, int proto, int port)
static void free_name_lst(struct name_lst* lst)
{
struct name_lst* tmp;
while(lst){
tmp=lst;
lst=lst->next;
@ -3582,7 +3586,7 @@ static struct socket_id* mk_listen_id2(struct name_lst* addr_l, int proto,
if (addr_l==0) return 0;
l=pkg_malloc(sizeof(struct socket_id));
if (l==0) {
LOG(L_CRIT,"ERROR: cfg. parser: out of memory.\n");
LM_CRIT("cfg. parser: out of memory.\n");
} else {
l->flags=addr_l->flags;
l->port=port;
@ -3604,7 +3608,7 @@ static void free_socket_id(struct socket_id* i)
static void free_socket_id_lst(struct socket_id* lst)
{
struct socket_id* tmp;
while(lst){
tmp=lst;
lst=lst->next;
@ -3626,7 +3630,7 @@ static struct case_stms* mk_case_stm(struct rval_expr* ct, int is_re,
struct rval_expr* bad_rve;
enum rval_type type, bad_t, exp_t;
enum match_str_type t;
t=MATCH_UNKNOWN;
if (ct){
/* if ct!=0 => case, else if ct==0 is a default */
@ -3674,7 +3678,7 @@ static int case_check_type(struct case_stms* stms)
{
struct case_stms* c;
struct case_stms* s;
for(c=stms; c ; c=c->next){
if (!c->ct_rve) continue;
for (s=c->next; s; s=s->next){
@ -3698,7 +3702,7 @@ static int case_check_default(struct case_stms* stms)
{
struct case_stms* c;
int default_no;
default_no=0;
for(c=stms; c ; c=c->next)
if (c->ct_rve==0) default_no++;
@ -3709,8 +3713,8 @@ static int case_check_default(struct case_stms* stms)
/** fixes the parameters and the type of a module function call.
* It is done here instead of fix action, to have quicker feedback
* on error cases (e.g. passing a non constant to a function with a
* declared fixup)
* on error cases (e.g. passing a non constant to a function with a
* declared fixup)
* The rest of the fixup is done inside do_action().
* @param a - filled module function call (MODULE*_T) action structure
* complete with parameters, starting at val[2] and parameter
@ -3727,11 +3731,11 @@ static int mod_f_params_pre_fixup(struct action* a)
struct rvalue* rv;
int r;
str s;
cmd_exp = a->val[0].u.data;
param_no = a->val[1].u.number;
params = &a->val[2];
switch(cmd_exp->param_no) {
case 0:
a->type = MODULE0_T;
@ -3762,7 +3766,7 @@ static int mod_f_params_pre_fixup(struct action* a)
" (invalid number of parameters)", cmd_exp->name);
return -1;
}
if ( cmd_exp->fixup) {
if (is_fparam_rve_fixup(cmd_exp->fixup))
/* mark known fparam rve safe fixups */
@ -3814,10 +3818,10 @@ static void free_mod_func_action(struct action* a)
action_u_t* params;
int param_no;
int r;
param_no = a->val[1].u.number;
params = &a->val[2];
for (r=0; r < param_no; r++)
if (params[r].u.data)
rve_destroy(params[r].u.data);

@ -347,6 +347,9 @@ int init_dns_cache()
ret=E_OUT_OF_MEM;
goto error;
}
*dns_cache_mem_used=0;
#ifdef DNS_LU_LST
dns_last_used_lst=shm_malloc(sizeof(*dns_last_used_lst));
if (dns_last_used_lst==0){
@ -594,8 +597,10 @@ again:
cname_chain++;
cname.s=((struct cname_rdata*)e->rr_lst->rdata)->name;
cname.len= ((struct cname_rdata*)e->rr_lst->rdata)->name_len;
name=&cname;
goto again;
if(cname.s!=NULL && cname.len>0) {
name=&cname;
goto again;
}
}
}
return ret;
@ -2362,6 +2367,7 @@ inline static struct hostent* dns_entry2he(struct dns_hash_entry* e)
int af, len;
struct dns_rr* rr;
unsigned char rr_no;
unsigned char *ip;
ticks_t now;
int i;
@ -2389,7 +2395,15 @@ inline static struct hostent* dns_entry2he(struct dns_hash_entry* e)
for(i=0; rr && (i<DNS_HE_MAX_ADDR); i++,
rr=dns_entry_get_rr(e, &rr_no, now)){
p_addr[i]=&address[i*len];
memcpy(p_addr[i], ((struct a_rdata*)rr->rdata)->ip, len);
switch(e->type){
case T_A:
ip = ((struct a_rdata*)rr->rdata)->ip;
break;
case T_AAAA:
ip = ((struct aaaa_rdata*)rr->rdata)->ip6;
break;
}
memcpy(p_addr[i], ip, len);
}
if (i==0){
LM_DBG("no good records found (%d) for %.*s (%d)\n",

@ -400,11 +400,11 @@ void log_prefix_init(void);
# define DBG(fmt, args...)
# else
# define DBG(fmt, args...) LOG(L_DBG, fmt , ## args)
# endif
# endif
/* obsolete, do not use */
# define DEBUG(fmt, args...) DBG(fmt , ## args)
#endif /* __SUNPRO_C */
@ -415,6 +415,7 @@ void log_prefix_init(void);
#define LM_NPRL NPRL
#define LM_ALERT ALERT
#define LM_CRIT CRIT
#define LM_BUG BUG
#define LM_ERR ERR
#define LM_WARN WARN
#define LM_NOTICE NOTICE

@ -4,7 +4,7 @@
# - web: http://www.kamailio.org
# - git: http://sip-router.org
#
# Direct your questions about this file to: <sr-users@lists.sip-router.org>
# Direct your questions about this file to: <sr-users@lists.kamailio.org>
#
# Refer to the Core CookBook at http://www.kamailio.org/wiki/
# for an explanation of possible statements, functions and parameters.
@ -471,18 +471,20 @@ request_route {
exit;
}
# handle retransmissions
if (!is_method("ACK")) {
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
}
# handle requests within SIP dialogs
route(WITHINDLG);
### only initial requests (no To tag)
# handle retransmissions
if(t_precheck_trans()) {
t_check_trans();
exit;
}
t_check_trans();
# authentication
route(AUTH);

@ -3,6 +3,8 @@
*
* Copyright (C) 2001-2003 FhG Fokus
*
* Copyright (C) 2017 Core Network Dynamics for ARM8 (aarch64) support
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
@ -50,7 +52,7 @@ typedef volatile int fl_lock_t;
/* what membar to use (if any) after taking a lock. This
* was separated from the lock code to allow better optimizations.
* e.g.: use the membar_getlock only after getting the lock and don't use
* e.g.: use the membar_getlock only after getting the lock and don't use
* it if lock_get fails / when spinning on tsl.
* There is no corresponding membar_release_lock (because lock_release
* must always include the needed memory barrier).
@ -76,14 +78,20 @@ typedef volatile int fl_lock_t;
#ifndef NOSMP
#warning smp not supported on arm* (no membars), try compiling with -DNOSMP
#endif /* NOSMP */
#define membar_getlock()
#define membar_getlock()
#elif defined(__CPU_aarch64)
#ifndef NOSMP
#warning smp not supported on arm* (no membars), try compiling with -DNOSMP
#endif /* NOSMP */
#define membar_getlock()
#elif defined(__CPU_ppc) || defined(__CPU_ppc64)
#ifndef NOSMP
#define membar_getlock() \
asm volatile("lwsync \n\t" : : : "memory");
#else
#define membar_getlock()
#define membar_getlock()
#endif /* NOSMP */
#elif defined __CPU_mips2 || defined __CPU_mips64
@ -91,21 +99,21 @@ typedef volatile int fl_lock_t;
#define membar_getlock() \
asm volatile("sync \n\t" : : : "memory");
#else
#define membar_getlock()
#define membar_getlock()
#endif /* NOSMP */
#elif defined __CPU_mips
#ifndef NOSMP
#warning smp not supported on mips1 (no membars), try compiling with -DNOSMP
#endif
#define membar_getlock()
#define membar_getlock()
#elif defined __CPU_alpha
#ifndef NOSMP
#define membar_getlock() \
asm volatile("mb \n\t" : : : "memory");
#else
#define membar_getlock()
#define membar_getlock()
#endif /* NOSMP */
#else /* __CPU_xxx */
@ -116,7 +124,7 @@ typedef volatile int fl_lock_t;
/*test and set lock, ret !=0 if lock held by someone else, 0 otherwise
* WARNING: no memory barriers included, if you use this function directly
* (not recommended) and it gets the lock (ret==0), you should call
* (not recommended) and it gets the lock (ret==0), you should call
* membar_getlock() after it */
inline static int tsl(fl_lock_t* lock)
{
@ -176,21 +184,35 @@ inline static int tsl(fl_lock_t* lock)
, "cc"
#endif
);
#elif defined __CPU_arm
#elif defined __CPU_arm
asm volatile(
"swp %0, %2, [%3] \n\t"
: "=&r" (val), "=m"(*lock) : "r"(1), "r" (lock) : "memory"
);
#elif defined __CPU_arm6
asm volatile(
" ldrex %0, [%2] \n\t"
" ldrex %0, [%2] \n\t"
" cmp %0, #0 \n\t"
" strexeq %0, %3, [%2] \n\t" /* executed only if Z=1 */
/* if %0!=0 => either it was 1 initially or was 0
* and somebody changed it just before the strexeq (so the
* and somebody changed it just before the strexeq (so the
* lock is taken) => it's safe to return %0 */
: "=&r"(val), "=m"(*lock) : "r"(lock), "r"(1) : "cc"
);
#elif defined __CPU_aarch64
int res = 0;
int one = 1;
asm volatile(
"1: ldaxr %w0, %2 \n\t"
" stlxr %w1, %w3, %2 \n\t"
" cbnz %w1, 1b \n\t"
: "=&r" (val), "=&r" (res), "+Q"(*lock)
: "r"(one)
: "cc", "memory"
);
#elif defined(__CPU_ppc) || defined(__CPU_ppc64)
asm volatile(
"1: \n\t"
@ -211,7 +233,7 @@ inline static int tsl(fl_lock_t* lock)
#elif defined __CPU_mips2 || ( defined __CPU_mips && defined MIPS_HAS_LLSC ) \
|| defined __CPU_mips64
long tmp;
asm volatile(
".set push \n\t"
".set noreorder\n\t"
@ -230,8 +252,8 @@ inline static int tsl(fl_lock_t* lock)
"2: \n\t"
/* membar_getlock must be called outside this function */
".set pop\n\t"
: "=&r" (tmp), "=&r" (val), "=m" (*lock)
: "m" (*lock)
: "=&r" (tmp), "=&r" (val), "=m" (*lock)
: "m" (*lock)
: "memory"
);
#elif defined __CPU_alpha
@ -242,10 +264,10 @@ inline static int tsl(fl_lock_t* lock)
"1: ldl %0, %1 \n\t"
" blbs %0, 2f \n\t" /* optimization if locked */
" ldl_l %0, %1 \n\t"
" blbs %0, 2f \n\t"
" blbs %0, 2f \n\t"
" lda %2, 1 \n\t" /* or: or $31, 1, %2 ??? */
" stl_c %2, %1 \n\t"
" beq %2, 3f \n\t" /* back cond. jumps are always predicted to be
" beq %2, 3f \n\t" /* back cond. jumps are always predicted to be
taken => make forward jump */
/* membar_getlock must be called outside this function */
"2: \n\t"
@ -253,7 +275,7 @@ inline static int tsl(fl_lock_t* lock)
"3: br 1b \n\t"
".previous \n\t"
:"=&r" (val), "=m"(*lock), "=&r"(tmp)
:"m"(*lock)
:"m"(*lock)
: "memory"
);
#else
@ -269,7 +291,7 @@ inline static void get_lock(fl_lock_t* lock)
#ifdef ADAPTIVE_WAIT
int i=ADAPTIVE_WAIT_LOOPS;
#endif
while(tsl(lock)){
#ifdef BUSY_WAIT
#elif defined ADAPTIVE_WAIT
@ -299,12 +321,12 @@ inline static int try_lock(fl_lock_t* lock)
inline static void release_lock(fl_lock_t* lock)
{
#if defined(__CPU_i386)
#if defined(__CPU_i386)
#ifdef NOSMP
asm volatile(
" movb $0, %0 \n\t"
" movb $0, %0 \n\t"
: "=m"(*lock) : : "memory"
);
);
#else /* ! NOSMP */
int val;
/* a simple mov $0, (lock) does not force StoreStore ordering on all
@ -316,7 +338,7 @@ inline static void release_lock(fl_lock_t* lock)
#endif /* NOSMP */
#elif defined(__CPU_x86_64)
asm volatile(
" movb $0, %0 \n\t" /* on amd64 membar StoreStore | LoadStore is
" movb $0, %0 \n\t" /* on amd64 membar StoreStore | LoadStore is
implicit (at least on the same mem. type) */
: "=m"(*lock) : : "memory"
);
@ -337,9 +359,22 @@ inline static void release_lock(fl_lock_t* lock)
#warning arm* smp mode not supported (no membars), try compiling with -DNOSMP
#endif
asm volatile(
" str %1, [%2] \n\r"
" str %1, [%2] \n\r"
: "=m"(*lock) : "r"(0), "r"(lock) : "memory"
);
#elif defined __CPU_aarch64
#ifndef NOSMP
#warning arm* smp mode not supported (no membars), try compiling with -DNOSMP
#endif
asm volatile(
" stlr %w1, %0 \n\t"
: "=Q"(*lock)
: "r"(0)
: "memory"
);
#elif defined(__CPU_ppc) || defined(__CPU_ppc64)
asm volatile(
/* "sync\n\t" lwsync is faster and will work
@ -374,7 +409,7 @@ inline static void release_lock(fl_lock_t* lock)
#endif
" stl $31, %0 \n\t"
: "=m"(*lock) :/* no input*/ : "memory" /* because of the mb */
);
);
#else
#error "unknown architecture"
#endif

@ -25,6 +25,9 @@
#include "dprint.h"
#include "route.h"
static char _lval_empty_buf[2] = {0};
static str _lval_empty = { _lval_empty_buf, 0 };
/* callback to log assign actions */
static log_assign_action_f _log_assign_action = NULL;
@ -124,8 +127,7 @@ inline static int lval_avp_assign(struct run_act_ctx* h, struct sip_msg* msg,
flags=avp->type|AVP_VAL_STR;
v=run_select(&value.s, &rv->v.sel, msg);
if (unlikely(v!=0)){
value.s.s="";
value.s.len=0;
value.s = _lval_empty;
if (v<0){
ret=-1;
break;
@ -302,8 +304,7 @@ inline static int lval_pvar_assign(struct run_act_ctx* h, struct sip_msg* msg,
v=run_select(&pval.rs, &rv->v.sel, msg);
if (unlikely(v!=0)){
pval.flags|=PV_VAL_EMPTY;
pval.rs.s="";
pval.rs.len=0;
pval.rs = _lval_empty;
if (v<0){
ret=-1;
break;

@ -709,7 +709,7 @@ void handle_sigs(void)
LOG(memlog, "Memory status (pkg):\n");
pkg_status();
}
if (cfg_get(core, core_cfg, mem_summary) & 2) {
if (cfg_get(core, core_cfg, mem_summary) & 4) {
LOG(memlog, "Memory still-in-use summary (pkg):\n");
pkg_sums();
}
@ -717,11 +717,11 @@ void handle_sigs(void)
#endif
#ifdef SHM_MEM
if (memlog <= cfg_get(core, core_cfg, debug)){
if (cfg_get(core, core_cfg, mem_summary) & 1) {
if (cfg_get(core, core_cfg, mem_summary) & 2) {
LOG(memlog, "Memory status (shm):\n");
shm_status();
}
if (cfg_get(core, core_cfg, mem_summary) & 2) {
if (cfg_get(core, core_cfg, mem_summary) & 8) {
LOG(memlog, "Memory still-in-use summary (shm):\n");
shm_sums();
}
@ -821,7 +821,7 @@ void sig_usr(int signo)
LOG(memlog, "Memory status (pkg):\n");
pkg_status();
}
if (cfg_get(core, core_cfg, mem_summary) & 2) {
if (cfg_get(core, core_cfg, mem_summary) & 4) {
LOG(memlog, "Memory still-in-use summary (pkg):"
"\n");
pkg_sums();
@ -840,7 +840,7 @@ void sig_usr(int signo)
LOG(memlog, "Memory status (pkg):\n");
pkg_status();
}
if (cfg_get(core, core_cfg, mem_summary) & 2) {
if (cfg_get(core, core_cfg, mem_summary) & 4) {
LOG(memlog, "Memory still-in-use summary (pkg):\n");
pkg_sums();
}

@ -576,6 +576,14 @@ int fixup_spve_all(void** param, int param_no)
return fixup_spve_null(param, 1);
}
/**
*
*/
int fixup_free_spve_all(void** param, int param_no)
{
return fixup_free_spve_null(param, 1);
}
/**
*
*/
@ -607,3 +615,27 @@ int fixup_free_spve_igp(void** param, int param_no)
return fixup_free_igp_null(param, 1);
return E_UNSPEC;
}
/**
*
*/
int fixup_spve_pvar(void** param, int param_no)
{
if(param_no==1)
return fixup_spve_null(param, 1);
if(param_no==2)
return fixup_pvar_null(param, 1);
return E_UNSPEC;
}
/**
*
*/
int fixup_free_spve_pvar(void** param, int param_no)
{
if(param_no==1)
return fixup_free_spve_null(param, 1);
if(param_no==2)
return fixup_free_pvar_null(param, 1);
return E_UNSPEC;
}

@ -132,14 +132,18 @@ int fixup_free_spve_spve(void** param, int param_no);
int fixup_spve_null(void** param, int param_no);
int fixup_free_spve_null(void** param, int param_no);
int fixup_spve_uint(void** param, int param_no);
int fixup_free_spve_uint(void** param, int param_no);
int fixup_spve_str(void** param, int param_no);
int fixup_free_spve_str(void** param, int param_no);
int fixup_spve_all(void** param, int param_no);
int fixup_free_spve_all(void** param, int param_no);
int fixup_igp_all(void** param, int param_no);
int fixup_spve_igp(void** param, int param_no);
int fixup_free_spve_igp(void** param, int param_no);
int fixup_spve_pvar(void** param, int param_no);
int fixup_free_spve_pvar(void** param, int param_no);
/** get the corresp. free fixup function.*/
free_fixup_function mod_fix_get_fixup_free(fixup_function f);

@ -34,8 +34,6 @@ Sven Knoblich
Copyright © 2004, 2006 Voice Sistem SRL
Copyright © 2011 1&1 Internet AG
Revision History
Revision $Revision$ $Date$
__________________________________________________________________
Table of Contents
@ -892,11 +890,11 @@ modparam("acc", "log_missed_flag", 3)
Log level at which accounting messages are issued to syslog.
Default value is L_NOTICE.
Default value is 1 (L_NOTICE).
Example 1.12. log_level example
...
modparam("acc", "log_level", 2) # Set log_level to 2
modparam("acc", "log_level", 2) # Set log_level to 2 (L_INFO)
...
6.13. log_facility (string)
@ -1344,7 +1342,7 @@ modparam("acc", "cdrs_table", "acc_cdrs")
* 0 - (default), save only unix timestamp for syslog and datetime for
database.
* 1 - save seconds in time_attr and microseconds in time_exten.
* 2 - save seconds.miliseconds in time_attr.
* 2 - save seconds.milliseconds in time_attr.
* 3 - save formatted time according to time_format parameter, using
the output of localtime().
* 4 - save formatted time according to time_format parameter, using
@ -1385,7 +1383,7 @@ modparam("acc", "time_attr", "seconds")
Example 1.51. time_exten example
...
modparam("acc", "time_exten", "micorsecs")
modparam("acc", "time_exten", "microsecs")
...
6.52. time_format (str)

@ -78,7 +78,6 @@
#define ST_MSG_CODE 0x13010000
#define MASK_MSG_CODE 0xffffff00
#else
#error BIG endian detected!!
#define AS_MSG_CODE 0x00000112
#define AC_MSG_CODE 0x0000010f
#define CE_MSG_CODE 0x00000101

@ -58,12 +58,6 @@
<year>2011</year>
<holder>1&amp;1 Internet AG</holder>
</copyright>
<revhistory>
<revision>
<revnumber>$Revision$</revnumber>
<date>$Date$</date>
</revision>
</revhistory>
</bookinfo>
<toc></toc>

@ -730,13 +730,13 @@ modparam("acc", "log_missed_flag", 3)
Log level at which accounting messages are issued to syslog.
</para>
<para>
Default value is L_NOTICE.
Default value is 1 (L_NOTICE).
</para>
<example>
<title>log_level example</title>
<programlisting format="linespecific">
...
modparam("acc", "log_level", 2) # Set log_level to 2
modparam("acc", "log_level", 2) # Set log_level to 2 (L_INFO)
...
</programlisting>
</example>
@ -1421,7 +1421,7 @@ modparam("acc", "cdrs_table", "acc_cdrs")
microseconds in time_exten.</para>
</listitem>
<listitem>
<para><emphasis>2</emphasis> - save seconds.miliseconds
<para><emphasis>2</emphasis> - save seconds.milliseconds
in time_attr.</para>
</listitem>
<listitem>
@ -1496,7 +1496,7 @@ modparam("acc", "time_attr", "seconds")
<title>time_exten example</title>
<programlisting format="linespecific">
...
modparam("acc", "time_exten", "micorsecs")
modparam("acc", "time_exten", "microsecs")
...
</programlisting>
</example>

@ -402,7 +402,7 @@ char *pv_sprintf(struct sip_msg *m, char *fmt) {
* - strflag: flag mask to be or-applied for string match
*/
inline int sv2int_str(SV *val, int_str *is,
static inline int sv2int_str(SV *val, int_str *is,
unsigned short *flags, unsigned short strflag) {
char *s;
STRLEN len;

@ -231,8 +231,8 @@ static int mod_init(void) {
}
if( !( fs.st_mode & S_IWOTH) &&
!((fs.st_mode & S_IWGRP) && (fs.st_gid == uid)) &&
!((fs.st_mode & S_IWUSR) && (fs.st_uid == gid))) {
!((fs.st_mode & S_IWGRP) && (fs.st_gid == gid)) &&
!((fs.st_mode & S_IWUSR) && (fs.st_uid == uid))) {
LM_ERR("config file %s not writable\n", config_file);
return -1;
}

@ -116,7 +116,6 @@
#define ST_MSG_CODE 0x13010000
#define MASK_MSG_CODE 0xffffff00
#else
#error BIG endian detected!!
#define AS_MSG_CODE 0x00000112
#define AC_MSG_CODE 0x0000010f
#define CE_MSG_CODE 0x00000101

@ -311,10 +311,12 @@ void db_cluster_close(db1_con_t* _h)
LM_DBG("executing db cluster close command\n");
cls = (dbcl_cls_t*)_h->tail;
cls->ref--;
if(cls->ref > 0)
return;
/* close connections */
dbcl_close_connections(cls);
if(cls->ref <= 0) {
/* close connections */
dbcl_close_connections(cls);
}
/* free _h - allocated for each db_cluster_init() */
pkg_free(_h);
return;
}

@ -442,7 +442,8 @@ int dbcl_init_connections(dbcl_cls_t *cls)
{
for(j=0; j<cls->rlist[i].clen; j++)
{
if(cls->rlist[i].clist[j] != NULL && cls->rlist[i].clist[j]->flags!=0)
if(cls->rlist[i].clist[j] != NULL && cls->rlist[i].clist[j]->flags!=0
&& cls->rlist[i].clist[j]->dbh==NULL)
{
LM_DBG("setting up read connection [%.*s]\n",
cls->rlist[i].clist[j]->name.len,
@ -459,7 +460,8 @@ int dbcl_init_connections(dbcl_cls_t *cls)
}
for(j=0; j<cls->wlist[i].clen; j++)
{
if(cls->wlist[i].clist[j] != NULL && cls->wlist[i].clist[j]->flags!=0)
if(cls->wlist[i].clist[j] != NULL && cls->wlist[i].clist[j]->flags!=0
&& cls->wlist[i].clist[j]->dbh==NULL)
{
LM_DBG("setting up write connection [%.*s]\n",
cls->wlist[i].clist[j]->name.len,

@ -522,9 +522,15 @@ static int db_mongodb_convert_bson(const db1_con_t* _h, db1_res_t* _r,
LM_DBG("looking for field[%d] named: %s\n", col, colname);
if(mgres->colsdoc) {
if(!bson_iter_find(&riter, colname)) {
LM_ERR("field [%s] not found in result iterator\n",
if (!bson_iter_init (&riter, _rdoc)) {
LM_ERR("failed to initialize result iterator\n");
return -3;
}
if(!bson_iter_find(&riter, colname)) {
LM_ERR("field [%s] not found in result iterator\n",
colname);
return -4;
return -4;
}
}
piter = &riter;
} else {

@ -1397,10 +1397,9 @@ redlg_setflag("1");
Meaning of the parameters is as follows:
* side - where to send the BYE. It can be: 'caller', 'callee', or
both.
'all' (send to both sides).
This function can be used from BRANCH_ROUTE, REQUEST_ROUTE,
ONREPLY_ROUTE and FAILURE_ROUTE.
This function can be used from ANY_ROUTE.
Example 1.61. dlg_bye usage
...

@ -1142,8 +1142,16 @@ static int w_dlg_set_timeout(struct sip_msg *msg, char *pto, char *phe, char *ph
LM_ERR("no timeout value\n");
return -1;
}
if(to<=0) {
LM_ERR("invalid timeout value: %d\n", to);
return -1;
}
if(phe!=NULL)
{
if(phi==NULL) {
LM_ERR("invalid number of parameters\n");
return -1;
}
if(fixup_get_ivalue(msg, (gparam_p)phe, (int*)&he)!=0)
{
LM_ERR("no hash entry value value\n");
@ -1165,7 +1173,7 @@ static int w_dlg_set_timeout(struct sip_msg *msg, char *pto, char *phe, char *ph
return -1;
}
if(update_dlg_timeout(dlg, to) != 0)
if(update_dlg_timeout(dlg, to) != 0)
return -1;
return 1;
@ -1676,8 +1684,8 @@ static void internal_rpc_profile_print_dlgs(rpc_t *rpc, void *c, str *profile_na
ph=ph->next;
}while(ph!=profile->entries[i].first);
}
lock_release(&profile->lock);
}
lock_release(&profile->lock);
}
/*

@ -455,7 +455,11 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
event = DLG_EVENT_RPL3xx;
next_state_dlg( dlg, event, &old_state, &new_state, &unref);
dlg_run_event_route(dlg, (rpl==FAKED_REPLY)?NULL:rpl, old_state, new_state);
if(dlg_run_event_route(dlg, (rpl==FAKED_REPLY)?NULL:rpl, old_state,
new_state)<0) {
/* dialog is gone */
return;
}
if (new_state==DLG_STATE_EARLY) {
run_dlg_callbacks(DLGCB_EARLY, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
@ -1311,7 +1315,10 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
CURR_DLG_LIFETIME = (unsigned int)(time(0))-dlg->start_ts;
CURR_DLG_STATUS = new_state;
dlg_run_event_route(dlg, req, old_state, new_state);
if(dlg_run_event_route(dlg, req, old_state, new_state)<0) {
/* dialog is gone */
return;
}
/* delay deletion of dialog until transaction has died off in order
* to absorb in-air messages */
@ -1506,7 +1513,10 @@ void dlg_ontimeout(struct dlg_tl *tl)
timeout_cb = (void *)CONFIRMED_DIALOG_STATE;
}
dlg_run_event_route(dlg, NULL, old_state, new_state);
if(dlg_run_event_route(dlg, NULL, old_state, new_state)<0) {
/* dialog is gone */
return;
}
if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
LM_WARN("timeout for dlg with CallID '%.*s' and tags '%.*s' '%.*s'\n",
@ -1594,17 +1604,22 @@ int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
/*!
* \brief Execute event routes based on new state
*
* - returns: -1 if dialog doesn't exist after event route execution
* 0 if all ok
*/
void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate)
int dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate)
{
sip_msg_t *fmsg;
int rt;
int bkroute;
int h_entry=0;
int h_id=0;
dlg_cell_t *dlg0 = NULL;
if(dlg==NULL)
return;
return -1;
if(ostate==nstate)
return;
return 0;
rt = -1;
if(nstate==DLG_STATE_CONFIRMED_NA) {
@ -1617,7 +1632,7 @@ void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate
}
if(rt==-1 || event_rt.rlist[rt]==NULL)
return;
return 0;
if(msg==NULL)
fmsg = faked_msg_next();
@ -1627,6 +1642,8 @@ void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate
if (exec_pre_script_cb(fmsg, LOCAL_CB_TYPE)>0)
{
dlg_ref(dlg, 1);
h_entry = dlg->h_entry;
h_id = dlg->h_id;
dlg_set_ctx_iuid(dlg);
LM_DBG("executing event_route %d on state %d\n", rt, nstate);
bkroute = get_route_type();
@ -1634,9 +1651,19 @@ void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate
run_top_route(event_rt.rlist[rt], fmsg, 0);
dlg_reset_ctx_iuid();
exec_post_script_cb(fmsg, LOCAL_CB_TYPE);
dlg_unref(dlg, 1);
set_route_type(bkroute);
/* re-lookup the dialog, execution of the route could take long time */
dlg0 = dlg_lookup(h_entry, h_id);
if (dlg0==0) {
LM_ALERT("after event route - dialog not found [%u:%u] (%d/%d) (%p)\n",
h_entry, h_id, ostate, nstate, dlg);
return -1;
} else {
dlg_release(dlg0);
dlg_unref(dlg, 1);
}
}
return 0;
}
int dlg_manage(sip_msg_t *msg)

@ -582,7 +582,7 @@ static inline int match_downstream_dialog(dlg_cell_t *dlg, str *callid, str *fta
/*!
*
*/
void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate);
int dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate);
int dlg_ka_add(dlg_cell_t *dlg);

@ -437,6 +437,10 @@ int profile_cleanup( struct sip_msg *msg, unsigned int flags, void *param )
{
dlg_cell_t *dlg;
if(get_route_type()==LOCAL_ROUTE) {
return 1;
}
current_dlg_msg_id = 0;
current_dlg_msg_pid = 0;
dlg = dlg_get_ctx_dialog();

@ -47,6 +47,9 @@ int msg_id;
int dlg_cfg_cb(sip_msg_t *msg, unsigned int flags, void *cbp)
{
dlg_cell_t *dlg;
if(get_route_type()==LOCAL_ROUTE) {
return 1;
}
if(flags&POST_SCRIPT_CB) {
dlg = dlg_get_ctx_dialog();
if(dlg!=NULL) {
@ -76,6 +79,9 @@ int dlg_cfg_cb(sip_msg_t *msg, unsigned int flags, void *cbp)
int cb_dlg_cfg_reset(sip_msg_t *msg, unsigned int flags, void *cbp)
{
if(get_route_type()==LOCAL_ROUTE) {
return 1;
}
memset(&_dlg_ctx, 0, sizeof(dlg_ctx_t));
return 1;
@ -83,6 +89,9 @@ int cb_dlg_cfg_reset(sip_msg_t *msg, unsigned int flags, void *cbp)
int cb_dlg_locals_reset(sip_msg_t *msg, unsigned int flags, void *cbp)
{
if(get_route_type()==LOCAL_ROUTE) {
return 1;
}
LM_DBG("resetting the local dialog shortcuts on script callback: %u\n", flags);
cb_dlg_cfg_reset(msg, flags, cbp);
cb_profile_reset(msg, flags, cbp);
@ -918,6 +927,9 @@ dlg_ctx_t* dlg_get_dlg_ctx(void)
int spiral_detect_reset(struct sip_msg *foo, unsigned int flags, void *bar)
{
if(get_route_type()==LOCAL_ROUTE) {
return 1;
}
spiral_detected = -1;
return 0;

@ -1663,13 +1663,12 @@ redlg_setflag("1");
<itemizedlist>
<listitem>
<para><emphasis>side</emphasis> - where to send the BYE. It can be:
'caller', 'callee', or both.
'caller', 'callee', or 'all' (send to both sides).
</para>
</listitem>
</itemizedlist>
<para>
This function can be used from BRANCH_ROUTE,
REQUEST_ROUTE, ONREPLY_ROUTE and FAILURE_ROUTE.
This function can be used from ANY_ROUTE.
</para>
<example>
<title><function>dlg_bye</function> usage</title>

@ -328,7 +328,7 @@ Chapter 1. Admin Guide
3.1. list_file (string)
Path to the file with destination sets.
Path to the file with destination sets (destination groups).
Default value is “/etc/kamailio/dispatcher.list” or
“/usr/local/etc/kamailio/dispatcher.list”.
@ -340,7 +340,7 @@ modparam("dispatcher", "list_file", "/var/run/kamailio/dispatcher.list")
3.2. db_url (string)
If you want to load the sets of gateways from the database you must set
If you want to load the list of gateways from the database you must set
this parameter.
Default value is “NULL” (disable DB support).
@ -352,7 +352,7 @@ modparam("dispatcher", "db_url", "mysql://user:passwb@localhost/database")
3.3. table_name (string)
If you want to load the sets of gateways from the database you must set
If you want to load the list of gateways from the database you must set
this parameter as the database name.
Default value is “dispatcher”.
@ -364,7 +364,7 @@ modparam("dispatcher", "table_name", "my_dispatcher")
3.4. setid_col (string)
The column's name in the database storing the gateway's group id.
The column's name in the database storing the gateway's set (group) id.
Default value is “setid”.
@ -1226,8 +1226,8 @@ kamcmd dispatcher.ping_active 0
7.1. Destination List File
Each destination point must be on one line. First token is the set id
(an integer value), followed by destination address (s string value in
SIP URI format).
(an integer value, also referenced by group id), followed by
destination address (string value in full SIP URI format).
Optionally, these fields can be followed by:
* flags (listed by index - can be bitwise mask of values): 0 (value
@ -1278,21 +1278,21 @@ setid(int) destination(sip uri) flags(int,opt) priority(int,opt) attrs(str,opt)
Example 1.40. dispatcher list file
...
# $Id$
# dispatcher destination sets
#
# dispatcher destination sets (groups)
#
# line format
# setit(int) destination(sip uri) flags(int,opt) priority(int,opt) attributes(st
# setid(int) destination(sip uri) flags(int,opt) priority(int,opt) attributes(st
r,opt)
# proxies
2 sip:127.0.0.1:5080
2 sip:127.0.0.1:5082
2 sip:127.0.0.1:5080;transport=tcp 0 10 class=4;prefix=448;strip=2
2 sip:127.0.0.1:5082;px=vx 0 5 duid=abc;socket=udp:192.168.0.125:5060;pipe=p10
# gateways
1 sip:127.0.0.1:7070
1 sip:127.0.0.1:7072
1 sip:127.0.0.1:7070 0 0 duid=xyz;maxload=20
1 sip:127.0.0.1:7072 0 5
1 sip:127.0.0.1:7074
...

@ -1,15 +1,15 @@
# $Id$
# dispatcher destination sets
#
# dispatcher destination sets (groups)
#
# line format
# setit(int) destination(sip uri) flags(int,opt) priority(int,opt) attributes(str,opt)
# setid(int) destination(sip uri) flags(int,opt) priority(int,opt) attributes(str,opt)
# proxies
2 sip:127.0.0.1:5080
2 sip:127.0.0.1:5082
2 sip:127.0.0.1:5080;transport=tcp 0 10 class=4;prefix=448;strip=2
2 sip:127.0.0.1:5082;px=vx 0 5 duid=abc;socket=udp:192.168.0.125:5060;pipe=p10
# gateways
1 sip:127.0.0.1:7070
1 sip:127.0.0.1:7072
1 sip:127.0.0.1:7070 0 0 duid=xyz;maxload=20
1 sip:127.0.0.1:7072 0 5
1 sip:127.0.0.1:7074

@ -77,7 +77,7 @@
<section id="dispatcher.p.list_file">
<title><varname>list_file</varname> (string)</title>
<para>
Path to the file with destination sets.
Path to the file with destination sets (destination groups).
</para>
<para>
<emphasis>
@ -98,7 +98,7 @@ modparam("dispatcher", "list_file", "/var/run/kamailio/dispatcher.list")
<section id="dispatcher.p.db_url">
<title><varname>db_url</varname> (string)</title>
<para>
If you want to load the sets of gateways from the database you must set
If you want to load the list of gateways from the database you must set
this parameter.
</para>
<para>
@ -119,7 +119,7 @@ modparam("dispatcher", "db_url", "mysql://user:passwb@localhost/database")
<section id="dispatcher.p.table_name">
<title><varname>table_name</varname> (string)</title>
<para>
If you want to load the sets of gateways from the database you must set
If you want to load the list of gateways from the database you must set
this parameter as the database name.
</para>
<para>
@ -140,7 +140,8 @@ modparam("dispatcher", "table_name", "my_dispatcher")
<section id="dispatcher.p.setid_col">
<title><varname>setid_col</varname> (string)</title>
<para>
The column's name in the database storing the gateway's group id.
The column's name in the database storing the gateway's set (group)
id.
</para>
<para>
<emphasis>
@ -1517,8 +1518,8 @@ onreply_route {
<title>Destination List File</title>
<para>
Each destination point must be on one line. First token is the set
id (an integer value), followed by destination address
(s string value in SIP URI format).
id (an integer value, also referenced by group id), followed by
destination address (string value in full SIP URI format).
</para>
<para>
Optionally, these fields can be followed by:

@ -50,9 +50,9 @@ extern int _dmq_usrloc_batch_usleep;
static int add_contact(str aor, ucontact_info_t* ci)
{
urecord_t* r;
urecord_t* r = NULL;
udomain_t* _d;
ucontact_t* c;
ucontact_t* c = NULL;
str contact;
int res;
@ -61,37 +61,53 @@ static int add_contact(str aor, ucontact_info_t* ci)
return -1;
}
dmq_ul.lock_udomain(_d, &aor);
LM_DBG("aor: %.*s\n", aor.len, aor.s);
LM_DBG("ci->ruid: %.*s\n", ci->ruid.len, ci->ruid.s);
LM_DBG("aorhash: %i\n", dmq_ul.get_aorhash(&aor));
res = dmq_ul.get_urecord(_d, &aor, &r);
if (res < 0) {
LM_ERR("failed to retrieve record from usrloc\n");
goto error;
} else if ( res == 0) {
LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s));
res = dmq_ul.get_ucontact(r, ci->c, ci->callid, ci->path, ci->cseq, &c);
LM_DBG("get_ucontact = %d\n", res);
if (res==-1) {
LM_ERR("Invalid cseq\n");
if (ci->ruid.len > 0) {
// Search by ruid, if possible
res = dmq_ul.get_urecord_by_ruid(_d, dmq_ul.get_aorhash(&aor), &ci->ruid, &r, &c);
if (res == 0) {
LM_DBG("Found contact\n");
dmq_ul.update_ucontact(r, c, ci);
LM_DBG("Release record\n");
dmq_ul.release_urecord(r);
LM_DBG("Unlock udomain\n");
dmq_ul.unlock_udomain(_d, &aor);
return 0;
}
}
dmq_ul.lock_udomain(_d, &aor);
res = dmq_ul.get_urecord(_d, &aor, &r);
if (res < 0) {
LM_ERR("failed to retrieve record from usrloc\n");
goto error;
} else if (res > 0 ) {
LM_DBG("Not found contact\n");
} else if ( res == 0) {
LM_DBG("'%.*s' found in usrloc\n", aor.len, ZSW(aor.s));
res = dmq_ul.get_ucontact(r, ci->c, ci->callid, ci->path, ci->cseq, &c);
LM_DBG("get_ucontact = %d\n", res);
if (res==-1) {
LM_ERR("Invalid cseq\n");
goto error;
} else if (res > 0 ) {
LM_DBG("Not found contact\n");
contact.s = ci->c->s;
contact.len = ci->c->len;
dmq_ul.insert_ucontact(r, &contact, ci, &c);
} else if (res == 0) {
LM_DBG("Found contact\n");
dmq_ul.update_ucontact(r, c, ci);
}
} else {
LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
dmq_ul.insert_urecord(_d, &aor, &r);
LM_DBG("Insert record\n");
contact.s = ci->c->s;
contact.len = ci->c->len;
dmq_ul.insert_ucontact(r, &contact, ci, &c);
} else if (res == 0) {
LM_DBG("Found contact\n");
dmq_ul.update_ucontact(r, c, ci);
LM_DBG("Insert ucontact\n");
}
} else {
LM_DBG("'%.*s' Not found in usrloc\n", aor.len, ZSW(aor.s));
dmq_ul.insert_urecord(_d, &aor, &r);
LM_DBG("Insert record\n");
contact.s = ci->c->s;
contact.len = ci->c->len;
dmq_ul.insert_ucontact(r, &contact, ci, &c);
LM_DBG("Insert ucontact\n");
}
LM_DBG("Release record\n");
dmq_ul.release_urecord(r);

@ -154,7 +154,7 @@ get_prefix(
goto err_exit;
/* is it a real node or an intermediate one */
idx = get_node_index(*tmp);
if(NULL != ptree->ptnode[idx].rg) {
if(idx!=-1 && NULL != ptree->ptnode[idx].rg) {
/* real node; check the constraints on the routing info*/
if( NULL != (rt = internal_check_rt( &(ptree->ptnode[idx]), rgid)))
break;
@ -169,7 +169,7 @@ err_exit:
}
pgw_t*
pgw_t*
get_pgw(
pgw_t* pgw_l,
long id

@ -204,6 +204,7 @@ int ht_db_load_table(ht_t *ht, str *dbtable, int mode)
return -1;
}
if(ht->ncols>0) {
db_ord = &ht->scols[0];
for(c=0; c<ht->ncols; c++) {
db_cols[c] = &ht->scols[c];
}
@ -238,6 +239,7 @@ int ht_db_load_table(ht_t *ht, str *dbtable, int mode)
} else {
if(RES_ROW_N(db_res)==0)
{
ht_dbf.free_result(ht_db_con, db_res);
LM_DBG("Nothing to be loaded in hash table\n");
return 0;
}

@ -48,17 +48,17 @@ int pv_get_ht_cell(struct sip_msg *msg, pv_param_t *param,
return -1;
}
htc = ht_cell_pkg_copy(hpv->ht, &htname, _htc_local);
if(_htc_local!=htc)
{
ht_cell_pkg_free(_htc_local);
_htc_local=htc;
}
if(htc==NULL)
{
if(hpv->ht->flags==PV_VAL_INT)
return pv_get_sintval(msg, param, res, hpv->ht->initval.n);
return pv_get_null(msg, param, res);
}
if(_htc_local!=htc)
{
ht_cell_pkg_free(_htc_local);
_htc_local=htc;
}
if(htc->flags&AVP_VAL_STR)
return pv_get_strval(msg, param, res, &htc->value.s);
@ -326,15 +326,15 @@ int pv_get_ht_add(struct sip_msg *msg, pv_param_t *param,
return -1;
}
htc = ht_cell_value_add(hpv->ht, &htname, val, 1, _htc_local);
if(htc==NULL)
{
return pv_get_null(msg, param, res);
}
if(_htc_local!=htc)
{
ht_cell_pkg_free(_htc_local);
_htc_local=htc;
}
if(htc==NULL)
{
return pv_get_null(msg, param, res);
}
if(htc->flags&AVP_VAL_STR)
return pv_get_null(msg, param, res);

@ -1168,12 +1168,14 @@ static void htable_rpc_reload(rpc_t* rpc, void* c)
if (rpc->scan(c, "S", &htname) < 1)
{
ht_db_close_con();
rpc->fault(c, 500, "No htable name given");
return;
}
ht = ht_get_table(&htname);
if(ht==NULL)
{
ht_db_close_con();
rpc->fault(c, 500, "No such htable");
return;
}

@ -45,7 +45,7 @@
#include "../../dprint.h"
#include "../../ut.h"
#include "../../cfg/cfg_struct.h"
#include "../../lib/kcore/faked_msg.h"
#include "../../fmsg.h"
#include "../../modules/tm/tm_load.h"
#include "async_http.h"
@ -122,6 +122,7 @@ void async_http_cb(struct http_m_reply *reply, void *param)
unsigned int tlabel;
struct cell *t = NULL;
char *p;
str newbuf = {0, 0};
sip_msg_t *fmsg;
if (reply->result != NULL) {
@ -140,7 +141,6 @@ void async_http_cb(struct http_m_reply *reply, void *param)
ah_error.len = strlen(ah_error.s);
} else {
/* success */
/* check for HTTP Via header
* - HTTP Via format is different that SIP Via
* - workaround: replace with Hia to be ignored by SIP parser
@ -158,7 +158,28 @@ void async_http_cb(struct http_m_reply *reply, void *param)
if (parse_msg(reply->result->s, reply->result->len, ah_reply) != 0) {
LM_DBG("failed to parse the http_reply\n");
} else {
LM_DBG("successfully parsed http reply %p\n", ah_reply);
if (ah_reply->first_line.u.reply.statuscode == 100) {
newbuf.s = get_body( ah_reply );
newbuf.len = reply->result->s + reply->result->len - newbuf.s;
if (!(newbuf.len < 0)) {
memset(ah_reply, 0, sizeof(struct sip_msg));
ah_reply->buf = newbuf.s;
ah_reply->len = newbuf.len;
if (parse_msg(ah_reply->buf, ah_reply->len, ah_reply) != 0) {
LM_DBG("failed to parse the http_reply\n");
} else {
LM_DBG("successfully parsed http reply %p\n", ah_reply);
}
} else {
/* this should not happen! */
LM_WARN("something got wrong parsing the 100 Continue: got %d len\n", newbuf.len);
}
} else {
LM_DBG("successfully parsed http reply %p\n", ah_reply);
}
}
}

@ -316,6 +316,8 @@ void reply_error(struct http_m_cell *cell)
cell->cb(reply, cell->param);
pkg_free(reply);
return;
}

@ -1,7 +1,3 @@
/*
* Warning: This file is auto generated from a ragel syntax (ip_parser.rl),
* do not change it!
*/
#line 1 "ip_parser.rl"
#include "ip_parser.h"
@ -16,11 +12,6 @@
#line 14 "ip_parser.c"
static const int ip_parser_start = 1;
static const int ip_parser_first_final = 237;
static const int ip_parser_error = 0;
static const int ip_parser_en_main = 1;
#line 45 "ip_parser.rl"

@ -13,11 +13,6 @@
#line 15 "rfc1918_parser.c"
static const int rfc1918_parser_start = 1;
static const int rfc1918_parser_first_final = 28;
static const int rfc1918_parser_error = 0;
static const int rfc1918_parser_en_main = 1;
#line 26 "rfc1918_parser.rl"

@ -142,14 +142,14 @@ int janssonmod_set(unsigned int append, struct sip_msg* msg, char* type_in,
if(STR_EQ_STATIC(type_s, "object") || STR_EQ_STATIC(type_s, "obj")){
value = json_loads(value_s.s, JSON_REJECT_DUPLICATES, &parsing_error);
if(value && !json_is_object(value)) {
ERR("value to add is not an object\n");
ERR("value to add is not an object - \"%s\"\n", path_s.s);
goto fail;
}
}else if(STR_EQ_STATIC(type_s, "array")) {
value = json_loads(value_s.s, JSON_REJECT_DUPLICATES, &parsing_error);
if(value && !json_is_array(value)) {
ERR("value to add is not an array\n");
ERR("value to add is not an array - \"%s\"\n", path_s.s);
goto fail;
}
@ -157,7 +157,7 @@ int janssonmod_set(unsigned int append, struct sip_msg* msg, char* type_in,
|| STR_EQ_STATIC(type_s, "str")) {
value = json_string(value_s.s);
if(!value || !json_is_string(value)) {
ERR("value to add is not a string\n");
ERR("value to add is not a string - \"%s\"\n", path_s.s);
goto fail;
}
@ -165,24 +165,24 @@ int janssonmod_set(unsigned int append, struct sip_msg* msg, char* type_in,
|| STR_EQ_STATIC(type_s, "int")) {
long long i = strtoll(value_s.s, &endptr, 10);
if(*endptr != '\0') {
ERR("parsing int failed for \"%s\"\n", value_s.s);
ERR("parsing int failed for \"%s\" - \"%s\"\n", path_s.s, value_s.s);
goto fail;
}
value = json_integer(i);
if(!value || !json_is_integer(value)) {
ERR("value to add is not an integer\n");
ERR("value to add is not an integer \"%s\"\n", path_s.s);
goto fail;
}
}else if(STR_EQ_STATIC(type_s, "real")) {
double d = strtod(value_s.s, &endptr);
if(*endptr != '\0') {
ERR("parsing real failed for \"%s\"\n", value_s.s);
ERR("parsing real failed for \"%s\" - \"%s\"\n", path_s.s, value_s.s);
goto fail;
}
value = json_real(d);
if(!value || !json_is_real(value)) {
ERR("value to add is not a real\n");
ERR("value to add is not a real \"%s\"\n", path_s.s);
goto fail;
}

@ -18,9 +18,9 @@
#include "../../mod_fix.h"
/* jansson private helper functions */
void *jsonp_malloc(size_t size);
void jsonp_free(void *ptr);
char *jsonp_strdup(const char *str);
static void *jsonp_malloc(size_t size);
static void jsonp_free(void *ptr);
static char *jsonp_strdup(const char *str);
static json_malloc_t do_malloc = malloc;
static json_free_t do_free = free;
@ -252,21 +252,21 @@ fail:
}
/* jansson private helper functions */
void *jsonp_malloc(size_t size) {
static void *jsonp_malloc(size_t size) {
if(!size)
return NULL;
return (*do_malloc)(size);
}
void jsonp_free(void *ptr) {
static void jsonp_free(void *ptr) {
if(!ptr)
return;
(*do_free)(ptr);
}
char *jsonp_strdup(const char *str) {
static char *jsonp_strdup(const char *str) {
char *new_str;
new_str = jsonp_malloc(strlen(str) + 1);

@ -9,6 +9,14 @@
#define DBK_DEFS_H_
#define BLF_MAX_DIALOGS 8
#define BLF_JSON_AMQP_RECEIVED "AMQP-Received"
#define BLF_JSON_AMQP_CONSUMER "AMQP-Consumer"
#define BLF_JSON_AMQP_PUBLISHED "AMQP-Published"
#define BLF_JSON_AMQP_SENT "AMQP-Sent"
#define BLF_JSON_AMQP_PIPE_IN "AMQP-Pipe-In"
#define BLF_JSON_AMQP_PIPE_OUT "AMQP-Pipe-Out"
#define BLF_JSON_PRES "Presentity"
#define BLF_JSON_PRES_USER "Presentity-User"
#define BLF_JSON_PRES_REALM "Presentity-Realm"
@ -21,6 +29,10 @@
#define BLF_JSON_TO_REALM "To-Realm"
#define BLF_JSON_TO_URI "To-URI"
#define BLF_JSON_CALLID "Call-ID"
#define BLF_JSON_DIALOGID "Dialog-ID"
#define BLF_JSON_SENDER "Sender-URI"
#define BLF_JSON_SWITCH_URI "Switch-URI"
#define BLF_JSON_ETAG "ETag"
#define BLF_JSON_TOTAG "To-Tag"
#define BLF_JSON_FROMTAG "From-Tag"
#define BLF_JSON_STATE "State"
@ -36,6 +48,7 @@
#define BLF_JSON_TYPE "Type"
#define BLF_JSON_MSG_ID "Msg-ID"
#define BLF_JSON_DIRECTION "Direction"
#define BLF_JSON_BROKER_ZONE "AMQP-Broker-Zone"
#define BLF_JSON_CONTACT "Contact"
#define BLF_JSON_EVENT_PKG "Event-Package"

@ -44,6 +44,8 @@
#define DBK_DEFAULT_NO_CONSUMERS 1
#define DBK_DEFAULT_NO_WORKERS 8
#define AMQP_WORKERS_RANKING PROC_SIPRPC
static int mod_init(void);
static int mod_child_init(int rank);
static int fire_init_event(int rank);
@ -64,9 +66,6 @@ int dbk_use_federated_exchange = 0;
str dbk_federated_exchange = str_init("federation");
str dbk_primary_zone_name = str_init("local");
//int dbk_dialog_expires = 30;
//int dbk_presence_expires = 3600;
//int dbk_mwi_expires = 3600;
int dbk_create_empty_dialog = 1;
int dbk_channels = 50;
@ -92,6 +91,7 @@ int dbk_consumer_loop_count = 10;
int dbk_consumer_ack_loop_count = 20;
int dbk_include_entity = 1;
int dbk_pua_mode = 1;
db_locking_t kz_pua_lock_type = DB_LOCKING_WRITE;
int dbk_use_hearbeats = 0;
int dbk_single_consumer_on_reconnect = 1;
int dbk_consume_messages_on_reconnect = 1;
@ -144,18 +144,10 @@ static cmd_export_t cmds[] = {
{"kazoo_query", (cmd_function) kz_amqp_query, 4, fixup_kz_amqp, fixup_kz_amqp_free, ANY_ROUTE},
{"kazoo_query", (cmd_function) kz_amqp_query_ex, 3, fixup_kz_amqp, fixup_kz_amqp_free, ANY_ROUTE},
{"kazoo_pua_publish", (cmd_function) kz_pua_publish, 1, 0, 0, ANY_ROUTE},
/*
{"kazoo_pua_flush", (cmd_function) w_mi_dbk_presentity_flush0, 0, 0, 0, ANY_ROUTE},
{"kazoo_pua_flush", (cmd_function) w_mi_dbk_presentity_flush1, 1, 0, 0, ANY_ROUTE},
{"kazoo_pua_flush", (cmd_function) w_mi_dbk_presentity_flush2, 2, 0, 0, ANY_ROUTE},
{"kazoo_pua_flush", (cmd_function) w_mi_dbk_presentity_flush3, 3, 0, 0, ANY_ROUTE},
*/
{"kazoo_pua_publish_mwi", (cmd_function) kz_pua_publish_mwi, 1, 0, 0, ANY_ROUTE},
{"kazoo_pua_publish_presence", (cmd_function) kz_pua_publish_presence, 1, 0, 0, ANY_ROUTE},
{"kazoo_pua_publish_dialoginfo", (cmd_function) kz_pua_publish_dialoginfo, 1, 0, 0, ANY_ROUTE},
/*
{"kazoo_subscribe", (cmd_function) kz_amqp_subscribe_1, 1, fixup_kz_amqp4, fixup_kz_amqp4_free, ANY_ROUTE},
{"kazoo_subscribe", (cmd_function) kz_amqp_subscribe_2, 2, fixup_kz_amqp4, fixup_kz_amqp4_free, ANY_ROUTE},
{"kazoo_subscribe", (cmd_function) kz_amqp_subscribe_3, 3, fixup_kz_amqp4, fixup_kz_amqp4_free, ANY_ROUTE},
*/
{"kazoo_subscribe", (cmd_function) kz_amqp_subscribe, 1, fixup_kz_amqp4, fixup_kz_amqp4_free, ANY_ROUTE},
{"kazoo_subscribe", (cmd_function) kz_amqp_subscribe_simple, 4, fixup_kz_amqp4, fixup_kz_amqp4_free, ANY_ROUTE},
@ -171,9 +163,6 @@ static cmd_export_t cmds[] = {
static param_export_t params[] = {
{"node_hostname", STR_PARAM, &dbk_node_hostname.s},
// {"dialog_expires", INT_PARAM, &dbk_dialog_expires},
// {"presence_expires", INT_PARAM, &dbk_presence_expires},
// {"mwi_expires", INT_PARAM, &dbk_mwi_expires},
{"amqp_connection", STR_PARAM|USE_FUNC_PARAM,(void*)kz_amqp_add_connection},
{"amqp_max_channels", INT_PARAM, &dbk_channels},
{"amqp_timmer_process_interval", INT_PARAM, &kz_timer_ms},
@ -212,6 +201,7 @@ static param_export_t params[] = {
{"amqps_key", STR_PARAM, &kz_amqps_key.s},
{"amqps_verify_peer", INT_PARAM, &kz_amqps_verify_peer},
{"amqps_verify_hostname", INT_PARAM, &kz_amqps_verify_hostname},
{"pua_lock_type", INT_PARAM, &kz_pua_lock_type},
{0, 0, 0}
};
@ -369,32 +359,21 @@ static int mod_child_init(int rank)
kz_amqp_zone_ptr g;
kz_amqp_server_ptr s;
fire_init_event(rank);
if (rank==PROC_INIT)
fire_init_event(rank);
if (rank==PROC_INIT || rank==PROC_TCP_MAIN)
return 0;
// if (rank>PROC_MAIN)
// kz_cmd_pipe = kz_cmd_pipe_fds[1];
if (rank==PROC_MAIN) {
/*
pid=fork_process(PROC_NOCHLDINIT, "AMQP Timer", 0);
if (pid<0)
return -1;
if(pid==0){
return(kz_amqp_timeout_proc());
}
*/
for(i=0; i < dbk_consumer_workers; i++) {
pid=fork_process(i+1, "AMQP Consumer Worker", 1);
pid=fork_process(AMQP_WORKERS_RANKING, "AMQP Consumer Worker", 1);
if (pid<0)
return -1; /* error */
if(pid==0){
if (cfg_child_init()) return -1;
close(kz_worker_pipes_fds[i*2+1]);
cfg_update();
return(kz_amqp_consumer_worker_proc(kz_worker_pipes_fds[i*2]));
}
}
@ -408,6 +387,7 @@ static int mod_child_init(int rank)
return -1; /* error */
if(pid==0){
if (cfg_child_init()) return -1;
cfg_update();
return(kz_amqp_consumer_proc(s));
}
}
@ -420,12 +400,13 @@ static int mod_child_init(int rank)
if(pid==0){
if (cfg_child_init()) return -1;
close(kz_cmd_pipe_fds[1]);
cfg_update();
kz_amqp_publisher_proc(kz_cmd_pipe_fds[0]);
}
return 0;
}
if(dbk_pua_mode == 1) {
if(rank == AMQP_WORKERS_RANKING && dbk_pua_mode == 1) {
if (kz_pa_dbf.init==0)
{
LM_CRIT("child_init: database not bound\n");
@ -483,8 +464,8 @@ static int fire_init_event(int rank)
static void mod_destroy(void) {
kz_amqp_destroy();
shm_free(kz_worker_pipes_fds);
shm_free(kz_worker_pipes);
if (kz_worker_pipes_fds) { shm_free(kz_worker_pipes_fds); }
if (kz_worker_pipes) { shm_free(kz_worker_pipes); }
}

File diff suppressed because it is too large Load Diff

@ -59,26 +59,23 @@ extern int dbk_consumer_workers;
typedef struct kz_amqp_connection_t {
kz_amqp_connection_info info;
char* url;
// struct kz_amqp_connection_t* next;
} kz_amqp_connection, *kz_amqp_connection_ptr;
/*
typedef struct {
kz_amqp_connection_ptr current;
kz_amqp_connection_ptr head;
kz_amqp_connection_ptr tail;
} kz_amqp_connection_pool, *kz_amqp_connection_pool_ptr;
*/
typedef struct kz_amqp_timer_t {
struct event *ev;
struct itimerspec *timer;
int fd;
} kz_amqp_timer, *kz_amqp_timer_ptr;
typedef struct kz_amqp_conn_t {
struct kz_amqp_server_t* server;
amqp_connection_state_t conn;
kz_amqp_connection_state state;
struct event *ev;
struct itimerspec *timer;
kz_amqp_timer_ptr reconnect;
kz_amqp_timer_ptr heartbeat;
amqp_socket_t *socket;
amqp_channel_t channel_count;
amqp_channel_t channel_counter;
// struct kz_amqp_conn_t* next;
} kz_amqp_conn, *kz_amqp_conn_ptr;
typedef struct {
@ -112,10 +109,6 @@ typedef struct {
amqp_channel_t channel;
struct timeval timeout;
/* timer */
// struct event *timer_ev;
// int timerfd;
/* async */
char *cb_route;
char *err_route;
@ -152,23 +145,58 @@ typedef struct {
char* event_key;
char* event_subkey;
str* message_id;
str* routing_key;
kz_amqp_cmd_ptr cmd;
} kz_amqp_consumer_delivery, *kz_amqp_consumer_delivery_ptr;
typedef struct {
amqp_bytes_t exchange;
amqp_bytes_t exchange_type;
amqp_bytes_t routing_key;
amqp_bytes_t queue;
amqp_bytes_t event_key;
amqp_bytes_t event_subkey;
amqp_bytes_t name;
amqp_bytes_t type;
amqp_boolean_t passive;
amqp_boolean_t durable;
amqp_boolean_t auto_delete;
amqp_boolean_t internal;
} kz_amqp_exchange, *kz_amqp_exchange_ptr;
typedef struct {
amqp_bytes_t name;
amqp_boolean_t passive;
amqp_boolean_t durable;
amqp_boolean_t exclusive;
amqp_boolean_t auto_delete;
} kz_amqp_queue, *kz_amqp_queue_ptr;
typedef struct kz_amqp_routings_t {
amqp_bytes_t routing;
struct kz_amqp_routings_t* next;
} kz_amqp_routings, *kz_amqp_routings_ptr;
typedef struct kz_amqp_exchange_binding_t {
kz_amqp_exchange_ptr from_exchange;
kz_amqp_routings_ptr routing;
struct kz_amqp_exchange_binding_t* next;
} kz_amqp_exchange_binding, *kz_amqp_exchange_binding_ptr;
typedef struct {
// amqp_bytes_t exchange;
// amqp_bytes_t exchange_type;
kz_amqp_exchange_ptr exchange;
kz_amqp_exchange_binding_ptr exchange_bindings;
kz_amqp_queue_ptr queue;
kz_amqp_routings_ptr queue_bindings;
// amqp_bytes_t routing_key;
// amqp_bytes_t queue;
amqp_bytes_t event_key;
amqp_bytes_t event_subkey;
// amqp_boolean_t passive;
// amqp_boolean_t durable;
// amqp_boolean_t exclusive;
// amqp_boolean_t auto_delete;
amqp_boolean_t no_ack;
amqp_boolean_t wait_for_consumer_ack;
amqp_boolean_t federate;
amqp_boolean_t consistent_worker;
str* consistent_worker_key;
} kz_amqp_bind, *kz_amqp_bind_ptr;
typedef struct {
@ -257,10 +285,22 @@ kz_amqp_zone_ptr kz_amqp_get_zones();
kz_amqp_zone_ptr kz_amqp_get_zone(char* zone);
kz_amqp_zone_ptr kz_amqp_add_zone(char* zone);
void kz_amqp_fire_connection_event(char *event, char* host);
void kz_amqp_fire_connection_event(char *event, char* host, char* zone);
void kz_amqp_free_pipe_cmd(kz_amqp_cmd_ptr cmd);
void kz_amqp_timer_destroy(kz_amqp_timer_ptr* pTimer);
int kz_amqp_timer_create(kz_amqp_timer_ptr* pTimer, int seconds, void (*callback)(int, short, void *), void *data);
void kz_amqp_heartbeat_proc(int fd, short event, void *arg);
void kz_amqp_queue_free(kz_amqp_queue_ptr exchange);
void kz_amqp_exchange_free(kz_amqp_exchange_ptr exchange);
void kz_amqp_exchange_bindings_free(kz_amqp_exchange_binding_ptr binding);
void kz_amqp_routing_free(kz_amqp_routings_ptr routing);
kz_amqp_queue_ptr kz_amqp_queue_new(str *name);
kz_amqp_exchange_ptr kz_amqp_exchange_new(str *name, str* type);
kz_amqp_routings_ptr kz_amqp_routing_new(char* routing);
static inline int kz_amqp_error(char const *context, amqp_rpc_reply_t x)
{
amqp_connection_close_t *mconn;
@ -306,3 +346,4 @@ static inline int kz_amqp_error(char const *context, amqp_rpc_reply_t x)
#endif /* KZ_AMQP_H_ */

@ -29,24 +29,22 @@
#include "../../pvar.h"
#include "../../usr_avp.h"
# define json_foreach_key(obj,key) \
char *key;\
struct lh_entry *entry ## key; \
struct lh_entry *entry_next ## key = NULL; \
for(entry ## key = json_object_get_object(obj)->head; \
(entry ## key ? ( \
key = (char*)entry ## key->k, \
entry_next ## key = entry ## key->next, \
entry ## key) : 0); \
entry ## key = entry_next ## key)
static str kz_pv_str_empty = {"", 0};
char** str_split(char* a_str, const char a_delim)
enum json_type kz_json_get_type(struct json_object *jso)
{
char** result = 0;
size_t count = 0;
return json_object_get_type(jso);
}
typedef str* json_key;
typedef json_key* json_keys;
json_keys str_split(char* a_str, const char a_delim, int* c)
{
json_keys result = 0;
int count = 0;
char* tmp = a_str;
char* last_comma = 0;
char delim[2];
@ -70,34 +68,43 @@ char** str_split(char* a_str, const char a_delim)
/* Add space for terminating null string so caller
knows where the list of returned strings ends. */
count++;
// count++;
*c = count;
LM_DBG("COUNT %d\n", count);
result = pkg_malloc(sizeof(char*) * count);
result = pkg_malloc(sizeof(json_key) * count);
memset(result, 0, sizeof(json_key) * count);
if (result)
{
size_t idx = 0;
int idx = 0;
char* token = strtok(a_str, delim);
while (token)
{
LM_DBG("TOKEN %d : %s\n", idx, token);
assert(idx < count);
result[idx] = pkg_malloc(sizeof(str));
len = strlen(token);
char* ptr = pkg_malloc( (len+1) * sizeof(char));
*(result + idx) = ptr;
memcpy(ptr, token, len);
ptr[len] = '\0';
result[idx]->len = len;
result[idx]->s = pkg_malloc((len + 1) * sizeof(char));
strncpy(result[idx]->s, token, len);
result[idx]->s[len] = '\0';
int i = 0;
while(i < len) {
if(ptr[i] == kz_json_escape_char)
ptr[i] = '.';
if(result[idx]->s[i] == kz_json_escape_char)
result[idx]->s[i] = '.';
i++;
}
LM_DBG("TOKEN2 %d : %s\n", idx, result[idx]->s);
token = strtok(0, delim);
idx++;
}
assert(idx == count - 1);
*(result + idx) = 0;
assert(idx == count);
}
return result;
@ -105,10 +112,12 @@ char** str_split(char* a_str, const char a_delim)
struct json_object * kz_json_get_field_object(str* json, str* field)
{
char** tokens;
json_keys keys;
json_key key;
char* dup;
char f1[25], f2[25];//, f3[25];
int i;
char* token;
char f1[250], f2[250];//, f3[25];
int i, parts;
dup = pkg_malloc(json->len+1);
memcpy(dup, json->s, json->len);
@ -129,19 +138,22 @@ struct json_object * kz_json_get_field_object(str* json, str* field)
dup = pkg_malloc(field->len+1);
memcpy(dup, field->s, field->len);
dup[field->len] = '\0';
tokens = str_split(dup, '.');
keys = str_split(dup, '.', &parts);
pkg_free(dup);
if (tokens)
if (keys)
{
jtree = j;
for (i = 0; *(tokens + i); i++)
for (i = 0; i < parts; i++)
{
key = keys[i];
LM_DBG("TOKEN %d , %p, %p : %s\n", i, keys[i], key->s, key->s);
if(jtree != NULL) {
str field = str_init(*(tokens + i));
//str field1 = str_init(token);
// check for idx []
int sresult = sscanf(field.s, "%[^[][%[^]]]", f1, f2); //, f3);
LM_DBG("CHECK IDX %d - %s , %s, %s\n", sresult, field.s, f1, (sresult > 1? f2 : "(null)"));
int sresult = sscanf(key->s, "%[^[][%[^]]]", f1, f2); //, f3);
LM_DBG("CHECK IDX %d - %s , %s, %s\n", sresult, key->s, f1, (sresult > 1? f2 : "(null)"));
jtree = kz_json_get_object(jtree, f1);
if(jtree != NULL) {
@ -157,9 +169,15 @@ struct json_object * kz_json_get_field_object(str* json, str* field)
}
}
}
pkg_free(*(tokens + i));
}
pkg_free(tokens);
for(i = 0;i < parts; i++) {
LM_DBG("FREE %d\n", i);
pkg_free(keys[i]->s);
pkg_free(keys[i]);
}
pkg_free(keys);
}
@ -314,3 +332,4 @@ int kz_json_get_keys(struct sip_msg* msg, char* json, char* field, char* dst)
return 1;
}

@ -1,8 +1,29 @@
/*
* kz_json.h
* $Id$
*
* Created on: Aug 2, 2014
* Author: root
* Kazoo module interface
*
* Copyright (C) 2010-2014 2600Hz
*
* This file is part of Kamailio, a free SIP server.
*
* Kamailio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
* Kamailio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
* History:
* --------
* 2014-08 first version (2600hz)
*/
#ifndef KZ_JSON_H_
@ -15,8 +36,61 @@
int kz_json_get_field(struct sip_msg* msg, char* json, char* field, char* dst);
int kz_json_get_field_ex(str* json, str* field, pv_value_p dst_val);
int kz_json_get_keys(struct sip_msg* msg, char* json, char* field, char* dst);
enum json_type kz_json_get_type(struct json_object *jso);
struct json_object* kz_json_parse(const char *str);
struct json_object* kz_json_get_object(struct json_object* jso, const char *key);
#if defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L
# define json_foreach(obj,key,val) \
char *key; \
struct json_object *val __attribute__((__unused__)); \
for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \
({ if(entry ## key) { \
key = (char*)entry ## key->k; \
val = (struct json_object*)entry ## key->v; \
entry_next ## key = entry ## key->next; \
} ; entry ## key; }); \
entry ## key = entry_next ## key )
# define json_foreach_key(obj,key) \
char *key; \
for(struct lh_entry *entry ## key = json_object_get_object(obj)->head, *entry_next ## key = NULL; \
({ if(entry ## key) { \
key = (char*)entry ## key->k; \
entry_next ## key = entry ## key->next; \
} ; entry ## key; }); \
entry ## key = entry_next ## key )
#else /* ANSI C or MSC */
# define json_foreach(obj,key,val) \
char *key;\
struct json_object *val; \
struct lh_entry *entry ## key; \
struct lh_entry *entry_next ## key = NULL; \
for(entry ## key = json_object_get_object(obj)->head; \
(entry ## key ? ( \
key = (char*)entry ## key->k, \
val = (struct json_object*)entry ## key->v, \
entry_next ## key = entry ## key->next, \
entry ## key) : 0); \
entry ## key = entry_next ## key)
# define json_foreach_key(obj,key) \
char *key;\
struct lh_entry *entry ## key; \
struct lh_entry *entry_next ## key = NULL; \
for(entry ## key = json_object_get_object(obj)->head; \
(entry ## key ? ( \
key = (char*)entry ## key->k, \
entry_next ## key = entry ## key->next, \
entry ## key) : 0); \
entry ## key = entry_next ## key)
#endif /* defined(__GNUC__) && !defined(__STRICT_ANSI__) && __STDC_VERSION__ >= 199901L */
#endif /* KZ_JSON_H_ */

@ -21,6 +21,7 @@ extern db1_con_t *kz_pa_db;
extern db_func_t kz_pa_dbf;
extern str kz_presentity_table;
extern db_locking_t kz_pua_lock_type;
int kz_pua_update_presentity(str* event, str* realm, str* user, str* etag, str* sender, str* body, int expires, int reset)
{
@ -103,7 +104,7 @@ int kz_pua_update_presentity(str* event, str* realm, str* user, str* etag, str*
if (kz_pa_dbf.start_transaction)
{
if (kz_pa_dbf.start_transaction(kz_pa_db, DB_LOCKING_WRITE) < 0)
if (kz_pa_dbf.start_transaction(kz_pa_db, kz_pua_lock_type) < 0)
{
LM_ERR("in start_transaction\n");
goto error;
@ -173,6 +174,8 @@ int kz_pua_publish_presence_to_presentity(struct json_object *json_obj) {
str note = str_init("Available");
str status = str_presence_status_online;
int expires = 0;
str sender = {0, 0},
etag = { 0, 0 };
char *body = (char *)pkg_malloc(PRESENCE_BODY_BUFFER_SIZE);
if(body == NULL) {
@ -181,311 +184,395 @@ int kz_pua_publish_presence_to_presentity(struct json_object *json_obj) {
goto error;
}
json_extract_field(BLF_JSON_FROM, from);
json_extract_field(BLF_JSON_FROM_USER, from_user);
json_extract_field(BLF_JSON_FROM_REALM, from_realm);
json_extract_field(BLF_JSON_TO, to);
json_extract_field(BLF_JSON_TO_USER, to_user);
json_extract_field(BLF_JSON_TO_REALM, to_realm);
json_extract_field(BLF_JSON_CALLID, callid);
json_extract_field(BLF_JSON_FROMTAG, fromtag);
json_extract_field(BLF_JSON_TOTAG, totag);
json_extract_field(BLF_JSON_DIRECTION, direction);
json_extract_field(BLF_JSON_STATE, state);
struct json_object* ExpiresObj = kz_json_get_object(json_obj, BLF_JSON_EXPIRES);
if(ExpiresObj != NULL) {
expires = json_object_get_int(ExpiresObj);
if(expires > 0)
expires += (int)time(NULL);
}
json_extract_field(BLF_JSON_FROM, from);
json_extract_field(BLF_JSON_FROM_USER, from_user);
json_extract_field(BLF_JSON_FROM_REALM, from_realm);
json_extract_field(BLF_JSON_TO, to);
json_extract_field(BLF_JSON_TO_USER, to_user);
json_extract_field(BLF_JSON_TO_REALM, to_realm);
json_extract_field(BLF_JSON_CALLID, callid);
json_extract_field(BLF_JSON_FROMTAG, fromtag);
json_extract_field(BLF_JSON_TOTAG, totag);
json_extract_field(BLF_JSON_DIRECTION, direction);
json_extract_field(BLF_JSON_STATE, state);
json_extract_field(BLF_JSON_ETAG, etag);
json_extract_field(BLF_JSON_SENDER, sender);
if (sender.len == 0) {
json_extract_field(BLF_JSON_SWITCH_URI, sender);
}
if (!from_user.len || !to_user.len || !state.len) {
LM_ERR("missing one of From / To / State\n");
goto error;
}
struct json_object* ExpiresObj = kz_json_get_object(json_obj, BLF_JSON_EXPIRES);
if (ExpiresObj != NULL) {
expires = json_object_get_int(ExpiresObj);
if (expires > 0)
expires += (int) time(NULL);
}
if (!strcmp(state.s, "early")) {
note = str_presence_note_busy;
activity = str_presence_act_busy;
if (!from_user.len || !to_user.len || !state.len) {
LM_ERR("missing one of From / To / State\n");
goto error;
}
} else if (!strcmp(state.s, "confirmed")) {
note = str_presence_note_otp;
activity = str_presence_act_otp;
if (!strcmp(state.s, "early")) {
note = str_presence_note_busy;
activity = str_presence_act_busy;
} else if (!strcmp(state.s, "offline")) {
note = str_presence_note_offline;
status = str_presence_status_offline;
} else if (!strcmp(state.s, "confirmed")) {
note = str_presence_note_otp;
activity = str_presence_act_otp;
}; // else {
// note = str_presence_note_idle;
// }
} else if (!strcmp(state.s, "offline")) {
note = str_presence_note_offline;
status = str_presence_status_offline;
};
sprintf(body, PRESENCE_BODY, from_user.s, callid.s, status.s, note.s, activity.s, note.s);
sprintf(body, PRESENCE_BODY, from_user.s, callid.s, status.s, note.s, activity.s, note.s);
presence_body.s = body;
presence_body.len = strlen(body);
presence_body.s = body;
presence_body.len = strlen(body);
if(dbk_pua_mode == 1) {
kz_pua_update_presentity(&event, &from_realm, &from_user, &callid, &from, &presence_body, expires, 1);
}
if (sender.len == 0) {
sender = from;
}
error:
if (etag.len == 0) {
etag = callid;
}
kz_pua_update_presentity(&event, &from_realm, &from_user, &etag, &sender, &presence_body, expires, 1);
error:
if(body)
pkg_free(body);
if (body)
pkg_free(body);
return ret;
return ret;
}
int kz_pua_publish_mwi_to_presentity(struct json_object *json_obj) {
int ret = 1;
str event = str_init("message-summary");
str from = { 0, 0 }, to = { 0, 0 };
str from_user = { 0, 0 }, to_user = { 0, 0 };
str from_realm = { 0, 0 }, to_realm = { 0, 0 };
str callid = { 0, 0 }, fromtag = { 0, 0 }, totag = { 0, 0 };
str mwi_user = { 0, 0 }, mwi_waiting = { 0, 0 },
mwi_new = { 0, 0 }, mwi_saved = { 0, 0 },
mwi_urgent = { 0, 0 }, mwi_urgent_saved = { 0, 0 },
mwi_account = { 0, 0 }, mwi_body = { 0, 0 };
int expires = 0;
int kz_pua_publish_mwi_to_presentity(struct json_object *json_obj)
{
int ret = 1;
str event = str_init("message-summary");
str from = {0, 0},
to = { 0, 0 };
str from_user = { 0, 0 }, to_user = { 0, 0 };
str from_realm = { 0, 0 }, to_realm = { 0, 0 };
str callid = { 0, 0 }, fromtag = { 0, 0 }, totag = { 0, 0 };
str mwi_user = { 0, 0 }, mwi_waiting = { 0, 0 }, mwi_new = { 0, 0 }, mwi_saved = { 0, 0 }, mwi_urgent = { 0, 0 }, mwi_urgent_saved = { 0, 0 }, mwi_account = { 0, 0 },
mwi_body = { 0, 0 };
int expires = 0;
str sender = { 0, 0 }, etag = { 0, 0 };
char *body = (char *) pkg_malloc(MWI_BODY_BUFFER_SIZE);
if (body == NULL) {
LM_ERR("Error allocating buffer for publish\n");
ret = -1;
goto error;
}
char *body = (char *)pkg_malloc(MWI_BODY_BUFFER_SIZE);
if(body == NULL) {
LM_ERR("Error allocating buffer for publish\n");
ret = -1;
goto error;
}
json_extract_field(BLF_JSON_FROM, from);
json_extract_field(BLF_JSON_FROM_USER, from_user);
json_extract_field(BLF_JSON_FROM_REALM, from_realm);
json_extract_field(BLF_JSON_TO, to);
json_extract_field(BLF_JSON_TO_USER, to_user);
json_extract_field(BLF_JSON_TO_REALM, to_realm);
json_extract_field(BLF_JSON_CALLID, callid);
json_extract_field(BLF_JSON_FROMTAG, fromtag);
json_extract_field(BLF_JSON_TOTAG, totag);
json_extract_field(MWI_JSON_TO, mwi_user);
json_extract_field(MWI_JSON_WAITING, mwi_waiting);
json_extract_field(MWI_JSON_NEW, mwi_new);
json_extract_field(MWI_JSON_SAVED, mwi_saved);
json_extract_field(MWI_JSON_URGENT, mwi_urgent);
json_extract_field(MWI_JSON_URGENT_SAVED, mwi_urgent_saved);
json_extract_field(MWI_JSON_ACCOUNT, mwi_account);
json_extract_field(BLF_JSON_ETAG, etag);
json_extract_field(BLF_JSON_SENDER, sender);
struct json_object* ExpiresObj = kz_json_get_object(json_obj, BLF_JSON_EXPIRES);
if (ExpiresObj != NULL) {
expires = json_object_get_int(ExpiresObj);
if (expires > 0)
expires += (int) time(NULL);
}
json_extract_field(BLF_JSON_FROM, from);
json_extract_field(BLF_JSON_FROM_USER, from_user);
json_extract_field(BLF_JSON_FROM_REALM, from_realm);
json_extract_field(BLF_JSON_TO, to);
json_extract_field(BLF_JSON_TO_USER, to_user);
json_extract_field(BLF_JSON_TO_REALM, to_realm);
json_extract_field(BLF_JSON_CALLID, callid);
json_extract_field(BLF_JSON_FROMTAG, fromtag);
json_extract_field(BLF_JSON_TOTAG, totag);
json_extract_field(MWI_JSON_TO, mwi_user);
json_extract_field(MWI_JSON_WAITING, mwi_waiting);
json_extract_field(MWI_JSON_NEW, mwi_new);
json_extract_field(MWI_JSON_SAVED, mwi_saved);
json_extract_field(MWI_JSON_URGENT, mwi_urgent);
json_extract_field(MWI_JSON_URGENT_SAVED, mwi_urgent_saved);
json_extract_field(MWI_JSON_ACCOUNT, mwi_account);
struct json_object* ExpiresObj = kz_json_get_object(json_obj, BLF_JSON_EXPIRES);
if(ExpiresObj != NULL) {
expires = json_object_get_int(ExpiresObj);
if(expires > 0)
expires += (int)time(NULL);
}
sprintf(body, MWI_BODY, mwi_waiting.len, mwi_waiting.s, mwi_account.len, mwi_account.s, mwi_new.len, mwi_new.s, mwi_saved.len, mwi_saved.s, mwi_urgent.len,
mwi_urgent.s, mwi_urgent_saved.len, mwi_urgent_saved.s);
sprintf(body, MWI_BODY, mwi_waiting.len, mwi_waiting.s,
mwi_account.len, mwi_account.s, mwi_new.len, mwi_new.s,
mwi_saved.len, mwi_saved.s, mwi_urgent.len, mwi_urgent.s,
mwi_urgent_saved.len, mwi_urgent_saved.s);
mwi_body.s = body;
mwi_body.len = strlen(body);
mwi_body.s = body;
mwi_body.len = strlen(body);
if (sender.len == 0) {
sender = from;
}
if(dbk_pua_mode == 1) {
kz_pua_update_presentity(&event, &from_realm, &from_user, &callid, &from, &mwi_body, expires, 1);
}
if (etag.len == 0) {
etag = callid;
}
error:
kz_pua_update_presentity(&event, &from_realm, &from_user, &etag, &from, &mwi_body, expires, 1);
if(body)
pkg_free(body);
error:
if (body)
pkg_free(body);
return ret;
return ret;
}
int kz_pua_publish_dialoginfo_to_presentity(struct json_object *json_obj) {
int ret = 1;
str from = { 0, 0 }, to = { 0, 0 }, pres = {0, 0};
str from_user = { 0, 0 }, to_user = { 0, 0 }, pres_user = { 0, 0 };
str from_realm = { 0, 0 }, to_realm = { 0, 0 }, pres_realm = { 0, 0 };
str from_uri = { 0, 0 }, to_uri = { 0, 0 };
str callid = { 0, 0 }, fromtag = { 0, 0 }, totag = { 0, 0 };
str state = { 0, 0 };
str direction = { 0, 0 };
char sender_buf[1024];
str sender = {0, 0};
str dialoginfo_body = {0 , 0};
int expires = 0;
str event = str_init("dialog");
int reset = 0;
char to_tag_buffer[100];
char from_tag_buffer[100];
char *body = (char *)pkg_malloc(DIALOGINFO_BODY_BUFFER_SIZE);
if(body == NULL) {
LM_ERR("Error allocating buffer for publish\n");
ret = -1;
goto error;
}
int kz_pua_publish_dialoginfo_to_presentity(struct json_object *json_obj)
{
int ret = 1;
str from = { 0, 0 }, to = { 0, 0 }, pres = { 0, 0 };
str from_user = { 0, 0 }, to_user = { 0, 0 }, pres_user = { 0, 0 };
str from_realm = { 0, 0 }, to_realm = { 0, 0 }, pres_realm = { 0, 0 };
str from_uri = { 0, 0 }, to_uri = { 0, 0 };
str callid = { 0, 0 }, dialogid = { 0, 0 };
str fromtag = { 0, 0 }, totag = { 0, 0 };
str state = { 0, 0 };
str direction = { 0, 0 };
str dialoginfo_body = { 0, 0 };
int expires = 0;
str event = str_init("dialog");
int reset = 0;
char to_tag_buffer[100];
char from_tag_buffer[100];
char sender_buf[1024];
str sender = { 0, 0 }, etag = { 0, 0 };
char *body = (char *) pkg_malloc(DIALOGINFO_BODY_BUFFER_SIZE);
if (body == NULL) {
LM_ERR("Error allocating buffer for publish\n");
ret = -1;
goto error;
}
json_extract_field(BLF_JSON_PRES, pres);
json_extract_field(BLF_JSON_PRES_USER, pres_user);
json_extract_field(BLF_JSON_PRES_REALM, pres_realm);
json_extract_field(BLF_JSON_FROM, from);
json_extract_field(BLF_JSON_FROM_USER, from_user);
json_extract_field(BLF_JSON_FROM_REALM, from_realm);
json_extract_field(BLF_JSON_FROM_URI, from_uri);
json_extract_field(BLF_JSON_TO, to);
json_extract_field(BLF_JSON_TO_USER, to_user);
json_extract_field(BLF_JSON_TO_REALM, to_realm);
json_extract_field(BLF_JSON_TO_URI, to_uri);
json_extract_field(BLF_JSON_CALLID, callid);
json_extract_field(BLF_JSON_DIALOGID, dialogid);
json_extract_field(BLF_JSON_FROMTAG, fromtag);
json_extract_field(BLF_JSON_TOTAG, totag);
json_extract_field(BLF_JSON_DIRECTION, direction);
json_extract_field(BLF_JSON_STATE, state);
json_extract_field(BLF_JSON_ETAG, etag);
json_extract_field(BLF_JSON_SENDER, sender);
if (sender.len == 0) {
json_extract_field(BLF_JSON_SWITCH_URI, sender);
}
json_extract_field(BLF_JSON_PRES, pres);
json_extract_field(BLF_JSON_PRES_USER, pres_user);
json_extract_field(BLF_JSON_PRES_REALM, pres_realm);
json_extract_field(BLF_JSON_FROM, from);
json_extract_field(BLF_JSON_FROM_USER, from_user);
json_extract_field(BLF_JSON_FROM_REALM, from_realm);
json_extract_field(BLF_JSON_FROM_URI, from_uri);
json_extract_field(BLF_JSON_TO, to);
json_extract_field(BLF_JSON_TO_USER, to_user);
json_extract_field(BLF_JSON_TO_REALM, to_realm);
json_extract_field(BLF_JSON_TO_URI, to_uri);
json_extract_field(BLF_JSON_CALLID, callid);
json_extract_field(BLF_JSON_FROMTAG, fromtag);
json_extract_field(BLF_JSON_TOTAG, totag);
json_extract_field(BLF_JSON_DIRECTION, direction);
json_extract_field(BLF_JSON_STATE, state);
struct json_object* ExpiresObj = kz_json_get_object(json_obj, BLF_JSON_EXPIRES);
if(ExpiresObj != NULL) {
expires = json_object_get_int(ExpiresObj);
if(expires > 0)
expires += (int)time(NULL);
}
struct json_object* ExpiresObj = kz_json_get_object(json_obj, BLF_JSON_EXPIRES);
if (ExpiresObj != NULL) {
expires = json_object_get_int(ExpiresObj);
if (expires > 0)
expires += (int) time(NULL);
}
ExpiresObj = kz_json_get_object(json_obj, "Flush-Level");
if(ExpiresObj != NULL) {
reset = json_object_get_int(ExpiresObj);
}
ExpiresObj = kz_json_get_object(json_obj, "Flush-Level");
if (ExpiresObj != NULL) {
reset = json_object_get_int(ExpiresObj);
}
if (!from.len || !to.len || !state.len) {
LM_ERR("missing one of From / To / State\n");
if (!from.len || !to.len || !state.len) {
LM_ERR("missing one of From / To / State\n");
goto error;
}
}
if(!pres.len || !pres_user.len || !pres_realm.len) {
pres = from;
pres_user = from_user;
pres_realm = from_realm;
}
if (!pres.len || !pres_user.len || !pres_realm.len) {
pres = from;
pres_user = from_user;
pres_realm = from_realm;
}
if(!from_uri.len)
from_uri = from;
if (!from_uri.len)
from_uri = from;
if(!to_uri.len)
to_uri = to;
if (!to_uri.len)
to_uri = to;
if(fromtag.len > 0) {
fromtag.len = sprintf(from_tag_buffer, LOCAL_TAG, fromtag.len, fromtag.s);
fromtag.s = from_tag_buffer;
}
if (fromtag.len > 0) {
fromtag.len = sprintf(from_tag_buffer, LOCAL_TAG, fromtag.len, fromtag.s);
fromtag.s = from_tag_buffer;
}
if(totag.len > 0) {
totag.len = sprintf(to_tag_buffer, REMOTE_TAG, totag.len, totag.s);
totag.s = to_tag_buffer;
}
if (totag.len > 0) {
totag.len = sprintf(to_tag_buffer, REMOTE_TAG, totag.len, totag.s);
totag.s = to_tag_buffer;
}
if(callid.len) {
if(dbk_include_entity) {
sprintf(body, DIALOGINFO_BODY,
pres.len, pres.s,
callid.len, callid.s,
callid.len, callid.s,
fromtag.len, fromtag.s,
totag.len, totag.s,
direction.len, direction.s,
state.len, state.s,
from_user.len, from_user.s,
from.len, from.s,
from_uri.len, from_uri.s,
to_user.len, to_user.s,
to.len, to.s,
to_uri.len, to_uri.s
);
} else {
sprintf(body, DIALOGINFO_BODY_2,
pres.len, pres.s,
callid.len, callid.s,
callid.len, callid.s,
fromtag.len, fromtag.s,
totag.len, totag.s,
direction.len, direction.s,
state.len, state.s,
from_user.len, from_user.s,
from.len, from.s,
to_user.len, to_user.s,
to.len, to.s
);
}
} else {
sprintf(body, DIALOGINFO_EMPTY_BODY, pres.len, pres.s);
}
if (dialogid.len == 0) {
dialogid = callid;
}
sprintf(sender_buf, "sip:%s",callid.s);
sender.s = sender_buf;
sender.len = strlen(sender_buf);
if (callid.len) {
dialoginfo_body.s = body;
dialoginfo_body.len = strlen(body);
if (dbk_include_entity) {
sprintf(body, DIALOGINFO_BODY, pres.len, pres.s, dialogid.len, dialogid.s, callid.len, callid.s, fromtag.len, fromtag.s, totag.len, totag.s, direction.len,
direction.s, state.len, state.s, from_user.len, from_user.s, from.len, from.s, from_uri.len, from_uri.s, to_user.len, to_user.s, to.len, to.s,
to_uri.len, to_uri.s);
} else {
if(dbk_pua_mode == 1) {
kz_pua_update_presentity(&event, &pres_realm, &pres_user, &callid, &sender, &dialoginfo_body, expires, reset);
}
sprintf(body, DIALOGINFO_BODY_2, pres.len, pres.s, dialogid.len, dialogid.s, callid.len, callid.s, fromtag.len, fromtag.s, totag.len, totag.s, direction.len,
direction.s, state.len, state.s, from_user.len, from_user.s, from.len, from.s, to_user.len, to_user.s, to.len, to.s);
}
} else {
sprintf(body, DIALOGINFO_EMPTY_BODY, pres.len, pres.s);
}
error:
if (sender.len == 0) {
sprintf(sender_buf, "sip:%s", callid.s);
sender.s = sender_buf;
sender.len = strlen(sender_buf);
}
if (etag.len == 0) {
etag = callid;
}
if(body)
pkg_free(body);
dialoginfo_body.s = body;
dialoginfo_body.len = strlen(body);
kz_pua_update_presentity(&event, &pres_realm, &pres_user, &etag, &sender, &dialoginfo_body, expires, reset);
return ret;
error:
if (body)
pkg_free(body);
return ret;
}
int kz_pua_publish(struct sip_msg* msg, char *json) {
str event_name = { 0, 0 }, event_package = { 0, 0 };
struct json_object *json_obj = NULL;
int ret = 1;
int kz_pua_publish(struct sip_msg* msg, char *json)
{
str event_name = { 0, 0 }, event_package = { 0, 0 };
struct json_object *json_obj = NULL;
int ret = 1;
if(dbk_pua_mode != 1) {
LM_ERR("pua_mode must be 1 to publish\n");
ret = -1;
goto error;
}
if (dbk_pua_mode != 1) {
LM_ERR("pua_mode must be 1 to publish\n");
ret = -1;
goto error;
}
/* extract info from json and construct xml */
json_obj = kz_json_parse(json);
if (json_obj == NULL) {
ret = -1;
goto error;
}
/* extract info from json and construct xml */
json_obj = kz_json_parse(json);
if (json_obj == NULL) {
ret = -1;
goto error;
}
json_extract_field(BLF_JSON_EVENT_NAME, event_name);
if (event_name.len == 6 && strncmp(event_name.s, "update", 6) == 0) {
json_extract_field(BLF_JSON_EVENT_PKG, event_package);
if (event_package.len == str_event_dialog.len
&& strncmp(event_package.s, str_event_dialog.s, event_package.len) == 0) {
ret = kz_pua_publish_dialoginfo_to_presentity(json_obj);
} else if (event_package.len == str_event_message_summary.len
&& strncmp(event_package.s, str_event_message_summary.s, event_package.len) == 0) {
ret = kz_pua_publish_mwi_to_presentity(json_obj);
} else if (event_package.len == str_event_presence.len
&& strncmp(event_package.s, str_event_presence.s, event_package.len) == 0) {
ret = kz_pua_publish_presence_to_presentity(json_obj);
}
}
json_extract_field(BLF_JSON_EVENT_NAME, event_name);
error:
if(json_obj)
if (event_name.len == 6 && strncmp(event_name.s, "update", 6) == 0) {
json_extract_field(BLF_JSON_EVENT_PKG, event_package);
if (event_package.len == str_event_dialog.len && strncmp(event_package.s, str_event_dialog.s, event_package.len) == 0) {
ret = kz_pua_publish_dialoginfo_to_presentity(json_obj);
} else if (event_package.len == str_event_message_summary.len && strncmp(event_package.s, str_event_message_summary.s, event_package.len) == 0) {
ret = kz_pua_publish_mwi_to_presentity(json_obj);
} else if (event_package.len == str_event_presence.len && strncmp(event_package.s, str_event_presence.s, event_package.len) == 0) {
ret = kz_pua_publish_presence_to_presentity(json_obj);
}
}
error: if (json_obj)
json_object_put(json_obj);
return ret;
}
int kz_pua_publish_mwi(struct sip_msg* msg, char *json)
{
struct json_object *json_obj = NULL;
int ret = 1;
if (dbk_pua_mode != 1) {
LM_ERR("pua_mode must be 1 to publish\n");
ret = -1;
goto error;
}
/* extract info from json and construct xml */
json_obj = kz_json_parse(json);
if (json_obj == NULL) {
ret = -1;
goto error;
}
ret = kz_pua_publish_mwi_to_presentity(json_obj);
error: if (json_obj)
json_object_put(json_obj);
return ret;
}
int kz_pua_publish_presence(struct sip_msg* msg, char *json)
{
struct json_object *json_obj = NULL;
int ret = 1;
if (dbk_pua_mode != 1) {
LM_ERR("pua_mode must be 1 to publish\n");
ret = -1;
goto error;
}
/* extract info from json and construct xml */
json_obj = kz_json_parse(json);
if (json_obj == NULL) {
ret = -1;
goto error;
}
ret = kz_pua_publish_presence_to_presentity(json_obj);
error: if (json_obj)
json_object_put(json_obj);
return ret;
}
int kz_pua_publish_dialoginfo(struct sip_msg* msg, char *json)
{
struct json_object *json_obj = NULL;
int ret = 1;
if (dbk_pua_mode != 1) {
LM_ERR("pua_mode must be 1 to publish\n");
ret = -1;
goto error;
}
/* extract info from json and construct xml */
json_obj = kz_json_parse(json);
if (json_obj == NULL) {
ret = -1;
goto error;
}
ret = kz_pua_publish_dialoginfo_to_presentity(json_obj);
error: if (json_obj)
json_object_put(json_obj);
return ret;
}

@ -4,6 +4,9 @@
int kz_initialize_pua();
int kz_pua_publish(struct sip_msg* msg, char *json);
int kz_pua_publish_mwi(struct sip_msg* msg, char *json);
int kz_pua_publish_presence(struct sip_msg* msg, char *json);
int kz_pua_publish_dialoginfo(struct sip_msg* msg, char *json);
#endif

@ -28,6 +28,7 @@
#ifndef LD_SESSION_H
#define LD_SESSION_H
#include <sys/time.h>
#include <ldap.h>
#include "iniparser.h"

@ -39,6 +39,7 @@
#include "ld_session.h"
static LDAP* last_ldap_handle = NULL;
static LDAPMessage* last_ldap_result_holder = NULL;
static LDAPMessage* last_ldap_result = NULL;
int get_connected_ldap_session(
@ -111,9 +112,10 @@ int get_connected_ldap_session(char* _lds_name, struct ld_session** _lds)
}
else
{
if (last_ldap_result != NULL)
if (last_ldap_result_holder != NULL)
{
ldap_msgfree(last_ldap_result);
ldap_msgfree(last_ldap_result_holder);
last_ldap_result_holder = NULL;
last_ldap_result = NULL;
}
ldap_disconnect(_lds_name);
@ -412,9 +414,10 @@ int lds_search(
/*
* free last_ldap_result
*/
if (last_ldap_result != NULL) {
ldap_msgfree(last_ldap_result);
last_ldap_result = NULL;
if (last_ldap_result_holder != NULL) {
ldap_msgfree(last_ldap_result_holder);
last_ldap_result_holder = NULL;
last_ldap_result = NULL;
}
@ -445,7 +448,7 @@ int lds_search(
NULL,
&lds->client_search_timeout,
0,
&last_ldap_result);
&last_ldap_result_holder);
#ifdef LDAP_PERF
gettimeofday(&after_search, NULL);
@ -458,10 +461,10 @@ int lds_search(
if (*_ld_error != LDAP_SUCCESS)
{
if (last_ldap_result != NULL)
if (last_ldap_result_holder != NULL)
{
ldap_msgfree(last_ldap_result);
last_ldap_result = NULL;
ldap_msgfree(last_ldap_result_holder);
last_ldap_result_holder = NULL;
}
if (LDAP_API_ERROR(*_ld_error))
@ -476,13 +479,15 @@ int lds_search(
}
last_ldap_handle = lds->handle;
*_ld_result_count = ldap_count_entries(lds->handle, last_ldap_result);
*_ld_result_count = ldap_count_entries(lds->handle, last_ldap_result_holder);
if (*_ld_result_count < 0)
{
LM_DBG("[%s]: ldap_count_entries failed\n", _lds_name);
return -1;
}
last_ldap_result = last_ldap_result_holder;
return 0;
}

@ -46,12 +46,12 @@ int pv_parse_msrp_name(pv_spec_t *sp, str *in)
switch(in->len)
{
case 3:
case 3:
if(strncmp(in->s, "buf", 3)==0)
sp->pvp.pvn.u.isname.name.n = 1;
else goto error;
break;
case 4:
case 4:
if(strncmp(in->s, "body", 4)==0)
sp->pvp.pvn.u.isname.name.n = 2;
else if(strncmp(in->s, "code", 4)==0)
@ -66,6 +66,7 @@ int pv_parse_msrp_name(pv_spec_t *sp, str *in)
else if(strncmp(in->s, "conid", 5)==0)
sp->pvp.pvn.u.isname.name.n = 21;
else goto error;
break;
case 6:
if(strncmp(in->s, "method", 6)==0)
sp->pvp.pvn.u.isname.name.n = 6;
@ -79,7 +80,7 @@ int pv_parse_msrp_name(pv_spec_t *sp, str *in)
sp->pvp.pvn.u.isname.name.n = 12;
else goto error;
break;
case 7:
case 7:
if(strncmp(in->s, "bodylen", 7)==0)
sp->pvp.pvn.u.isname.name.n = 10;
else if(strncmp(in->s, "transid", 7)==0)
@ -96,7 +97,7 @@ int pv_parse_msrp_name(pv_spec_t *sp, str *in)
sp->pvp.pvn.u.isname.name.n = 20;
else goto error;
break;
case 8:
case 8:
if(strncmp(in->s, "firsthop", 8)==0)
sp->pvp.pvn.u.isname.name.n = 16;
else if(strncmp(in->s, "prevhops", 8)==0)

@ -52,7 +52,9 @@ extern int _mt_allow_duplicates;
static m_tree_t **_ptree = NULL;
/* quick transaltion table */
unsigned char _mt_char_table[256];
#define MT_CHAR_TABLE_SIZE 256
#define MT_CHAR_TABLE_NOTSET 255
unsigned char _mt_char_table[MT_CHAR_TABLE_SIZE];
/**
*
@ -60,10 +62,17 @@ unsigned char _mt_char_table[256];
void mt_char_table_init(void)
{
unsigned int i;
for(i=0; i<=255; i++)
_mt_char_table[i] = 255;
for(i=0; i<mt_char_list.len; i++)
for(i=0; i<MT_CHAR_TABLE_SIZE; i++) {
_mt_char_table[i] = MT_CHAR_TABLE_NOTSET;
}
for(i=0; i<mt_char_list.len; i++) {
if((unsigned int)mt_char_list.s[i]>=MT_CHAR_TABLE_SIZE) {
LM_ERR("char at position %u in [%.*s] is out of range - skipping\n",
i, mt_char_list.len, mt_char_list.s);
continue;
}
_mt_char_table[(unsigned int)mt_char_list.s[i]] = (unsigned char)i;
}
}
@ -232,7 +241,12 @@ int mt_add_to_tree(m_tree_t *pt, str *sp, str *svalue)
}
itn0 = pt->head;
if(_mt_char_table[(unsigned int)sp->s[l]]==255)
if((unsigned int)sp->s[l]>=MT_CHAR_TABLE_SIZE) {
LM_ERR("invalid range for char %d in prefix [%c (0x%x)]\n",
l, sp->s[l], sp->s[l]);
return -1;
}
if(_mt_char_table[(unsigned int)sp->s[l]]==MT_CHAR_TABLE_NOTSET)
{
LM_ERR("invalid char %d in prefix [%c (0x%x)]\n",
l, sp->s[l], sp->s[l]);
@ -256,7 +270,13 @@ int mt_add_to_tree(m_tree_t *pt, str *sp, str *svalue)
itn0[_mt_char_table[(unsigned int)sp->s[l]]].child = itn;
}
l++;
if(_mt_char_table[(unsigned int)sp->s[l]]==255)
if((unsigned int)sp->s[l]>=MT_CHAR_TABLE_SIZE) {
LM_ERR("invalid range for char %d in prefix [%c (0x%x)]\n",
l, sp->s[l], sp->s[l]);
return -1;
}
if(_mt_char_table[(unsigned int)sp->s[l]]==MT_CHAR_TABLE_NOTSET)
{
LM_ERR("invalid char %d in prefix [%c (0x%x)]\n",
l, sp->s[l], sp->s[l]);
@ -362,8 +382,14 @@ is_t* mt_get_tvalue(m_tree_t *pt, str *tomatch, int *len)
while(itn!=NULL && l < tomatch->len && l < MT_MAX_DEPTH)
{
/* check range */
if((unsigned int)tomatch->s[l]>=MT_CHAR_TABLE_SIZE) {
LM_DBG("out of range char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);
return NULL;
}
/* check validity */
if(_mt_char_table[(unsigned int)tomatch->s[l]]==255)
if(_mt_char_table[(unsigned int)tomatch->s[l]]==MT_CHAR_TABLE_NOTSET)
{
LM_DBG("not matching char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);
@ -409,8 +435,14 @@ int mt_add_tvalues(struct sip_msg *msg, m_tree_t *pt, str *tomatch)
itn = pt->head;
while (itn != NULL && l < tomatch->len && l < MT_MAX_DEPTH) {
/* check range */
if((unsigned int)tomatch->s[l]>=MT_CHAR_TABLE_SIZE) {
LM_DBG("out of range char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);
return -1;
}
/* check validity */
if(_mt_char_table[(unsigned int)tomatch->s[l]]==255) {
if(_mt_char_table[(unsigned int)tomatch->s[l]]==MT_CHAR_TABLE_NOTSET) {
LM_ERR("invalid char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);
return -1;
@ -518,8 +550,14 @@ int mt_match_prefix(struct sip_msg *msg, m_tree_t *it,
while(itn!=NULL && l < tomatch->len && l < MT_MAX_DEPTH)
{
/* check range */
if((unsigned int)tomatch->s[l]>=MT_CHAR_TABLE_SIZE) {
LM_DBG("out of range char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);
return -1;
}
/* check validity */
if(_mt_char_table[(unsigned int)tomatch->s[l]]==255)
if(_mt_char_table[(unsigned int)tomatch->s[l]]==MT_CHAR_TABLE_NOTSET)
{
LM_ERR("invalid char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);
@ -1162,8 +1200,14 @@ int mt_rpc_add_tvalues(rpc_t* rpc, void* ctx, m_tree_t *pt, str *tomatch)
itn = pt->head;
while (itn != NULL && l < tomatch->len && l < MT_MAX_DEPTH) {
/* check range */
if((unsigned int)tomatch->s[l]>=MT_CHAR_TABLE_SIZE) {
LM_DBG("out of range char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);
return -1;
}
/* check validity */
if(_mt_char_table[(unsigned int)tomatch->s[l]]==255) {
if(_mt_char_table[(unsigned int)tomatch->s[l]]==MT_CHAR_TABLE_NOTSET) {
LM_ERR("invalid char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);
return -1;
@ -1272,8 +1316,14 @@ int mt_rpc_match_prefix(rpc_t* rpc, void* ctx, m_tree_t *it,
while(itn!=NULL && l < tomatch->len && l < MT_MAX_DEPTH)
{
/* check range */
if((unsigned int)tomatch->s[l]>=MT_CHAR_TABLE_SIZE) {
LM_DBG("out of range char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);
return -1;
}
/* check validity */
if(_mt_char_table[(unsigned int)tomatch->s[l]]==255)
if(_mt_char_table[(unsigned int)tomatch->s[l]]==MT_CHAR_TABLE_NOTSET)
{
LM_ERR("invalid char at %d in [%.*s]\n",
l, tomatch->len, tomatch->s);

@ -1632,7 +1632,8 @@ save_keepalive_state(void)
f = fopen(keepalive_state_file, "w");
if (!f) {
LM_ERR("failed to open keepalive state file for writing: %s\n", strerror(errno));
LM_ERR("failed to open keepalive state file (%s) for writing: %s\n",
keepalive_state_file, strerror(errno));
return;
}
@ -1651,7 +1652,8 @@ save_keepalive_state(void)
}
if (ferror(f))
LM_ERR("couldn't write keepalive state file: %s\n", strerror(errno));
LM_ERR("couldn't write keepalive state file (%s): %s\n",
keepalive_state_file, strerror(errno));
fclose(f);
}

@ -819,10 +819,10 @@ int db_update_ucontact_ruid(ucontact_t* _c)
vals2[n2].val.str_val = _c->c;
n2++;
keys2[n2] = &callid_col;
vals2[n2].type = DB1_STR;
keys2[n2] = &expires_col;
vals2[n2].type = DB1_DATETIME;
vals2[n2].nul = 0;
vals2[n2].val.str_val = _c->callid;
vals2[n2].val.time_val = _c->expires;
n2++;
keys2[n2] = &q_col;

@ -21,7 +21,7 @@ Richard Fuchs
1. Overview
1.1. Path insertion for registrations
1.1. Path Insertion For Registrations
1.2. Outbound routing to NAT'ed UACs
2. Dependencies
@ -44,13 +44,14 @@ Richard Fuchs
List of Examples
1.1. Set use_received parameter
1.2. add_path usage
1.3. add_path(user) usage
1.4. add_path(user, parameters) usage
1.5. add_path_received() usage
1.6. add_path_received(user) usage
1.7. add_path_received(user, parameters) usage
1.1. Add Supported header
1.2. Set use_received parameter
1.3. add_path usage
1.4. add_path(user) usage
1.5. add_path(user, parameters) usage
1.6. add_path_received() usage
1.7. add_path_received(user) usage
1.8. add_path_received(user, parameters) usage
Chapter 1. Admin Guide
@ -58,7 +59,7 @@ Chapter 1. Admin Guide
1. Overview
1.1. Path insertion for registrations
1.1. Path Insertion For Registrations
1.2. Outbound routing to NAT'ed UACs
2. Dependencies
@ -81,7 +82,7 @@ Chapter 1. Admin Guide
1. Overview
1.1. Path insertion for registrations
1.1. Path Insertion For Registrations
1.2. Outbound routing to NAT'ed UACs
This module is designed to be used at intermediate sip proxies like
@ -91,7 +92,7 @@ Chapter 1. Admin Guide
mechanism for evaluating this parameter in subsequent requests and to
set the destination URI according to it.
1.1. Path insertion for registrations
1.1. Path Insertion For Registrations
For registrations in a scenario like “[UAC] -> [P1] -> [REG]”, the
"path" module can be used at the intermediate proxy P1 to insert a Path
@ -110,6 +111,15 @@ Chapter 1. Admin Guide
If the function is called with a username, it's included in the
Path URI too.
Note that some SIP registrars may check if header Supported includes
'path'. It can be added in Kamailio.cfg using append_hf() from textops
module.
Example 1.1. Add Supported header
...
append_hf("Supported: path\r\n");
...
1.2. Outbound routing to NAT'ed UACs
If the NAT'ed address of an UAC is passed to the registrar, the
@ -152,7 +162,7 @@ Chapter 1. Admin Guide
Default value is 0.
Example 1.1. Set use_received parameter
Example 1.2. Set use_received parameter
...
modparam("path", "use_received", 1)
...
@ -181,7 +191,7 @@ modparam("path", "use_received", 1)
This function can be used from REQUEST_ROUTE.
Example 1.2. add_path usage
Example 1.3. add_path usage
...
if (!add_path()) {
sl_send_reply("503", "Internal Path Error");
@ -199,7 +209,7 @@ if (!add_path()) {
This function can be used from REQUEST_ROUTE.
Example 1.3. add_path(user) usage
Example 1.4. add_path(user) usage
...
if (!add_path("loadbalancer")) {
sl_send_reply("503", "Internal Path Error");
@ -221,7 +231,7 @@ if (!add_path("loadbalancer")) {
This function can be used from REQUEST_ROUTE.
Example 1.4. add_path(user, parameters) usage
Example 1.5. add_path(user, parameters) usage
...
if (!add_path("loadbalancer", "ob")) {
sl_send_reply("503", "Internal Path Error");
@ -238,7 +248,7 @@ if (!add_path("loadbalancer", "ob")) {
This function can be used from REQUEST_ROUTE.
Example 1.5. add_path_received() usage
Example 1.6. add_path_received() usage
...
if (!add_path_received()) {
sl_send_reply("503", "Internal Path Error");
@ -255,7 +265,7 @@ if (!add_path_received()) {
This function can be used from REQUEST_ROUTE.
Example 1.6. add_path_received(user) usage
Example 1.7. add_path_received(user) usage
...
if (!add_path_received("inbound")) {
sl_send_reply("503", "Internal Path Error");
@ -272,7 +282,7 @@ if (!add_path_received("inbound")) {
This function can be used from REQUEST_ROUTE.
Example 1.7. add_path_received(user, parameters) usage
Example 1.8. add_path_received(user, parameters) usage
...
if (!add_path_received("inbound", "ob")) {
sl_send_reply("503", "Internal Path Error");

@ -10,9 +10,9 @@
<!-- Module User's Guide -->
<chapter>
<title>&adminguide;</title>
<section>
<title>Overview</title>
<para>
@ -22,9 +22,9 @@
for evaluating this parameter in subsequent requests and to set the destination &uri; according to it.
</para>
<section>
<title>Path insertion for registrations</title>
<title>Path Insertion For Registrations</title>
<para>
For registrations in a scenario like <quote>[UAC] -> [P1] -> [REG]</quote>,
For registrations in a scenario like <quote>[UAC] -> [P1] -> [REG]</quote>,
the "path" module can be used at the intermediate proxy P1 to insert a Path
header into the message before forwarding it to the registrar REG. Two functions
can be used to achieve this:
@ -46,7 +46,7 @@
<para>
<emphasis>add_path_received(...)</emphasis> also add a Path header in the
same form as above, but also adds a parameter indicating the received-&uri;
of the message, like
of the message, like
<quote>Path: &lt;sip:1.2.3.4;received=sip:2.3.4.5:1234;lr&gt;</quote>. This
is especially useful if the proxy does NAT detection and wants to pass
the NAT'ed address to the registrar.
@ -58,7 +58,17 @@
</itemizedlist>
</para>
<para>
Note that some SIP registrars may check if header Supported includes 'path'. It
can be added in &kamailio;.cfg using append_hf() from textops module.
</para>
<example>
<title>Add Supported header</title>
<programlisting format="linespecific">
...
append_hf("Supported: path\r\n");
...
</programlisting>
</example>
</section>
<section>
<title>Outbound routing to NAT'ed UACs</title>

@ -369,7 +369,7 @@ kamcmd cfg.set_now_string pipelimit reply_reason "Limiting"
ratelimit module for details on each algorithm.
* limit - the integer or pseudovariable with the limit value.
This function can be used from REQUEST_ROUTE.
This function can be used from ANY_ROUTE.
Example 1.12. pl_check usage
...
@ -437,7 +437,8 @@ with unexpected retcode=$var(check_result)\n");
* min - the minimum value of "Retry-After" header.
* max - the maximum value of "Retry-After" header.
This function can be used from REQUEST_ROUTE.
This function can be used from
REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE.
Example 1.13. pl_drop usage
...

@ -376,7 +376,7 @@ modparam("pipelimit", "reply_reason", "Limiting")
</para></listitem>
</itemizedlist>
<para>
This function can be used from REQUEST_ROUTE.
This function can be used from ANY_ROUTE.
</para>
<example>
<title><function>pl_check</function> usage</title>
@ -461,7 +461,7 @@ with unexpected retcode=$var(check_result)\n");
</listitem>
</itemizedlist>
<para>
This function can be used from REQUEST_ROUTE.
This function can be used from REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE.
</para>
<example>
<title><function>pl_drop</function> usage</title>

@ -122,15 +122,15 @@ static int fixup_pl_check3(void** param, int param_no);
static cmd_export_t cmds[]={
{"pl_check", (cmd_function)w_pl_check, 1, fixup_spve_null,
0, REQUEST_ROUTE|CORE_ONREPLY_ROUTE},
0, ANY_ROUTE},
{"pl_check", (cmd_function)w_pl_check3, 3, fixup_pl_check3,
0, REQUEST_ROUTE|CORE_ONREPLY_ROUTE},
0, ANY_ROUTE},
{"pl_drop", (cmd_function)w_pl_drop_default, 0, 0,
0, REQUEST_ROUTE},
0, REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
{"pl_drop", (cmd_function)w_pl_drop_forced, 1, fixup_uint_null,
0, REQUEST_ROUTE},
0, REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
{"pl_drop", (cmd_function)w_pl_drop, 2, fixup_uint_uint,
0, REQUEST_ROUTE},
0, REQUEST_ROUTE|BRANCH_ROUTE|FAILURE_ROUTE|ONSEND_ROUTE},
{0,0,0,0,0,0}
};
static param_export_t params[]={
@ -237,6 +237,7 @@ static int get_cpuload(double * load)
if (fscanf(f, "cpu %lld%lld%lld%lld%lld%lld%lld%lld",
&n_user, &n_nice, &n_sys, &n_idle, &n_iow, &n_irq, &n_sirq, &n_stl) < 0) {
LM_ERR("could not parse load information\n");
fclose(f);
return -1;
}
fclose(f);

@ -982,9 +982,8 @@ dlg_t* ps_build_dlg_t(subs_t* subs)
pkg_free(tmp);
goto error;
}
td->send_sock = grep_sock_info (&host, (unsigned short) port, (unsigned short) proto);
pkg_free(tmp);
td->send_sock = grep_sock_info (
&host, (unsigned short) port, (unsigned short) proto);
}
return td;
@ -1349,15 +1348,6 @@ int publ_notify_notifier(str pres_uri, pres_ev_t *event)
result_cols[r_to_tag_col=n_result_cols++] = &str_to_tag_col;
result_cols[r_from_tag_col=n_result_cols++] = &str_from_tag_col;
if (pa_dbf.start_transaction)
{
if (pa_dbf.start_transaction(pa_db, db_table_lock) < 0)
{
LM_ERR("in start_transaction\n");
goto error;
}
}
if(query_fn(pa_db, query_cols, 0, query_vals, result_cols,
n_query_cols, n_result_cols, 0, &result )< 0)
{
@ -1386,26 +1376,11 @@ int publ_notify_notifier(str pres_uri, pres_ev_t *event)
set_updated(&subs);
}
if (pa_dbf.end_transaction)
{
if (pa_dbf.end_transaction(pa_db) < 0)
{
LM_ERR("in end_transaction\n");
goto error;
}
}
ret = RES_ROW_N(result);
error:
if (result) pa_dbf.free_result(pa_db, result);
if (pa_dbf.abort_transaction)
{
if (pa_dbf.abort_transaction(pa_db) < 0)
LM_ERR("in abort_transaction\n");
}
return ret;
}

@ -1564,15 +1564,6 @@ int mark_presentity_for_delete(presentity_t *pres)
result_cols[0] = &str_body_col;
if (pa_dbf.start_transaction)
{
if (pa_dbf.start_transaction(pa_db, db_table_lock) < 0)
{
LM_ERR("in start_transaction\n");
goto error;
}
}
if (query_fn(pa_db, query_cols, 0, query_vals, result_cols,
n_query_cols, 1, 0, &result) < 0)
{
@ -1653,15 +1644,6 @@ int mark_presentity_for_delete(presentity_t *pres)
goto error;
}
if (pa_dbf.end_transaction)
{
if (pa_dbf.end_transaction(pa_db) < 0)
{
LM_ERR("in end_transaction\n");
goto error;
}
}
if (pa_dbf.affected_rows)
ret = pa_dbf.affected_rows(pa_db);
else
@ -1673,12 +1655,6 @@ error:
if (cur_body) pkg_free(cur_body);
if (result) pa_dbf.free_result(pa_db, result);
if (pa_dbf.abort_transaction)
{
if (pa_dbf.abort_transaction(pa_db) < 0)
LM_ERR("in abort_transaction\n");
}
return ret;
}

@ -156,9 +156,22 @@ void msg_presentity_clean(unsigned int ticks,void *param)
if (pres_notifier_processes > 0)
{
if (pa_dbf.start_transaction)
{
if (pa_dbf.start_transaction(pa_db, db_table_lock) < 0)
{
LM_ERR("in start_transaction\n");
goto error;
}
}
if ((num_watchers = publ_notify_notifier(uri, pres.event)) < 0)
{
LM_ERR("Updating watcher records\n");
if (pa_dbf.abort_transaction)
{
if (pa_dbf.abort_transaction(pa_db) < 0)
LM_ERR("in abort_transaction\n");
}
goto error;
}
@ -167,6 +180,11 @@ void msg_presentity_clean(unsigned int ticks,void *param)
if (mark_presentity_for_delete(&pres) < 0)
{
LM_ERR("Marking presentity\n");
if (pa_dbf.abort_transaction)
{
if (pa_dbf.abort_transaction(pa_db) < 0)
LM_ERR("in abort_transaction\n");
}
goto error;
}
}
@ -178,6 +196,14 @@ void msg_presentity_clean(unsigned int ticks,void *param)
goto error;
}
}
if (pa_dbf.end_transaction)
{
if (pa_dbf.end_transaction(pa_db) < 0)
{
LM_ERR("in end_transaction\n");
goto error;
}
}
}
else
{

@ -77,7 +77,7 @@ static inline int uandd_to_uri(str user, str domain, str *out)
memcpy(out->s + out->len, domain.s, domain.len);
out->len += domain.len;
out->s[out->len] = '\0';
return 0;
}
@ -88,6 +88,7 @@ static inline int ps_fill_local_contact(struct sip_msg* msg, str *contact)
int port;
int len;
int plen;
char *p;
contact->s= (char*)pkg_malloc(LCONTACT_BUF_SIZE);
if(contact->s== NULL)
@ -98,22 +99,22 @@ static inline int ps_fill_local_contact(struct sip_msg* msg, str *contact)
memset(contact->s, 0, LCONTACT_BUF_SIZE);
contact->len= 0;
plen = 3;
if(msg->rcv.proto== PROTO_NONE || msg->rcv.proto==PROTO_UDP)
proto= "udp";
else
if(msg->rcv.proto== PROTO_TLS )
proto= "tls";
else
else
if(msg->rcv.proto== PROTO_TCP)
proto= "tcp";
else
else
if(msg->rcv.proto== PROTO_SCTP) {
proto= "sctp";
plen = 4;
}
else
else
if(msg->rcv.proto== PROTO_WS || msg->rcv.proto== PROTO_WSS) {
proto= "ws";
plen = 2;
@ -122,8 +123,8 @@ static inline int ps_fill_local_contact(struct sip_msg* msg, str *contact)
{
LM_ERR("unsupported proto\n");
goto error;
}
}
if(msg->rcv.bind_address->useinfo.name.len>0) {
ip = msg->rcv.bind_address->useinfo.name;
} else {
@ -135,30 +136,41 @@ static inline int ps_fill_local_contact(struct sip_msg* msg, str *contact)
} else {
port = msg->rcv.bind_address->port_no;
}
if(strncmp(ip.s, "sip:", 4)!=0)
{
strncpy(contact->s, "sip:", 4);
contact->len+= 4;
}
strncpy(contact->s+contact->len, ip.s, ip.len);
p = contact->s;
if(strncmp(ip.s, "sip:", 4)!=0) {
strncpy(p, "sip:", 4);
contact->len += 4;
p += 4;
}
if(msg->rcv.bind_address->address.af==AF_INET6) {
*p = '[';
contact->len += 1;
p += 1;
}
strncpy(p, ip.s, ip.len);
contact->len += ip.len;
if(contact->len> LCONTACT_BUF_SIZE - 21)
{
p += ip.len;
if(msg->rcv.bind_address->address.af==AF_INET6) {
*p = ']';
contact->len += 1;
p += 1;
}
if(contact->len > LCONTACT_BUF_SIZE - 21) {
LM_ERR("buffer overflow\n");
goto error;
}
len= sprintf(contact->s+contact->len, ":%d;transport=" , port);
if(len< 0)
{
}
len= sprintf(p, ":%d;transport=" , port);
if(len< 0) {
LM_ERR("unsuccessful sprintf\n");
goto error;
}
contact->len+= len;
strncpy(contact->s+ contact->len, proto, plen);
}
contact->len += len;
p += len;
strncpy(p, proto, plen);
contact->len += plen;
return 0;
error:
if(contact->s!=NULL)

@ -458,7 +458,7 @@ next_contact:
}
}
next_registration:
// if (ul_record) ul.release_urecord(ul_record);
if (ul_record) ul.release_urecord(ul_record);
/* Unlock the domain for this AOR: */
if (aor_key.len > 0)
ul.unlock_udomain(domain, &aor_key);

@ -223,7 +223,7 @@ void reginfo_usrloc_cb(ucontact_t* c, int type, void* param) {
publ_info_t publ;
str content_type;
udomain_t * domain;
urecord_t * record;
urecord_t * record = NULL;
int res;
str uri = {NULL, 0};
str user = {NULL, 0};
@ -332,6 +332,7 @@ error:
if(body->s) xmlFree(body->s);
pkg_free(body);
}
if(record) ul.release_urecord(record);
return;
}

@ -323,7 +323,7 @@ void ul_publish(ucontact_t* c, int type, void* param)
print_publ(publ);
if((error=_pu_pua.send_publish(publ))< 0)
{
LM_ERR("while sending publish for ul event %d\n", type);
LM_ERR("failed sending publish for ul event %d\n", type);
if((type & UL_CONTACT_UPDATE) && error == ERR_PUBLISH_NO_BODY) {
/* This error can occur if Kamailio was restarted/stopped and for any reason couldn't store a pua
* entry in 'pua' DB table. It can also occur if 'pua' table is cleaned externally while Kamailio
@ -336,19 +336,16 @@ void ul_publish(ucontact_t* c, int type, void* param)
* previous one expires), but this is a minor issue. */
LM_ERR("UPDATE action generated a PUBLISH without body -> invoking INSERT action\n");
ul_publish(c, UL_CONTACT_INSERT, param);
return;
goto error;
}
}
pua_ul_publish= 0;
error:
pua_ul_publish = 0;
if(publ)
pkg_free(publ);
if(body)
{
if(body) {
if(body->s)
xmlFree(body->s);
pkg_free(body);
@ -356,7 +353,6 @@ error:
if(uri.s)
pkg_free(uri.s);
pua_ul_publish= 0;
return;

@ -49,8 +49,8 @@
#include "pv_trans.h"
static char _empty_str[] = "";
static str _tr_empty = { _empty_str, 0 };
static char _tr_empty_buf[2] = {0};
static str _tr_empty = { _tr_empty_buf, 0 };
static str _tr_uri = {0, 0};
static struct sip_uri _tr_parsed_uri;
static param_t* _tr_uri_params = NULL;
@ -1259,6 +1259,7 @@ int tr_eval_paramlist(struct sip_msg *msg, tr_param_t *tp, int subtype,
pv_value_t *val)
{
pv_value_t v;
pv_value_t vs;
str sv;
int n, i;
char separator = ';';
@ -1272,17 +1273,23 @@ int tr_eval_paramlist(struct sip_msg *msg, tr_param_t *tp, int subtype,
{
if (subtype == TR_PL_COUNT)
{
if(tp->type != TR_PARAM_STRING || tp->v.s.len != 1)
return -1;
separator = tp->v.s.s[0];
}
else if (tp->next != NULL)
{
if(tp->type != TR_PARAM_STRING) {
if(pv_get_spec_value(msg, (pv_spec_t*)tp->v.data, &vs)!=0
|| (!(vs.flags&PV_VAL_STR)) || vs.rs.len<=0)
{
LM_ERR("value cannot get p1\n");
return -1;
}
separator = vs.rs.s[0];
} else {
if(tp->v.s.len != 1)
return -1;
separator = tp->v.s.s[0];
}
} else if (tp->next != NULL) {
if(tp->next->type != TR_PARAM_STRING
|| tp->next->v.s.len != 1)
return -1;
separator = tp->next->v.s.s[0];
}
}
@ -2624,13 +2631,13 @@ char* tr_parse_paramlist(str* in, trans_t *t)
start_pos = ++p;
_tr_parse_sparam(p, p0, tp, spec, ps, in, s);
t->params = tp;
tp = 0;
if (p - start_pos != 1)
if (tp->type != TR_PARAM_SPEC && p - start_pos != 1)
{
LM_ERR("invalid separator in transformation: "
"%.*s\n", in->len, in->s);
goto error;
}
tp = 0;
while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++;
if(*p!=TR_RBRACKET)

@ -622,7 +622,7 @@ int xavp_params_explode(str *params, str *xname)
int pv_var_to_xavp(str *varname, str *xname)
{
script_var_t *it;
sr_xavp_t *xavp = NULL;
sr_xavp_t *avp = NULL;
sr_xval_t xval;
LM_DBG("xname:%.*s varname:%.*s\n", xname->len, xname->s,
@ -638,18 +638,29 @@ int pv_var_to_xavp(str *varname, str *xname)
{
xval.type = SR_XTYPE_INT;
xval.v.i = it->v.value.n;
LM_DBG("[%.*s]: %d\n", it->name.len, it->name.s, xval.v.i);
} else {
if(it->v.value.s.len==0) continue;
xval.type = SR_XTYPE_STR;
xval.v.s.s = it->v.value.s.s;
xval.v.s.len = it->v.value.s.len;
LM_DBG("[%.*s]: '%.*s'\n", it->name.len, it->name.s,
xval.v.s.len, xval.v.s.s);
}
xavp = xavp_add_xavp_value(xname, &it->name, &xval, NULL);
if(xavp==NULL) {
if(xavp_add_value(&it->name, &xval, &avp)==NULL) {
LM_ERR("can't copy [%.*s]\n", it->name.len, it->name.s);
goto error;
}
}
if(avp) {
memset(&xval, 0, sizeof(sr_xval_t));
xval.type = SR_XTYPE_XAVP;
xval.v.xavp = avp;
if(xavp_add_value(xname, &xval, NULL)==NULL) {
LM_ERR("Can't create xavp[%.*s]\n", xname->len, xname->s);
goto error;
}
}
}
else {
it = get_var_by_name(varname);
@ -662,21 +673,23 @@ int pv_var_to_xavp(str *varname, str *xname)
{
xval.type = SR_XTYPE_INT;
xval.v.i = it->v.value.n;
LM_DBG("[%.*s]: %d\n", it->name.len, it->name.s, xval.v.i);
} else {
xval.type = SR_XTYPE_STR;
xval.v.s.s = it->v.value.s.s;
xval.v.s.len = it->v.value.s.len;
LM_DBG("[%.*s]: '%.*s'\n", it->name.len, it->name.s,
xval.v.s.len, xval.v.s.s);
}
xavp = xavp_add_xavp_value(xname, &it->name, &xval, NULL);
if(xavp==NULL) {
if(xavp_add_xavp_value(xname, &it->name, &xval, NULL)==NULL) {
LM_ERR("can't copy [%.*s]\n", it->name.len, it->name.s);
goto error;
return -1;
}
}
return 1;
error:
xavp_rm_by_name(xname, 1, NULL);
if(avp) xavp_destroy_list(&avp);
return -1;
}
@ -691,7 +704,7 @@ int pv_xavp_to_var_helper(sr_xavp_t *avp) {
flags |= VAR_VAL_STR;
value.s.len = avp->val.v.s.len;
value.s.s = avp->val.v.s.s;
LM_DBG("var:[%.*s] STR:[%.*s]\n", avp->name.len, avp->name.s,
LM_DBG("var:[%.*s] STR:[%.*s]\n", avp->name.len, avp->name.s,
value.s.len, value.s.s);
}
else if(avp->val.type==SR_XTYPE_INT) {
@ -723,18 +736,21 @@ int pv_xavp_to_var(str *xname) {
LM_ERR("%.*s not xavp type?\n", xname->len, xname->s);
return -1;
}
avp = xavp->val.v.xavp;
if (avp)
{
if(pv_xavp_to_var_helper(avp)<0) return -1;
avp = avp->next;
}
do {
avp = xavp->val.v.xavp;
if (avp)
{
if(pv_xavp_to_var_helper(avp)<0) return -1;
avp = avp->next;
}
while(avp)
{
if(pv_xavp_to_var_helper(avp)<0) return -1;
avp = avp->next;
}
while(avp)
{
if(pv_xavp_to_var_helper(avp)<0) return -1;
avp = avp->next;
}
xavp = xavp_get_next(xavp);
} while(xavp);
return 1;
}
#endif

@ -324,7 +324,6 @@ static int get_cpuload(double * load)
static int first_time = 1;
FILE * f = fopen("/proc/stat", "r");
double vload;
int ncpu;
static int errormsg = 0;
if (! f) {

@ -556,9 +556,10 @@ modparam("registrar", "sock_hdr_name", "Sock-Info")
3.17. method_filtering (integer)
Tells if the contact filtering based on supported methods should be
performed during lookup. It's enabled only if it has a non zero value.
Supported methods are listed in the “Allow:” header in the REGISTER
message and stored in the location database.
performed during lookup on initial requests without to-tag. It's
enabled only if it has a non zero value. Supported methods are listed
in the “Allow:” header in the REGISTER message and stored in the
location database.
Default value is 0 (disabled).
@ -846,9 +847,9 @@ save("location", "0x00", "sip:test@kamailio.org");
value and optionally the rest will be appended to the message
(depending on append_branches parameter value).
If the method_filtering option is enabled, the lookup function will
return only the contacts that support the method of the processed
request.
If the method_filtering option is enabled and request is initial
request without to-tag, the lookup function will return only the
contacts that support the method of the processed request.
Meaning of the parameters is as follows:
* domain - Name of table that should be used for the lookup.

@ -515,7 +515,8 @@ modparam("registrar", "sock_hdr_name", "Sock-Info")
<title><varname>method_filtering</varname> (integer)</title>
<para>
Tells if the contact filtering based on supported methods should be
performed during lookup. It's enabled only if it has a non zero
performed during lookup on initial requests without to-tag.
It's enabled only if it has a non zero
value. Supported methods are listed in the <quote>Allow:</quote>
header in the REGISTER message and stored in the location database.
</para>
@ -1032,8 +1033,9 @@ save("location", "0x00", "sip:test@kamailio.org");
the message (depending on append_branches parameter value).
</para>
<para>
If the <varname>method_filtering</varname> option is enabled,
the <function>lookup</function> function
If the <varname>method_filtering</varname> option is enabled and
request is initial request without to-tag, the
<function>lookup</function> function
will return only the contacts that support the method of the
processed request.
</para>

@ -45,9 +45,15 @@
#include "lookup.h"
#include "config.h"
#define allowed_method(_msg, _c) \
( !method_filtering || ((_msg)->REQ_METHOD)&((_c)->methods) )
static int has_to_tag(struct sip_msg* msg)
{
if (parse_to_header(msg) < 0) return 0;
return (get_to(msg)->tag_value.len > 0) ? 1 : 0;
}
#define allowed_method(_msg, _c) \
( !method_filtering || ((_msg)->REQ_METHOD)&((_c)->methods) || \
has_to_tag(_msg) )
/**
* compare two instances, by skipping '<' & '>'
@ -96,8 +102,9 @@ int lookup_to_dset(struct sip_msg* _m, udomain_t* _d, str* _uri) {
* add xavp with details of the record (ruid, ...)
*/
int xavp_rcd_helper(ucontact_t* ptr) {
sr_xavp_t *xavp=NULL;
sr_xavp_t **xavp=NULL;
sr_xavp_t *list=NULL;
sr_xavp_t *new_xavp=NULL;
str xname_ruid = {"ruid", 4};
str xname_received = { "received", 8};
str xname_contact = { "contact", 7};
@ -105,34 +112,34 @@ int xavp_rcd_helper(ucontact_t* ptr) {
if(ptr==NULL) return -1;
if(reg_xavp_rcd.s!=NULL)
{
list = xavp_get(&reg_xavp_rcd, NULL);
xavp = list;
memset(&xval, 0, sizeof(sr_xval_t));
xval.type = SR_XTYPE_STR;
xval.v.s = ptr->ruid;
xavp_add_value(&xname_ruid, &xval, &xavp);
if(ptr->received.len > 0)
{
memset(&xval, 0, sizeof(sr_xval_t));
xval.type = SR_XTYPE_STR;
xval.v.s = ptr->received;
xavp_add_value(&xname_received, &xval, &xavp);
}
if(reg_xavp_rcd.s==NULL || reg_xavp_rcd.len<=0) return 0;
list = xavp_get(&reg_xavp_rcd, NULL);
xavp = list ? &list->val.v.xavp : &new_xavp;
memset(&xval, 0, sizeof(sr_xval_t));
xval.type = SR_XTYPE_STR;
xval.v.s = ptr->ruid;
xavp_add_value(&xname_ruid, &xval, xavp);
if(ptr->received.len > 0) {
memset(&xval, 0, sizeof(sr_xval_t));
xval.type = SR_XTYPE_STR;
xval.v.s = ptr->c;
xavp_add_value(&xname_contact, &xval, &xavp);
if(list==NULL)
{
/* no reg_xavp_rcd xavp in root list - add it */
xval.type = SR_XTYPE_XAVP;
xval.v.xavp = xavp;
xavp_add_value(&reg_xavp_rcd, &xval, NULL);
xval.v.s = ptr->received;
xavp_add_value(&xname_received, &xval, xavp);
}
memset(&xval, 0, sizeof(sr_xval_t));
xval.type = SR_XTYPE_STR;
xval.v.s = ptr->c;
xavp_add_value(&xname_contact, &xval, xavp);
if(list==NULL) {
/* no reg_xavp_rcd xavp in root list - add it */
xval.type = SR_XTYPE_XAVP;
xval.v.xavp = *xavp;
if(xavp_add_value(&reg_xavp_rcd, &xval, NULL)==NULL) {
LM_ERR("cannot add ruid xavp to root list\n");
xavp_destroy_list(xavp);
}
}
return 0;

@ -173,8 +173,9 @@ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host)
unsigned int ahash;
unsigned short digit;
int mode;
sr_xavp_t *xavp=NULL;
sr_xavp_t **xavp=NULL;
sr_xavp_t *list=NULL;
sr_xavp_t *new_xavp=NULL;
str xname = {"ruid", 4};
sr_xval_t xval;
@ -212,7 +213,7 @@ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host)
if(reg_xavp_rcd.s!=NULL)
{
list = xavp_get(&reg_xavp_rcd, NULL);
xavp = list;
xavp = list ? &list->val.v.xavp : &new_xavp;
}
fl = 0;
@ -334,7 +335,7 @@ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host)
memset(&xval, 0, sizeof(sr_xval_t));
xval.type = SR_XTYPE_STR;
xval.v.s = c->ruid;
if(xavp_add_value(&xname, &xval, &xavp)==NULL) {
if(xavp_add_value(&xname, &xval, xavp)==NULL) {
LM_ERR("cannot add ruid value to xavp\n");
}
}
@ -346,14 +347,13 @@ int build_contact(sip_msg_t *msg, ucontact_t* c, str *host)
/* add xavp with details of the record (ruid, ...) */
if(reg_xavp_rcd.s!=NULL)
{
if(list==NULL && xavp!=NULL)
if(list==NULL && *xavp!=NULL)
{
/* no reg_xavp_rcd xavp in root list - add it */
xval.type = SR_XTYPE_XAVP;
xval.v.xavp = xavp;
xval.v.xavp = *xavp;
if(xavp_add_value(&reg_xavp_rcd, &xval, NULL)==NULL) {
LM_ERR("cannot add ruid xavp to root list\n");
xavp_destroy_list(&xavp);
xavp_destroy_list(xavp);
}
}
}

@ -520,7 +520,7 @@ static inline int process_outbound(struct sip_msg *_m, str flow_token)
return -1;
} else if (!ip_addr_cmp(&rcv->src_ip, &_m->rcv.src_ip)
|| rcv->src_port != _m->rcv.src_port) {
LM_DBG("\"incoming\" request found. Using flow-token for"
LM_DBG("\"incoming\" request found. Using flow-token for "
"routing\n");
/* First, force the local socket */

@ -121,7 +121,7 @@ modparam("rtimer", "timer", "name=ta;interval=10;mode=1;")
modparam("rtimer", "exec", "timer=ta;route=8")
route[8] {
xlog("timer routine: time is %TF\n");
xlog("timer routine: time is $TF\n");
# delete from my sql cache table entries older than 2H
sql_query("delete from kamailio_cache where last_updated<$TS-3600");
}

@ -152,7 +152,7 @@ modparam("rtimer", "timer", "name=ta;interval=10;mode=1;")
modparam("rtimer", "exec", "timer=ta;route=8")
route[8] {
xlog("timer routine: time is %TF\n");
xlog("timer routine: time is $TF\n");
# delete from my sql cache table entries older than 2H
sql_query("delete from kamailio_cache where last_updated&lt;$TS-3600");
}

@ -194,7 +194,7 @@ static struct rtpp_node *select_rtpp_node_new(str, str, int, struct rtpp_node **
static struct rtpp_node *select_rtpp_node_old(str, str, int, enum rtpe_operation);
static struct rtpp_node *select_rtpp_node(str, str, int, struct rtpp_node **, int, enum rtpe_operation);
static int is_queried_node(struct rtpp_node *, struct rtpp_node **, int);
static int build_rtpp_socks(unsigned int current_rtpp_no);
static int build_rtpp_socks();
static char *send_rtpp_command(struct rtpp_node *, bencode_item_t *, int *);
static int get_extra_id(struct sip_msg* msg, str *id_str);
@ -1068,6 +1068,9 @@ static struct mi_root* mi_enable_rtp_proxy(struct mi_root *cmd_tree, void *param
str rtpp_url;
str snode, sattr, svalue;
if (build_rtpp_socks())
return init_mi_tree(400, MI_DB_ERR, MI_DB_ERR_LEN);
found = MI_FOUND_NONE;
found_rtpp_disabled = 0;
found_rtpp = NULL;
@ -1412,6 +1415,9 @@ static struct mi_root* mi_ping_rtp_proxy(struct mi_root* cmd_tree, void* param)
str rtpp_url;
str snode, sattr, svalue;
if (build_rtpp_socks())
return init_mi_tree(400, MI_DB_ERR, MI_DB_ERR_LEN);
found = 0;
found_rtpp_disabled = 0;
found_rtpp = NULL;
@ -1576,7 +1582,6 @@ static struct mi_root*
mi_reload_rtp_proxy(struct mi_root* cmd_tree, void* param)
{
struct mi_root *root = NULL;
unsigned int current_rtpp_no;
if (rtpp_db_url.s == NULL) {
// no database
@ -1594,13 +1599,7 @@ mi_reload_rtp_proxy(struct mi_root* cmd_tree, void* param)
return 0;
}
} else {
lock_get(rtpp_no_lock);
current_rtpp_no = *rtpp_no;
lock_release(rtpp_no_lock);
if (rtpp_socks_size != current_rtpp_no) {
build_rtpp_socks(current_rtpp_no);
}
build_rtpp_socks();
// success reloading from database
root = init_mi_tree(200, MI_DB_OK, MI_DB_OK_LEN);
@ -1795,16 +1794,24 @@ mod_init(void)
return 0;
}
static int build_rtpp_socks(unsigned int current_rtpp_no) {
static int build_rtpp_socks() {
int n, i;
char *cp;
struct addrinfo hints, *res;
struct rtpp_set *rtpp_list;
struct rtpp_node *pnode;
unsigned int current_rtpp_no;
#ifdef IP_MTU_DISCOVER
int ip_mtu_discover = IP_PMTUDISC_DONT;
#endif
lock_get(rtpp_no_lock);
current_rtpp_no = *rtpp_no;
lock_release(rtpp_no_lock);
if (current_rtpp_no == rtpp_socks_size)
return 0;
// close current sockets
for (i = 0; i < rtpp_socks_size; i++) {
if (rtpp_socks[i] >= 0) {
@ -1920,16 +1927,6 @@ child_init(int rank)
mypid = getpid();
lock_get(rtpp_no_lock);
rtpp_socks_size = *rtpp_no;
lock_release(rtpp_no_lock);
rtpp_socks = (int*)pkg_malloc(sizeof(int)*(rtpp_socks_size));
if (!rtpp_socks) {
return -1;
}
memset(rtpp_socks, -1, sizeof(int)*(rtpp_socks_size));
// vector of pointers to queried nodes
queried_nodes_ptr = (struct rtpp_node**)pkg_malloc(queried_nodes_limit * sizeof(struct rtpp_node*));
if (!queried_nodes_ptr) {
@ -1939,9 +1936,8 @@ child_init(int rank)
memset(queried_nodes_ptr, 0, queried_nodes_limit * sizeof(struct rtpp_node*));
/* Iterate known RTP proxies - create sockets */
if (rtpp_socks_size) {
build_rtpp_socks(rtpp_socks_size);
}
if (build_rtpp_socks())
return -1;
return 0;
}
@ -2844,15 +2840,8 @@ static struct rtpp_node *
select_rtpp_node(str callid, str viabranch, int do_test, struct rtpp_node **queried_nodes_ptr, int queried_nodes, enum rtpe_operation op)
{
struct rtpp_node *node = NULL;
unsigned int current_rtpp_no;
lock_get(rtpp_no_lock);
current_rtpp_no = *rtpp_no;
lock_release(rtpp_no_lock);
if (rtpp_socks_size != current_rtpp_no) {
build_rtpp_socks(current_rtpp_no);
}
build_rtpp_socks();
if (!active_rtpp_set) {
default_rtpp_set = select_rtpp_set(setid_default);

@ -75,8 +75,8 @@ Carsten Bock
5.7. rtpproxy_stream2uac(prompt_name, count),
5.8. rtpproxy_stream2uas(prompt_name, count)
5.9. rtpproxy_stop_stream2uac(),
5.10. start_recording()
5.11. rtpproxy_stop_stream2uas(prompt_name, count)
5.10. rtpproxy_stop_stream2uas()
5.11. start_recording()
6. Exported Pseudo Variables
@ -109,10 +109,11 @@ Carsten Bock
1.16. rtpproxy_destroy usage
1.17. rtpproxy_manage usage
1.18. rtpproxy_stream2xxx usage
1.19. start_recording usage
1.20. $rtpstat-Usage
1.21. nh_enable_rtpp usage
1.22. nh_show_rtpp usage
1.19. rtpproxy_stop_stream2uas usage
1.20. start_recording usage
1.21. $rtpstat-Usage
1.22. nh_enable_rtpp usage
1.23. nh_show_rtpp usage
Chapter 1. Admin Guide
@ -150,8 +151,8 @@ Chapter 1. Admin Guide
5.7. rtpproxy_stream2uac(prompt_name, count),
5.8. rtpproxy_stream2uas(prompt_name, count)
5.9. rtpproxy_stop_stream2uac(),
5.10. start_recording()
5.11. rtpproxy_stop_stream2uas(prompt_name, count)
5.10. rtpproxy_stop_stream2uas()
5.11. start_recording()
6. Exported Pseudo Variables
@ -415,8 +416,8 @@ xlog("L_INFO", "Chose rtpp instance $var(RTP_INSTANCE)\n");
5.7. rtpproxy_stream2uac(prompt_name, count),
5.8. rtpproxy_stream2uas(prompt_name, count)
5.9. rtpproxy_stop_stream2uac(),
5.10. start_recording()
5.11. rtpproxy_stop_stream2uas(prompt_name, count)
5.10. rtpproxy_stop_stream2uas()
5.11. start_recording()
5.1. set_rtp_proxy_set(setid)
@ -714,7 +715,23 @@ rtpproxy_manage();
These functions can be used from REQUEST_ROUTE, ONREPLY_ROUTE.
5.10. start_recording()
5.10. rtpproxy_stop_stream2uas()
See function rtpproxy_stop_stream2uac().
Example 1.19. rtpproxy_stop_stream2uas usage
...
if (is_method("INVITE")) {
rtpproxy_offer();
if (is_audio_on_hold()) {
rtpproxy_stream2uas("/var/rtpproxy/prompts/music_on_hold", "-1");
} else {
rtpproxy_stop_stream2uas();
};
};
...
5.11. start_recording()
This function will send a signal to the RTP-Proxy to record the RTP
stream on the RTP-Proxy. This function is only supported by Sippy
@ -722,15 +739,11 @@ rtpproxy_manage();
This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE.
Example 1.19. start_recording usage
Example 1.20. start_recording usage
...
start_recording();
...
5.11. rtpproxy_stop_stream2uas(prompt_name, count)
See function rtpproxy_stop_stream2uac(prompt_name, count).
6. Exported Pseudo Variables
6.1. $rtpstat
@ -742,7 +755,7 @@ start_recording();
packet-counters. The statistics must be retrieved before the session is
deleted (before unforce_rtpproxy()).
Example 1.20. $rtpstat-Usage
Example 1.21. $rtpstat-Usage
...
append_hf("X-RTP-Statistics: $rtpstat\r\n");
...
@ -765,7 +778,7 @@ start_recording();
NOTE: if a rtpproxy is defined multiple times (in the same or different
sets), all of its instances will be enabled/disabled.
Example 1.21. nh_enable_rtpp usage
Example 1.22. nh_enable_rtpp usage
...
$ kamctl fifo nh_enable_rtpp udp:192.168.2.133:8081 0
...
@ -777,7 +790,7 @@ $ kamctl fifo nh_enable_rtpp udp:192.168.2.133:8081 0
No parameter.
Example 1.22. nh_show_rtpp usage
Example 1.23. nh_show_rtpp usage
...
$ kamctl fifo nh_show_rtpp
...

@ -801,6 +801,29 @@ rtpproxy_manage();
These functions can be used from REQUEST_ROUTE, ONREPLY_ROUTE.
</para>
</section>
<section id="rtpproxy.f.rtpproxy_stop_stream2uas">
<title>
<function>rtpproxy_stop_stream2uas()</function>
</title>
<para>
See function <function>rtpproxy_stop_stream2uac()</function>.
</para>
<example>
<title><function>rtpproxy_stop_stream2uas</function> usage</title>
<programlisting>
...
if (is_method("INVITE")) {
rtpproxy_offer();
if (is_audio_on_hold()) {
rtpproxy_stream2uas("/var/rtpproxy/prompts/music_on_hold", "-1");
} else {
rtpproxy_stop_stream2uas();
};
};
...
</programlisting>
</example>
</section>
<section id="rtpproxy.f.start_recording">
<title>
<function moreinfo="none">start_recording()</function>
@ -822,15 +845,6 @@ start_recording();
</programlisting>
</example>
</section>
<section id="rtpproxy.f.rtpproxy_stop_stream2uas">
<title>
<function>rtpproxy_stop_stream2uas(prompt_name, count)</function>
</title>
<para>
See function <function>rtpproxy_stop_stream2uac(prompt_name, count)</function>.
</para>
</section>
</section>

@ -2536,7 +2536,7 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer, int forc
&ice_candidate_priority_val, 0)
== NULL) {
ice_candidate_priority_val.n = 2;
} else if ((ice_candidate_priority_val.n < 1) ||
} else if ((ice_candidate_priority_val.n < 0) ||
(ice_candidate_priority_val.n > 2)) {
LM_ERR("invalid ice candidate priority value %d\n",
ice_candidate_priority_val.n);

@ -724,6 +724,7 @@ int check_proxy_require(struct sip_msg* _msg) {
* freed when the message freed. Lets hope nobody needs to access
* this header again later on */
free_str_list(_msg->proxy_require->parsed);
_msg->proxy_require->parsed = NULL;
}
}
#ifdef EXTRA_DEBUG

@ -482,6 +482,11 @@ sca_rpc_release_appearance( rpc_t *rpc, void *ctx )
return;
}
if (app_idx <= 0) {
rpc->fault(ctx, 500, "appearance-index must be > 0");
return;
}
if (( ht = sca->appearances ) == NULL ) {
rpc->fault( ctx, 500, "No active appearances" );
return;

@ -290,6 +290,26 @@ if(sdp_with_active_media("video"))
Remove the streams that match on 'm=type ...' line. The parameter can
be static string or variable holding the media type.
Note: If this is executed on a request, the callee should reply without
the Media too. However, RFC 3264 mandates, that the reply should
contain the exact same number of "m=" lines as the request.
6 Generating the Answer
[...]
For each "m=" line in the offer, there MUST be a corresponding "m="
line in the answer. The answer MUST contain exactly the same number of
"m=" lines as the offer. This allows for streams to be matched up based
on their order. This implies that if the offer contained zero "m="
lines, the answer MUST contain zero "m=" lines.
--RFC 3264
So this may not work with all Endpoints, especially if they follow RFC
3264 precisely (e.g. JSSIP).
This function can be used from ANY_ROUTE.
Example 1.8. sdp_remove_media usage

@ -268,6 +268,31 @@ if(sdp_with_active_media("video"))
Remove the streams that match on 'm=type ...' line. The
parameter can be static string or variable holding the media type.
</para>
<para>
Note: If this is executed on a request, the callee should reply
without the Media too. However, RFC 3264 mandates, that the reply
should contain the exact same number of "m=" lines as the
request.
</para>
<blockquote><attribution>RFC 3264</attribution>
<para>
6 Generating the Answer
</para>
<para>
[...]
</para>
<para>
For each "m=" line in the offer, there MUST be a corresponding "m="
line in the answer. The answer MUST contain exactly the same number
of "m=" lines as the offer. This allows for streams to be matched up
based on their order. This implies that if the offer contained zero
"m=" lines, the answer MUST contain zero "m=" lines.
</para>
</blockquote>
<para>
So this may not work with all Endpoints, especially if they
follow RFC 3264 precisely (e.g. JSSIP).
</para>
<para>
This function can be used from ANY_ROUTE.
</para>

@ -25,7 +25,7 @@
#include <string.h>/*strcmp,memset*/
#include <errno.h>/*errno*/
#include <unistd.h>/*close(),read(),pipe,fork,pid_t*/
#include <sys/poll.h>/*poll*/
#include <poll.h>/*poll*/
#include <signal.h>/*signal*/
#include <time.h>/*time*/
#include <string.h>/*memcmp*/

@ -1594,19 +1594,9 @@ static int trace_send_duplicate(char *buf, int len, struct dest_info *dst2)
return 0;
init_dest_info(&dst);
/* create a temporary proxy*/
dst.proto = PROTO_UDP;
p=mk_proxy(&dup_uri->host, (dup_uri->port_no)?dup_uri->port_no:SIP_PORT,
dst.proto);
if (p==0)
{
LM_ERR("bad host name in uri\n");
return -1;
}
if (!dst2){
init_dest_info(&dst);
/* create a temporary proxy*/
/* create a temporary proxy from dst param */
dst.proto = PROTO_UDP;
p=mk_proxy(&dup_uri->host, (dup_uri->port_no)?dup_uri->port_no:SIP_PORT,
dst.proto);
@ -1622,6 +1612,16 @@ static int trace_send_duplicate(char *buf, int len, struct dest_info *dst2)
" listening socket\n", dst.to.s.sa_family, dst.proto);
goto error;
}
} else {
/* create a temporary proxy to dup uri */
dst.proto = PROTO_UDP;
p=mk_proxy(&dup_uri->host, (dup_uri->port_no)?dup_uri->port_no:SIP_PORT,
dst.proto);
if (p==0)
{
LM_ERR("bad host name in uri\n");
return -1;
}
}
if (msg_send((dst2)?dst2:&dst, buf, len)<0)

@ -537,8 +537,8 @@ get_uri_param("nat", "$var(nat)");
Converts URI in first param (pseudo variable or string) to SIP URI, if
it is a tel URI. If conversion was done, writes resulting SIP URI to
third param (pseudo variable). Returns 1 if conversion succeeded or if
no conversion was needed.
third param (pseudo variable). Returns 1 if conversion succeeded, 2 if
no conversion was needed, and -1 in case of error.
The conversion follows the rules in RFC 3261 section 19.1.6:
* Visual separators ( "-", ".", "(", ")" ) are removed from tel URI

@ -322,7 +322,7 @@ ok:
/*
* Converts URI, if it is tel URI, to SIP URI. Returns 1, if
* conversion succeeded or if no conversion was needed, i.e., URI was not
* conversion succeeded and 2 if no conversion was needed, i.e., URI was not
* tel URI. Returns -1, if conversion failed. Takes SIP URI hostpart from
* second parameter and (if needed) writes the result to third paramater.
*/
@ -337,15 +337,17 @@ int tel2sip(struct sip_msg* _msg, char* _uri, char* _hostpart, char* _res)
/* get parameters */
if (get_str_fparam(&uri, _msg, (fparam_t*)_uri) < 0) {
LM_ERR("failed to get uri value\n");
return -1;
}
if (get_str_fparam(&hostpart, _msg, (fparam_t*)_hostpart) < 0) {
LM_ERR("failed to get hostpart value\n");
return -1;
}
res = (pv_spec_t *)_res;
/* check if anything needs to be done */
if (uri.len < 4) return 1;
if (strncasecmp(uri.s, "tel:", 4) != 0) return 1;
if (uri.len < 4) return 2;
if (strncasecmp(uri.s, "tel:", 4) != 0) return 2;
/* reserve memory for clean tel uri */
tel_uri.s = pkg_malloc(uri.len+1);

@ -513,8 +513,8 @@ get_uri_param("nat", "$var(nat)");
Converts URI in first param (pseudo variable or string) to
SIP URI, if it is a tel URI. If conversion was done,
writes resulting SIP URI to third param (pseudo variable).
Returns 1 if conversion succeeded or if no conversion
was needed.
Returns 1 if conversion succeeded, 2 if no conversion
was needed, and -1 in case of error.
</para>
<para>
The conversion follows the rules in RFC 3261 section 19.1.6:

@ -1,4 +1,4 @@
The SL Module - Statless request handling
The SL Module - Stateless request handling
Bogdan Iancu

@ -4,7 +4,7 @@
<book id="sl" xmlns:xi="http://www.w3.org/2001/XInclude">
<bookinfo>
<title>The SL Module - Statless request handling</title>
<title>The SL Module - Stateless request handling</title>
<authorgroup>
<author>
<firstname>Bogdan</firstname>

@ -17,7 +17,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*
*/
@ -137,14 +136,14 @@ int sd_lookup(struct sip_msg* _msg, char* _table, char* _owner)
LM_ERR("failed to parsing Request-URI\n");
goto err_server;
}
db_keys[nr_keys]=&sd_user_column;
db_vals[nr_keys].type = DB1_STR;
db_vals[nr_keys].nul = 0;
db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.user.s;
db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.user.len;
nr_keys++;
if(use_domain>=2)
{
db_keys[nr_keys]=&sd_domain_column;
@ -152,8 +151,7 @@ int sd_lookup(struct sip_msg* _msg, char* _table, char* _owner)
db_vals[nr_keys].nul = 0;
db_vals[nr_keys].val.str_val.s = _msg->parsed_uri.host.s;
db_vals[nr_keys].val.str_val.len = _msg->parsed_uri.host.len;
nr_keys++;
if (dstrip_s.s!=NULL && dstrip_s.len>0
&& dstrip_s.len<_msg->parsed_uri.host.len
&& strncasecmp(_msg->parsed_uri.host.s,dstrip_s.s,dstrip_s.len)==0)
@ -161,8 +159,9 @@ int sd_lookup(struct sip_msg* _msg, char* _table, char* _owner)
db_vals[nr_keys].val.str_val.s += dstrip_s.len;
db_vals[nr_keys].val.str_val.len -= dstrip_s.len;
}
nr_keys++;
}
db_funcs.use_table(db_handle, &table_s);
if(db_funcs.query(db_handle, db_keys, NULL, db_vals, db_cols,
nr_keys /*no keys*/, 1 /*no cols*/, NULL, &db_res)!=0)

@ -269,7 +269,7 @@ int sql_do_query(sql_con_t *con, str *query, sql_result_t *res)
if(db_res==NULL || RES_ROW_N(db_res)<=0 || RES_COL_N(db_res)<=0)
{
LM_DBG("no result after query\n");
con->dbf.free_result(con->dbh, db_res);
if (db_res) con->dbf.free_result(con->dbh, db_res);
return 2;
}
if(!res)

@ -675,7 +675,7 @@ int sst_check_min(struct sip_msg *msg, char *flag, char *str2)
* Too small. See if we need to send the 422 and are able
* to send it.
*/
if (flag) {
if (flag && *flag) {
str msehdr;
sst_build_minse_hdr(sst_min_se, &msehdr);
LM_DBG("Sending 422: %.*s\n", msehdr.len, msehdr.s);

Some files were not shown because too many files have changed in this diff Show More

Loading…
Cancel
Save