Merge sipwise and kamailio 3.1.5 branches

3.1
Jon Bonilla 14 years ago
parent 6361120030
commit e8c7f00561

File diff suppressed because it is too large Load Diff

@ -161,7 +161,7 @@ INSTALL_FLAVOUR=$(FLAVOUR)
#version number
VERSION = 3
PATCHLEVEL = 1
SUBLEVEL = 3
SUBLEVEL = 5
EXTRAVERSION =
# memory debugger switcher
@ -225,107 +225,6 @@ endif
# extra CC command line options (e.g -march=athlon-mp)
CC_EXTRA_OPTS ?=
LIBDIR ?=
ifeq ($(LIBDIR),)
ARCHBSZ= $(shell echo $(HOST_ARCH) | sed -e 's/.*64.*/64b/')
ifeq ($(ARCHBSZ),64b)
LIBDIR = lib64
else
LIBDIR = lib
endif
endif
# dirs
cfg_dir = etc/$(MAIN_NAME)/
bin_dir = sbin/
share_dir = share/$(MAIN_NAME)/
# lib/$(MAIN_NAME)/modules , lib/$(MAIN_NAME)/modules-s, lib/$(MAIN_NAME)/modules-k
modules_dir = $(LIBDIR)/$(MAIN_NAME)/
lib_dir = $(LIBDIR)/$(MAIN_NAME)/
doc_dir = doc/$(MAIN_NAME)/
man_dir = man/
data_dir = $(MAIN_NAME)/
ifeq ($(OS), linux)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = share/man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/local
endif
ifeq ($(OS), freebsd)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/local
endif
ifeq ($(OS), openbsd)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/local
endif
ifeq ($(OS), netbsd)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/pkg
endif
ifeq ($(OS), dragonfly)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/pkg
endif
ifeq ($(OS), darwin)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/local
endif
LOCALBASE ?= /usr/local
# Doxygen directory
doxygen_dir=doc/doxygen
# install location
PREFIX ?= $(LOCALBASE)
prefix = $(PREFIX)
# install path is $(basedir) $(prefix)
# example:
# creating a bin. archive in /tmp, which unpacks in /usr/local
# basedir=/tmp
# prefix=/usr/local
BASEDIR ?= $(DESTDIR)
basedir = $(BASEDIR)
# install prefixes for various stuff
cfg_prefix = $(basedir)$(prefix)
bin_prefix = $(basedir)$(prefix)
modules_prefix = $(basedir)$(prefix)
lib_prefix = $(basedir)$(prefix)
doc_prefix = $(basedir)$(prefix)
man_prefix = $(basedir)$(prefix)
ut_prefix = $(basedir)$(prefix)
share_prefix = $(basedir)$(prefix)
data_prefix = $(basedir)$(prefix)
# target dirs for various stuff
cfg_target = $(prefix)/$(cfg_dir)
bin_target = $(prefix)/$(bin_dir)
#modules_target = $(prefix)/$(modules_dir)
lib_target = $(prefix)/$(lib_dir)
doc_target = $(prefix)/$(doc_dir)
data_target = $(prefix)/$(data_dir)
ifeq ($(OS), solaris)
#use GNU versions
@ -385,12 +284,18 @@ ifneq (,$(findstring gcc, $(CC_LONGVER)))
#transform gcc version into 2.9x or 3.0
CC_SHORTVER:=$(shell echo "$(CC_VER)" | cut -d" " -f 2| \
sed -e 's/[^0-9]*-\(.*\)/\1/'| \
sed -e 's/2\.9.*/2.9x/' -e 's/3\.[0-3]\..*/3.0/' -e \
's/3\.[0-3]/3.0/' -e 's/3\.[4-9]\..*/3.4/' -e \
's/3\.[4-9]/3.4/' -e 's/4\.[0-1]\..*/4.x/' -e \
's/4\.[0-1]/4.x/' -e 's/4\.[2-9]\..*/4.2+/' -e \
's/4\.[2-9]$$/4.2+/')
ifeq (,$(strip $(filter-out 3.0 3.4 4.x 4.2+,$(CC_SHORTVER))))
sed -e 's/2\.9.*/2.9x/' \
-e 's/3\.[0-3]\..*/3.0/' \
-e 's/3\.[0-3]/3.0/' \
-e 's/3\.[4-9]\..*/3.4/' \
-e 's/3\.[4-9]/3.4/' \
-e 's/4\.[0-1]\..*/4.x/' \
-e 's/4\.[0-1]/4.x/' \
-e 's/4\.[2-46-9]\..*/4.2+/' \
-e 's/4\.[2-46-9]$$/4.2+/' \
-e 's/4\.5\..*/4.5/' \
-e 's/4\.5$$/4.5/')
ifeq (,$(strip $(filter-out 3.0 3.4 4.x 4.2+ 4.5,$(CC_SHORTVER))))
# dependencies can be generated on-the-fly while compiling *.c
CC_MKDEP_OPTS=-MMD -MP
endif # 3.0 <= $(CC_SHORTVER) <= 4.x
@ -504,6 +409,107 @@ ARCH:=$(HOST_ARCH)
endif
$(info target architecture <$(ARCH)>, host architecture <$(HOST_ARCH)>)
LIBDIR ?=
ifeq ($(LIBDIR),)
ARCHBSZ= $(shell echo $(ARCH) | sed -e 's/.*64.*/64b/')
ifeq ($(ARCHBSZ),64b)
LIBDIR = lib64
else
LIBDIR = lib
endif
endif
# dirs
cfg_dir = etc/$(MAIN_NAME)/
bin_dir = sbin/
share_dir = share/$(MAIN_NAME)/
# lib/$(MAIN_NAME)/modules , lib/$(MAIN_NAME)/modules-s, lib/$(MAIN_NAME)/modules-k
modules_dir = $(LIBDIR)/$(MAIN_NAME)/
lib_dir = $(LIBDIR)/$(MAIN_NAME)/
doc_dir = doc/$(MAIN_NAME)/
man_dir = man/
data_dir = $(MAIN_NAME)/
ifeq ($(OS), linux)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = share/man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/local
endif
ifeq ($(OS), freebsd)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/local
endif
ifeq ($(OS), openbsd)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/local
endif
ifeq ($(OS), netbsd)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/pkg
endif
ifeq ($(OS), dragonfly)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/pkg
endif
ifeq ($(OS), darwin)
doc_dir = share/doc/$(MAIN_NAME)/
man_dir = man/
data_dir = share/$(MAIN_NAME)/
LOCALBASE ?= /usr/local
endif
LOCALBASE ?= /usr/local
# Doxygen directory
doxygen_dir=doc/doxygen
# install location
PREFIX ?= $(LOCALBASE)
prefix = $(PREFIX)
# install path is $(basedir) $(prefix)
# example:
# creating a bin. archive in /tmp, which unpacks in /usr/local
# basedir=/tmp
# prefix=/usr/local
BASEDIR ?= $(DESTDIR)
basedir = $(BASEDIR)
# install prefixes for various stuff
cfg_prefix = $(basedir)$(prefix)
bin_prefix = $(basedir)$(prefix)
modules_prefix = $(basedir)$(prefix)
lib_prefix = $(basedir)$(prefix)
doc_prefix = $(basedir)$(prefix)
man_prefix = $(basedir)$(prefix)
ut_prefix = $(basedir)$(prefix)
share_prefix = $(basedir)$(prefix)
data_prefix = $(basedir)$(prefix)
# target dirs for various stuff
cfg_target = $(prefix)/$(cfg_dir)
bin_target = $(prefix)/$(bin_dir)
#modules_target = $(prefix)/$(modules_dir)
lib_target = $(prefix)/$(lib_dir)
doc_target = $(prefix)/$(doc_dir)
data_target = $(prefix)/$(data_dir)
# compile-time options
#
# -DSTATS
@ -857,8 +863,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS=-g -O9 -funroll-loops -Wcast-align $(PROFILE)
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
$(call set_if_empty,CPU,athlon64)
CFLAGS+=-m32 -minline-all-stringops \
-falign-loops \
@ -907,7 +913,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5 or 4.2+
else # CC_NAME, gcc
ifeq ($(CC_NAME), icc)
@ -932,6 +938,16 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS=-g -O9 -funroll-loops -Wcast-align $(PROFILE)
#if gcc 4.5
# don't add '-mtune=$(CPU)' - gcc failure
ifeq ($(CC_SHORTVER), 4.5)
$(call set_if_empty,CPU,opteron)
CFLAGS+=-m64 -minline-all-stringops \
-falign-loops \
-ftree-vectorize \
-fno-strict-overflow
LDFLAGS+=-m64
else
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
$(call set_if_empty,CPU,opteron)
@ -983,6 +999,7 @@ endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5
else # CC_NAME, gcc
ifeq ($(CC_NAME), icc)
@ -1009,8 +1026,8 @@ ifeq ($(CC_NAME), gcc)
CFLAGS=-g -O9 -funroll-loops $(PROFILE) \
#-Wcast-align \
#-Wmissing-prototypes
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
$(call set_if_empty,CPU,ultrasparc)
#use 32bit for now
CFLAGS+=-m64 -mcpu=ultrasparc \
@ -1076,7 +1093,7 @@ endif #CC_SHORTVER, 2.9x
endif #CC_SHORTVER, 3.0
endif #CC_SHORTVER, 3.4
endif #CC_SHORTVER, 4.x
endif #CC_SHORTVER, 4.2+
endif #CC_SHORTVER, 4.5 or 4.2+
else #CC_NAME, gcc
ifeq ($(CC_NAME), suncc)
@ -1100,8 +1117,8 @@ ifeq ($(CC_NAME), gcc)
CFLAGS=-g -O9 -funroll-loops $(PROFILE) \
#-Wcast-align \
#-Wmissing-prototypes
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
$(call set_if_empty,CPU,v8)
#use 32bit for now
CFLAGS+= -mtune=$(CPU) \
@ -1142,7 +1159,7 @@ endif #CC_SHORTVER, 2.9x
endif #CC_SHORTVER, 3.0
endif #CC_SHORTVER, 3.4
endif #CC_SHORTVER, 4.x
endif #CC_SHORTVER, 4.2+
endif #CC_SHORTVER, 4.5 or 4.2+
else #CC_NAME, gcc
ifeq ($(CC_NAME), suncc)
@ -1163,8 +1180,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS=-O9 -funroll-loops -fsigned-char $(PROFILE)
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
CFLAGS+= -ftree-vectorize -fno-strict-overflow
# not supported on arm: -minline-all-stringops
else
@ -1196,7 +1213,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5 or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1212,8 +1229,8 @@ ifeq ($(CC_NAME), gcc)
#common stuff
CFLAGS=-march=armv6 -O9 -funroll-loops -fsigned-char \
$(PROFILE)
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
CFLAGS+= -ftree-vectorize -fno-strict-overflow
else
#if gcc 4.x+
@ -1243,7 +1260,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5 or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1258,8 +1275,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS=-O9 -funroll-loops $(PROFILE)
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
CFLAGS+=-march=r3000 -minline-all-stringops \
-ftree-vectorize -fno-strict-overflow
else
@ -1290,7 +1307,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5 or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1305,8 +1322,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS= -mips2 -O9 -funroll-loops $(PROFILE)
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
CFLAGS+=-minline-all-stringops -ftree-vectorize \
-fno-strict-overflow
else
@ -1335,7 +1352,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5 or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1350,8 +1367,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS= -mips64 -O9 -funroll-loops $(PROFILE)
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
CFLAGS+=-minline-all-stringops -ftree-vectorize \
-fno-strict-overflow
else
@ -1380,7 +1397,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5 or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1395,8 +1412,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS= -O9 -funroll-loops $(PROFILE)
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
CFLAGS+= -fno-strict-overflow
# not supported: -minline-all-stringops
else
@ -1426,7 +1443,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5 or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1441,8 +1458,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS= -O9 -funroll-loops -fsigned-char $(PROFILE)
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
$(call set_if_empty,CPU,powerpc)
CFLAGS+=-ftree-vectorize \
-fno-strict-overflow \
@ -1475,7 +1492,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5 or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1490,8 +1507,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS= -O9 -funroll-loops -fsigned-char $(PROFILE)
#if gcc 4.2+
ifeq ($(CC_SHORTVER), 4.2+)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5,$(CC_SHORTVER))))
$(call set_if_empty,CPU,powerpc64)
CFLAGS+=-ftree-vectorize \
-fno-strict-overflow \
@ -1524,7 +1541,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5 or 4.2+
else # CC_NAME, gcc
#other compilers

@ -0,0 +1 @@
FLAVOUR?=kamailio

@ -0,0 +1,7 @@
/* this file is autogenerated by make autover.h
* DO NOT EDIT IT
*/
#define REPO_VER "ec672a"
#define REPO_HASH "ec672a"
#define REPO_STATE ""

@ -297,6 +297,10 @@ LOG_AND "and"|"&&"
BIN_AND "&"
LOG_OR "or"|"||"
BIN_OR "|"
BIN_NOT "~"
BIN_XOR "^"
BIN_LSHIFT "<<"
BIN_RSHIFT ">>"
PLUS "+"
MINUS "-"
MODULO "mod"
@ -927,6 +931,10 @@ SUBST subst
<INITIAL>{BIN_AND} { count(); return BIN_AND; }
<INITIAL>{LOG_OR} { count(); return LOG_OR; }
<INITIAL>{BIN_OR} { count(); return BIN_OR; }
<INITIAL>{BIN_NOT} { count(); return BIN_NOT; }
<INITIAL>{BIN_XOR} { count(); return BIN_XOR; }
<INITIAL>{BIN_LSHIFT} { count(); return BIN_LSHIFT; }
<INITIAL>{BIN_RSHIFT} { count(); return BIN_RSHIFT; }
<INITIAL>{PLUS} { count(); return PLUS; }
<INITIAL>{MINUS} { count(); return MINUS; }
<INITIAL>{MODULO} { count(); return MODULO; }

@ -564,11 +564,14 @@ extern char *finame;
%left LOG_AND
%left BIN_OR
%left BIN_AND
%left BIN_XOR
%left BIN_LSHIFT
%left BIN_RSHIFT
%left EQUAL_T DIFF MATCH INTEQ INTDIFF STREQ STRDIFF
%left GT LT GTE LTE
%left PLUS MINUS
%left STAR SLASH MODULO
%right NOT UNARY
%right NOT UNARY BIN_NOT
%right DEFINED
%right INTCAST STRCAST
%left DOT
@ -2733,6 +2736,7 @@ rval: intno {$$=mk_rve_rval(RV_INT, (void*)$1); }
rve_un_op: NOT { $$=RVE_LNOT_OP; }
| BIN_NOT { $$=RVE_BNOT_OP; }
| MINUS %prec UNARY { $$=RVE_UMINUS_OP; }
/* TODO: RVE_BOOL_OP, RVE_NOT_OP? */
;
@ -2762,6 +2766,9 @@ rval_expr: rval { $$=$1;
| rval_expr MODULO rval_expr {$$=mk_rve2(RVE_MOD_OP, $1, $3); }
| rval_expr BIN_OR rval_expr {$$=mk_rve2(RVE_BOR_OP, $1, $3); }
| rval_expr BIN_AND rval_expr {$$=mk_rve2(RVE_BAND_OP, $1, $3);}
| rval_expr BIN_XOR rval_expr {$$=mk_rve2(RVE_BXOR_OP, $1, $3);}
| rval_expr BIN_LSHIFT rval_expr {$$=mk_rve2(RVE_BLSHIFT_OP, $1, $3);}
| rval_expr BIN_RSHIFT rval_expr {$$=mk_rve2(RVE_BRSHIFT_OP, $1, $3);}
| rval_expr rve_cmpop rval_expr %prec GT { $$=mk_rve2( $2, $1, $3);}
| rval_expr rve_equalop rval_expr %prec EQUAL_T
{ $$=mk_rve2( $2, $1, $3);}

@ -2978,7 +2978,7 @@ inline static int dns_a_resolve( struct dns_hash_entry** e,
ret=-E_DNS_EOR;
}
error:
DBG("dns_a_resovle(%.*s, %d) returning %d\n",
DBG("dns_a_resolve(%.*s, %d) returning %d\n",
name->len, name->s, *rr_no, ret);
return ret;
}

@ -796,7 +796,7 @@ onreply_route[REPLY_ONE] {
&& status=~"(183)|(2[0-9][0-9])") {
force_rtp_proxy();
}
if (isbflagset("6")) {
if (isbflagset(FLB_NATB)) {
fix_nated_contact();
}
#!endif

@ -545,8 +545,8 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
value in there; better for performance
*/
if (syn_branch ) {
*msg->add_to_branch_s='0';
msg->add_to_branch_len=1;
memcpy(msg->add_to_branch_s, "z9hG4bKcydzigwkX", 16);
msg->add_to_branch_len=16;
} else {
if (!char_msg_val( msg, md5 )) { /* parses transaction key */
LOG(L_ERR, "ERROR: forward_request: char_msg_val failed\n");
@ -785,7 +785,7 @@ int forward_reply(struct sip_msg* msg)
|| (msg->via2==0) || (msg->via2->error!=PARSE_OK))
{
/* no second via => error */
/* LOG(L_INFO, "broken reply to forward - no 2nd via\n"); */
/*LOG(L_INFO, "broken reply to forward - no 2nd via\n");*/
DBG("DEBUG: broken reply to forward - no 2nd via\n");
goto error;
}

@ -722,7 +722,7 @@ static inline char* su2a(union sockaddr_union* su, int su_len)
{
static char buf[SU2A_MAX_STR_SIZE];
int offs;
#ifdef USE_IPV6
if (unlikely(su->s.sa_family==AF_INET6)){
if (unlikely(su_len<sizeof(su->sin6)))
@ -744,6 +744,34 @@ static inline char* su2a(union sockaddr_union* su, int su_len)
return buf;
}
#define SUIP2A_MAX_STR_SIZE (IP6_MAX_STR_SIZE + 2 /* [] */ + 1 /* \0 */)
/* returns an asciiz string containing the ip
* (<ipv4_addr> or [<ipv6_addr>])
*/
static inline char* suip2a(union sockaddr_union* su, int su_len)
{
static char buf[SUIP2A_MAX_STR_SIZE];
int offs;
#ifdef USE_IPV6
if (unlikely(su->s.sa_family==AF_INET6)){
if (unlikely(su_len<sizeof(su->sin6)))
return "<addr. error>";
buf[0]='[';
offs=1+ip6tosbuf((unsigned char*)su->sin6.sin6_addr.s6_addr, &buf[1],
sizeof(buf)-4);
buf[offs]=']';
offs++;
}else
#endif /* USE_IPV6*/
if (unlikely(su_len<sizeof(su->sin)))
return "<addr. error>";
else
offs=ip4tosbuf((unsigned char*)&su->sin.sin_addr, buf, sizeof(buf)-2);
buf[offs]=0;
return buf;
}
/* converts an ip_addr structure to a hostent, returns pointer to internal

@ -162,12 +162,14 @@ static int parse_db_url(struct db_id* id, const str* url)
case '@':
st = ST_HOST;
id->username = prev_token;
prev_token = 0;
if (dupl_string(&id->password, begin, url->s + i) < 0) goto err;
begin = url->s + i + 1;
break;
case '/':
id->host = prev_token;
prev_token = 0;
id->port = str2s(begin, url->s + i - begin, 0);
if (dupl_string(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
return 0;
@ -207,11 +209,14 @@ static int parse_db_url(struct db_id* id, const str* url)
return 0;
err:
if (id->scheme) pkg_free(id->scheme);
if (id->username) pkg_free(id->username);
if (id->password) pkg_free(id->password);
if (id->host) pkg_free(id->host);
if (id->database) pkg_free(id->database);
if(id){
if (id->scheme) pkg_free(id->scheme);
if (id->username) pkg_free(id->username);
if (id->password) pkg_free(id->password);
if (id->host) pkg_free(id->host);
if (id->database) pkg_free(id->database);
memset(id, 0, sizeof(struct db_id));
}
if (prev_token) pkg_free(prev_token);
return -1;
}

@ -12,7 +12,7 @@
<version>1</version>
<type db="mysql">&MYSQL_TABLE_TYPE;</type>
<description>
<db:para>This table us used by the htabke module to load values in the hash table at start up. More information about the avpops module can be found at: &KAMAILIO_MOD_DOC;htable.html
<db:para>This table us used by the htable module to load values in the hash table at start up. More information about the htable module can be found at: &KAMAILIO_MOD_DOC;htable.html
</db:para>
</description>

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE database PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN"
"http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
<!ENTITY % entities SYSTEM "entities.xml">
%entities;
]>
<database xmlns:xi="http://www.w3.org/2001/XInclude">
<name>Pipelimit</name>
<xi:include href="pipelimit.xml"/>
</database>

@ -0,0 +1,55 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE table PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN"
"http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
<!ENTITY % entities SYSTEM "entities.xml">
%entities;
]>
<table id="pl_pipes" xmlns:db="http://docbook.org/ns/docbook">
<name>pl_pipes</name>
<version>1</version>
<type db="mysql">&MYSQL_TABLE_TYPE;</type>
<description>
<db:para> This table us used by the pipelimit module to keep the definition of pipes.
More information about the pipelimit module can be found at: &KAMAILIO_MOD_DOC;pipelimit.html
</db:para>
</description>
<column id="id">
<name>id</name>
<type>unsigned int</type>
<size>&table_id_len;</size>
<autoincrement/>
<primary/>
<type db="dbtext">int,auto</type>
<description>unique ID</description>
</column>
<column>
<name>pipeid</name>
<type>string</type>
<size>64</size>
<default/>
<description>Unique ID for pipe</description>
</column>
<column>
<name>algorithm</name>
<type>string</type>
<size>32</size>
<default/>
<description>Algorithm to be used for pipe limits. See the readme of the
module for description of available options: NOP, RED, TAILDROP, FEEDBACK, NETWORK
</description>
</column>
<column>
<name>plimit</name>
<type>int</type>
<default>0</default>
<description>Pipe limit (hits per second)</description>
</column>
</table>

@ -96,7 +96,7 @@
<column id="callid">
<name>callid</name>
<type>string</type>
<size>&domain_len;</size>
<size>&uri_len;</size>
<description>Call ID</description>
</column>
@ -117,7 +117,7 @@
<column>
<name>contact</name>
<type>string</type>
<size>&domain_len;</size>
<size>&uri_len;</size>
<description>Contact</description>
</column>

@ -95,7 +95,7 @@
<column>
<name>call_id</name>
<type>string</type>
<size>&domain_len;</size>
<size>&uri_len;</size>
<description>Call ID</description>
</column>

@ -1537,9 +1537,15 @@ int main_loop()
/* udp processes */
for(si=udp_listen; si; si=si->next){
for(i=0;i<children_no;i++){
snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
if(si->address.af==AF_INET6) {
snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
"sock=[%s]:%s",
i, si->name.s, si->port_no_str.s);
} else {
snprintf(si_desc, MAX_PT_DESC, "udp receiver child=%d "
"sock=%s:%s",
i, si->name.s, si->port_no_str.s);
}
child_rank++;
pid = fork_process(child_rank, si_desc, 1);
if (pid<0){
@ -1562,9 +1568,15 @@ int main_loop()
if (!sctp_disable){
for(si=sctp_listen; si; si=si->next){
for(i=0;i<sctp_children_no;i++){
snprintf(si_desc, MAX_PT_DESC, "sctp receiver child=%d "
if(si->address.af==AF_INET6) {
snprintf(si_desc, MAX_PT_DESC, "sctp receiver child=%d "
"sock=[%s]:%s",
i, si->name.s, si->port_no_str.s);
} else {
snprintf(si_desc, MAX_PT_DESC, "sctp receiver child=%d "
"sock=%s:%s",
i, si->name.s, si->port_no_str.s);
}
child_rank++;
pid = fork_process(child_rank, si_desc, 1);
if (pid<0){

@ -33,12 +33,12 @@ ifeq ($(BUILDER),)
LIBS= -llua5.1
endif
else
DEFS+ = $(shell pkg-config --cflags lua)
DEFS+= $(shell pkg-config --cflags lua)
LIBS = $(shell pkg-config --libs lua)
endif
endif
else
DEFS+ = $(shell lua-config --include)
DEFS+= $(shell lua-config --include)
LIBS = $(shell lua-config --libs)
endif

@ -85,7 +85,7 @@ struct module_exports exports = {
static int
mod_init(void)
{
char *dname, *bname;
char *dname, *bname, *tname;
int i;
PyObject *sys_path, *pDir, *pModule, *pFunc, *pArgs;
PyThreadState *mainThreadState;
@ -100,11 +100,19 @@ mod_init(void)
child_init_mname.len = strlen(child_init_mname.s);
}
dname = dirname(script_name.s);
tname = as_asciiz(&script_name);
if(tname==NULL)
{
LM_ERR("no more pkg memory\n");
return -1;
}
dname = dirname(tname);
if (strlen(dname) == 0)
dname = ".";
bname = basename(script_name.s);
memcpy(tname, script_name.s, script_name.len);
bname = basename(tname);
i = strlen(bname);
pkg_free(tname);
if (bname[i - 1] == 'c' || bname[i - 1] == 'o')
i -= 1;
if (bname[i - 3] == '.' && bname[i - 2] == 'p' && bname[i - 1] == 'y') {

@ -526,8 +526,7 @@ static PyTypeObject MSGtype = {
int
python_msgobj_init(void)
{
Py_TYPE(&MSGtype) = &PyType_Type;
Py_TYPE((void*)(&MSGtype)) = &PyType_Type;
if (PyType_Ready(&MSGtype) < 0)
return -1;
return 0;

@ -437,7 +437,7 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest
}
break;
case alg_crc32_nofallback:
if ((prob = (hash_func(msg, hash_source, rf->max_targets) + 1)) < 0) {
if ((prob = (hash_func(msg, hash_source, rf->max_targets))) < 0) {
LM_ERR("could not hash message with CRC32");
return -1;
}
@ -445,7 +445,7 @@ static int rewrite_on_rule(struct route_flags *rf_head, flag_t flags, str * dest
* this function just tries only a backup rule and otherwise
* returns -1. This way we get an error
*/
if ((rr = get_rule_by_hash(rf, prob)) == NULL) {
if ((rr = get_rule_by_hash(rf, prob + 1)) == NULL) {
LM_CRIT("no route found\n");
return -1;
}

@ -14,6 +14,9 @@ DEFS +=-DSER_MOD_INTERFACE
ifeq ($(CROSS_COMPILE),)
MYSQLCFG=$(shell which mysql_config)
ifeq ($(MYSQLCFG),)
MYSQLCFG=$(shell which mysql_config5)
endif
endif
ifneq ($(MYSQLCFG),)

@ -240,7 +240,7 @@ int dbg_cfg_trace(void *data)
a = (struct action *)srevp[0];
msg = (struct sip_msg *)srevp[1];
if(a==NULL || msg==NULL)
if(a==NULL || msg==NULL || _dbg_pid_list==NULL)
return 0;
an = dbg_get_action_name(a);

@ -68,12 +68,20 @@ Chapter 1. Admin Guide
identifying the physical location with which an IP host address is
associated on a relatively granular level.
This database itself can be obtained on a free or commercial basis
here. The library that interfaces with the Max Mind API, as well as
scripts to automate downloading of the on-disk version of the
open-source database is also packaged by the Debian Linux distribution
and its derivatives as libgeoip, and probably by other distributions as
well.
This database itself can be obtained on a free or commercial basis from
http://www.maxmind.com/app/ip-location. The library that interfaces
with the Max Mind API, as well as scripts to automate downloading of
the on-disk version of the open-source database is also packaged by the
Debian Linux distribution and its derivatives as libgeoip, and probably
by other distributions as well.
Debian Linux squeeze includes already a database as dependency, but as
this contain the wrong data, it will not work correctly with the
module. More acurate, the module expect the GeoIP City Edition, and
will not work with the GeoIP Country Edition. In newer Debian Linux
releases the package geoip-database-contrib should contain the
necessary database. You can download the Lite edition of the DB from
http://www.maxmind.com/app/geolitecity.
This module exports a new class of pseudo-variables - $gip(pvc=>key) -
to enable access to the results of a query to the database.

@ -28,13 +28,24 @@
</para>
<para>
This database itself can be obtained on a free or commercial basis
<ulink url="http://www.maxmind.com/app/ip-location">here</ulink>. The
from <ulink url="http://www.maxmind.com/app/ip-location">
http://www.maxmind.com/app/ip-location</ulink>. The
library that interfaces with the Max Mind API, as well as scripts to
automate downloading of the on-disk version of the open-source
database is also packaged by the Debian Linux distribution and
its derivatives as <emphasis>libgeoip</emphasis>, and probably by
other distributions as well.
</para>
<para>
Debian Linux squeeze includes already a database as dependency, but as
this contain the wrong data, it will not work correctly with the module.
More acurate, the module expect the <emphasis>GeoIP City Edition</emphasis>,
and will not work with the <emphasis>GeoIP Country Edition</emphasis>. In
newer Debian Linux releases the package <emphasis>geoip-database-contrib</emphasis>
should contain the necessary database. You can download the Lite edition
of the DB from <ulink url="http://www.maxmind.com/app/geolitecity">
http://www.maxmind.com/app/geolitecity</ulink>.
</para>
<para>
This module exports a new class of pseudo-variables -
$gip(pvc=&gt;key) - to enable access to the results of a query to the

@ -1563,7 +1563,7 @@ use_media_proxy(struct sip_msg *msg, char *dialog_id, ice_candidate_data *ice_da
str callid, cseq, from_uri, to_uri, from_tag, to_tag, user_agent;
str signaling_ip, media_relay, sdp, str_buf, tokens[MAX_STREAMS+1];
str priority_str, candidate;
char request[8192], media_str[4096], buf[64], *result, *type;
char request[8192], media_str[4096], buf[128], *result, *type;
int i, j, port, len, status;
Bool removed_session_ip, have_sdp;
SessionInfo session;

@ -10,7 +10,7 @@ Elena-Ramona Modroiu
<ramona@asipto.com>
Copyright © 2010 Elena-Ramona Modroiu (asipto.com)
Copyright © 2010 Elena-Ramona Modroiu (asipto.com)
__________________________________________________________________
Table of Contents
@ -94,7 +94,7 @@ Chapter 1. Admin Guide
Definition of memory queue
Default value is "none".
Default value is “none”.
Value must be a list of parameters: attr=value;... The attribute 'name'
is mandatory, defining the name of the queue. Optional attribute 'size'
@ -128,8 +128,11 @@ mq_add("myq", "$rU", "call from $fU");
4.2. mq_fetch(queue)
Take oldest item from que and fill $mqk(queue) and $mqv(queue) pseudo
variables. Return true on success.
Take oldest item from queue and fill $mqk(queue) and $mqv(queue) pseudo
variables.
Return: true on success (1); false on failure (-1) or no item fetched
(-2).
Example 1.3. mq_fetch usage
...

@ -118,8 +118,12 @@ mq_add("myq", "$rU", "call from $fU");
<function moreinfo="none">mq_fetch(queue)</function>
</title>
<para>
Take oldest item from que and fill $mqk(queue) and $mqv(queue) pseudo
variables. Return true on success.
Take oldest item from queue and fill $mqk(queue) and
$mqv(queue) pseudo variables.
</para>
<para>
Return: true on success (1); false on failure (-1) or
no item fetched (-2).
</para>
<example>
<title><function>mq_fetch</function> usage</title>

@ -254,18 +254,22 @@ int mq_head_fetch(str *name)
return -1;
lock_get(&mh->lock);
if(mh->ifirst!=NULL)
if(mh->ifirst==NULL)
{
mp->item = mh->ifirst;
mh->ifirst = mh->ifirst->next;
if(mh->ifirst==NULL) {
mh->ilast = NULL;
} else {
mh->ifirst->prev = NULL;
}
mh->csize--;
/* empty queue */
lock_release(&mh->lock);
return -2;
}
mp->item = mh->ifirst;
mh->ifirst = mh->ifirst->next;
if(mh->ifirst==NULL) {
mh->ilast = NULL;
} else {
mh->ifirst->prev = NULL;
}
mh->csize--;
lock_release(&mh->lock);
return 0;
}
@ -339,6 +343,8 @@ int mq_item_add(str *qname, str *key, str *val)
mh->ilast = NULL;
else
mh->ifirst->prev = NULL;
mh->csize--;
shm_free(mi);
}
lock_release(&mh->lock);
return 0;

@ -109,8 +109,11 @@ static void mod_destroy(void)
static int w_mq_fetch(struct sip_msg* msg, char* mq, char* str2)
{
if(mq_head_fetch((str*)mq)<0)
return -1;
int ret;
ret = mq_head_fetch((str*)mq);
if(ret<0)
return ret;
return 1;
}

@ -424,7 +424,7 @@ static int mod_init(void)
return -1;
}
timer_init(rl_timer, rl_timer_handle, 0, F_TIMER_FAST);
timer_add(rl_timer, MS_TO_TICKS(1500)); /* Start it after 1500ms */
timer_add(rl_timer, MS_TO_TICKS(1000*timer_interval));
network_load_value = shm_malloc(sizeof(int));
if (network_load_value==NULL) {

@ -133,11 +133,15 @@ static void tls_list(rpc_t* rpc, void* c)
"dst_ip", dst_ip,
"dst_port", con->rcv.dst_port);
if (tls_d) {
tls_info = SSL_CIPHER_description(
if(SSL_get_current_cipher(tls_d->ssl)) {
tls_info = SSL_CIPHER_description(
SSL_get_current_cipher(tls_d->ssl),
buf, sizeof(buf));
len = strlen(buf);
if (len && buf[len - 1] == '\n') buf[len - 1] = '\0';
len = strlen(buf);
if (len && buf[len - 1] == '\n') buf[len - 1] = '\0';
} else {
tls_info = "unknown";
}
/* tls data */
state = "unknown/error";
lock_get(&con->write_lock);

@ -97,13 +97,29 @@ enum kill_reason get_kr() {
void lock_hash(int i)
{
lock(&_tm_table->entries[i].mutex);
int mypid;
mypid = my_pid();
if (likely(atomic_get(&_tm_table->entries[i].locker_pid) != mypid)) {
lock(&_tm_table->entries[i].mutex);
atomic_set(&_tm_table->entries[i].locker_pid, mypid);
} else {
/* locked within the same process that called us*/
_tm_table->entries[i].rec_lock_level++;
}
}
void unlock_hash(int i)
{
unlock(&_tm_table->entries[i].mutex);
if (likely(_tm_table->entries[i].rec_lock_level == 0)) {
atomic_set(&_tm_table->entries[i].locker_pid, 0);
unlock(&_tm_table->entries[i].mutex);
} else {
/* recursive locked => decrease rec. lock count */
_tm_table->entries[i].rec_lock_level--;
}
}
@ -478,4 +494,82 @@ error0:
}
/**
* backup xdata from/to msg context to local var and use T lists
* - mode = 0 - from msg context to _txdata and use T lists
* - mode = 1 - restore to msg context from _txdata
*/
void tm_xdata_swap(tm_cell_t *t, tm_xlinks_t *xd, int mode)
{
static tm_xlinks_t _txdata;
tm_xlinks_t *x;
if(xd==NULL)
x = &_txdata;
else
x = xd;
if(mode==0) {
if(t==NULL)
return;
x->uri_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &t->uri_avps_from );
x->uri_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &t->uri_avps_to );
x->user_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &t->user_avps_from );
x->user_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &t->user_avps_to );
x->domain_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &t->domain_avps_from );
x->domain_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &t->domain_avps_to );
#ifdef WITH_XAVP
x->xavps_list = xavp_set_list(&t->xavps_list);
#endif
} else if(mode==1) {
/* restore original avp list */
set_avp_list( AVP_TRACK_FROM | AVP_CLASS_URI, x->uri_avps_from );
set_avp_list( AVP_TRACK_TO | AVP_CLASS_URI, x->uri_avps_to );
set_avp_list( AVP_TRACK_FROM | AVP_CLASS_USER, x->user_avps_from );
set_avp_list( AVP_TRACK_TO | AVP_CLASS_USER, x->user_avps_to );
set_avp_list( AVP_TRACK_FROM | AVP_CLASS_DOMAIN, x->domain_avps_from );
set_avp_list( AVP_TRACK_TO | AVP_CLASS_DOMAIN, x->domain_avps_to );
#ifdef WITH_XAVP
xavp_set_list(x->xavps_list);
#endif
}
}
/**
* replace existing lists with newxd and backup in bakxd or restore from bakxd
*/
void tm_xdata_replace(tm_xdata_t *newxd, tm_xlinks_t *bakxd)
{
if(newxd==NULL && bakxd!=NULL) {
set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, bakxd->uri_avps_from);
set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, bakxd->uri_avps_to);
set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, bakxd->user_avps_from);
set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, bakxd->user_avps_to);
set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, bakxd->domain_avps_from);
set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, bakxd->domain_avps_to);
#ifdef WITH_XAVP
xavp_set_list(bakxd->xavps_list);
#endif
return;
}
if(newxd!=NULL && bakxd!=NULL) {
bakxd->uri_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI,
&newxd->uri_avps_from);
bakxd->uri_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI,
&newxd->uri_avps_to);
bakxd->user_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER,
&newxd->user_avps_from);
bakxd->user_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER,
&newxd->user_avps_to);
bakxd->domain_avps_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN,
&newxd->domain_avps_from);
bakxd->domain_avps_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN,
&newxd->domain_avps_to);
#ifdef WITH_XAVP
bakxd->xavps_list = xavp_set_list(&newxd->xavps_list);
#endif
return;
}
}

@ -300,6 +300,42 @@ struct totag_elem {
* saves us 2*2 bytes */
typedef unsigned short retr_timeout_t;
/**
* extra data from SIP message context to transaction storage
*/
typedef struct tm_xdata
{
/* lists with avps */
struct usr_avp *uri_avps_from;
struct usr_avp *uri_avps_to;
struct usr_avp *user_avps_from;
struct usr_avp *user_avps_to;
struct usr_avp *domain_avps_from;
struct usr_avp *domain_avps_to;
#ifdef WITH_XAVP
sr_xavp_t *xavps_list;
#endif
} tm_xdata_t;
/**
* links to extra data from SIP message context to transaction storage
*/
typedef struct tm_xlinks
{
/* links to lists with avps */
struct usr_avp **uri_avps_from;
struct usr_avp **uri_avps_to;
struct usr_avp **user_avps_from;
struct usr_avp **user_avps_to;
struct usr_avp **domain_avps_from;
struct usr_avp **domain_avps_to;
#ifdef WITH_XAVP
sr_xavp_t **xavps_list;
#endif
} tm_xlinks_t;
/* transaction context */
typedef struct cell
@ -370,7 +406,7 @@ typedef struct cell
* many due to downstream forking; */
struct totag_elem *fwded_totags;
/* list with avp */
/* lists with avps */
struct usr_avp *uri_avps_from;
struct usr_avp *uri_avps_to;
struct usr_avp *user_avps_from;
@ -406,7 +442,7 @@ typedef struct cell
/* place holder for MD5checksum (meaningful only if syn_branch=0) */
char md5[0]; /* if syn_branch==0 then MD5_LEN bytes are extra alloc'ed*/
}cell_type;
} tm_cell_t;
#if 0
@ -429,6 +465,8 @@ typedef struct entry
struct cell* prev_c;
/* sync mutex */
ser_lock_t mutex;
atomic_t locker_pid; /* pid of the process that holds the lock */
int rec_lock_level; /* recursive lock count */
/* currently highest sequence number in a synonym list */
unsigned int next_label;
#ifdef TM_HASH_STATS
@ -541,6 +579,13 @@ inline static void remove_from_hash_table_unsafe( struct cell * p_cell)
t_stats_deleted( is_local(p_cell) );
}
/**
* backup xdata from/to msg context to local var and use T lists
*/
void tm_xdata_swap(tm_cell_t *t, tm_xlinks_t *xd, int mode);
void tm_xdata_replace(tm_xdata_t *newxd, tm_xlinks_t *bakxd);
#endif

@ -152,6 +152,8 @@ unsigned int get_on_branch(void)
/* prepare_new_uac flags */
#define UAC_DNS_FAILOVER_F 1 /**< new branch due to dns failover */
#define UAC_SKIP_BR_DST_F 2 /**< don't set next hop as dst_uri for
branch_route */
/** prepares a new branch "buffer".
@ -177,7 +179,7 @@ unsigned int get_on_branch(void)
* @param fsocket - forced send socket for forwarding.
* @param send_flags - special flags for sending (see SND_F_* / snd_flags_t).
* @param fproto - forced proto for forwarding. Used only if next_hop!=0.
* @param flags - 0 or UAC_DNS_FAILOVER_F for now.
* @param flags - 0, UAC_DNS_FAILOVER_F or UAC_SKIP_BR_DST_F for now.
*
* @return 0 on success, < 0 (ser_errror E***) on failure.
*/
@ -305,10 +307,12 @@ static int prepare_new_uac( struct cell *t, struct sip_msg *i_req,
i_req->dst_uri.s=0;
i_req->dst_uri.len=0;
if (likely(next_hop)){
/* set dst uri to next_hop for the on_branch route */
if (unlikely(set_dst_uri(i_req, next_hop)<0)){
ret=E_OUT_OF_MEM;
goto error03;
if(unlikely((flags & UAC_SKIP_BR_DST_F)==0)){
/* set dst uri to next_hop for the on_branch route */
if (unlikely(set_dst_uri(i_req, next_hop)<0)){
ret=E_OUT_OF_MEM;
goto error03;
}
}
}
@ -1481,7 +1485,8 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
try_new=1;
branch_ret=add_uac( t, p_msg, GET_RURI(p_msg), GET_NEXT_HOP(p_msg),
&p_msg->path_vec, proxy, p_msg->force_send_socket,
p_msg->fwd_send_flags, proto, 0);
p_msg->fwd_send_flags, proto,
(p_msg->dst_uri.len)?0:UAC_SKIP_BR_DST_F);
if (branch_ret>=0)
added_branches |= 1<<branch_ret;
else
@ -1497,7 +1502,7 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
branch_ret=add_uac( t, p_msg, &current_uri,
(dst_uri.len) ? (&dst_uri) : &current_uri,
&path, proxy, si, p_msg->fwd_send_flags,
proto, 0);
proto, (dst_uri.len)?0:UAC_SKIP_BR_DST_F);
/* pick some of the errors in case things go wrong;
note that picking lowest error is just as good as
any other algorithm which picks any other negative
@ -1512,6 +1517,9 @@ int t_forward_nonack( struct cell *t, struct sip_msg* p_msg ,
setbflagsval(0, backup_bflags);
/* update message flags, if changed in branch route */
t->uas.request->flags = p_msg->flags;
/* don't forget to clear all branches processed so far */
/* things went wrong ... no new branch has been fwd-ed at all */

@ -960,11 +960,13 @@ int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
on_failure = t->on_negative;
t->on_negative=0;
if (exec_pre_script_cb(&faked_req, FAILURE_CB_TYPE)>0) {
/* run a reply_route action if some was marked */
/* run a failure_route action if some was marked */
if (run_top_route(failure_rt.rlist[on_failure], &faked_req, 0)<0)
LOG(L_ERR, "ERROR: run_failure_handlers: Error in run_top_route\n");
exec_post_script_cb(&faked_req, FAILURE_CB_TYPE);
}
/* update message flags, if changed in failure route */
t->uas.request->flags = faked_req.flags;
}
/* restore original environment and free the fake msg */

@ -242,15 +242,21 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
}
ruri = (str *)0;
/* Take first q from Request-URI */
ruri = GET_RURI(msg);
if (!ruri) {
LM_ERR("no Request-URI found\n");
return -1;
if (ruri_is_new) {
/* Take first q from Request-URI */
ruri = GET_RURI(msg);
if (!ruri) {
LM_ERR("no Request-URI found\n");
return -1;
}
first_q = get_ruri_q();
first_idx = 0;
} else {
/* Take first q from first branch */
uri.s = get_branch(0, &uri.len, &first_q, &dst_uri, &path, &flags,
&sock);
first_idx = 1;
}
first_q = get_ruri_q();
first_idx = 0;
/* Check if all q values are equal */
for(idx = first_idx; (tmp.s = get_branch(idx, &tmp.len, &q, 0, 0, 0, 0))
@ -272,15 +278,24 @@ rest:
return -1;
}
/* Insert Request-URI branch to first contact */
contacts->uri.s = ruri->s;
contacts->uri.len = ruri->len;
contacts->dst_uri = msg->dst_uri;
contacts->sock = msg->force_send_socket;
getbflagsval(0, &contacts->flags);
contacts->path = msg->path_vec;
contacts->q = first_q;
contacts->next = (struct contact *)0;
if (ruri_is_new) {
/* Insert Request-URI branch to first contact */
contacts->uri.s = ruri->s;
contacts->uri.len = ruri->len;
contacts->dst_uri = msg->dst_uri;
contacts->sock = msg->force_send_socket;
getbflagsval(0, &contacts->flags);
contacts->path = msg->path_vec;
} else {
/* Insert first branch to first contact */
contacts->uri = uri;
contacts->dst_uri = dst_uri;
contacts->sock = sock;
contacts->flags = flags;
contacts->path = path;
}
contacts->q = first_q;
contacts->next = (struct contact *)0;
/* Insert (remaining) branches to contact list in increasing q order */

@ -402,9 +402,9 @@ static cmd_export_t cmds[]={
{"t_relay_cancel", w_t_relay_cancel, 0, 0,
REQUEST_ROUTE},
{"t_on_failure", w_t_on_negative, 1, fixup_on_failure,
REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE },
REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE },
{"t_on_reply", w_t_on_reply, 1, fixup_on_reply,
REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE },
REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE },
{"t_on_branch", w_t_on_branch, 1, fixup_on_branch,
REQUEST_ROUTE | FAILURE_ROUTE },
{"t_check_status", t_check_status, 1, fixup_t_check_status,
@ -1940,12 +1940,17 @@ int w_t_reply_wrp(struct sip_msg *m, unsigned int code, char *txt)
static int t_check_trans(struct sip_msg* msg, char* foo, char* bar)
{
struct cell* t;
int branch;
int ret;
if (msg->first_line.type==SIP_REPLY)
return w_t_check(msg, 0 ,0);
else if (msg->REQ_METHOD==METHOD_CANCEL)
if (msg->first_line.type==SIP_REPLY) {
branch = 0;
ret = (t_check_msg( msg , &branch)==1) ? 1 : -1;
tm_ctx_set_branch_index(branch);
return ret;
} else if (msg->REQ_METHOD==METHOD_CANCEL) {
return w_t_lookup_cancel(msg, 0, 0);
else{
} else {
switch(t_check_msg(msg, 0)){
case -2: /* possible e2e ack */
return 1;

@ -216,6 +216,8 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
int backup_route_type;
#endif
snd_flags_t snd_flags;
tm_xlinks_t backup_xd;
tm_xdata_t local_xd;
ret=-1;
hi=0; /* make gcc happy */
@ -275,7 +277,13 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
}
#endif /* USE_DNS_FAILOVER */
/* build cell sets X/AVP lists to new transaction structure
* => bakup in a tmp struct and restore afterwards */
memset(&local_xd, 0, sizeof(tm_xdata_t));
tm_xdata_replace(&local_xd, &backup_xd);
new_cell = build_cell(0);
tm_xdata_replace(0, &backup_xd);
if (!new_cell) {
ret=E_OUT_OF_MEM;
LOG(L_ERR, "t_uac: short of cell shmem\n");
@ -352,9 +360,8 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
#ifdef USE_COMP
lreq.rcv.comp=dst.comp;
#endif /* USE_COMP */
/* AVPs are reset anyway afterwards, so no need to
backup/restore them*/
sflag_bk = getsflags();
tm_xdata_swap(new_cell, &backup_xd, 0);
/* run the route */
backup_route_type = get_route_type();
@ -373,6 +380,7 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
set_route_type( backup_route_type );
/* restore original environment */
tm_xdata_swap(new_cell, &backup_xd, 1);
setsflagsval(sflag_bk);
if (unlikely(lreq.new_uri.s))
@ -408,13 +416,6 @@ static inline int t_uac_prepare(uac_req_t *uac_r,
}
#endif
/* better reset avp list now - anyhow, it's useless from
* this point (bogdan) */
reset_avps();
#ifdef WITH_XAVP
xavp_reset_list();
#endif
new_cell->method.s = buf;
new_cell->method.len = uac_r->method->len;

@ -360,8 +360,13 @@ static int mod_init( void )
return -1;
#ifdef SQL_ACC
if (db_url.s)
if (db_url.s) {
db_url.len = strlen(db_url.s);
if(db_url.len<=0) {
db_url.s = NULL;
db_url.len = 0;
}
}
db_table_acc.len = strlen(db_table_acc.s);
db_table_mc.len = strlen(db_table_mc.s);
acc_method_col.len = strlen(acc_method_col.s);
@ -471,8 +476,10 @@ static int mod_init( void )
return -1;
}
} else {
db_flag = 0;
db_missed_flag = 0;
db_url.s = NULL;
db_url.len = 0;
db_flag = -1;
db_missed_flag = -1;
}
#endif
@ -503,8 +510,8 @@ static int mod_init( void )
}
} else {
radius_config = 0;
radius_flag = 0;
radius_missed_flag = 0;
radius_flag = -1;
radius_missed_flag = -1;
}
#endif

@ -88,7 +88,7 @@ acc_extra_t *rad_extra = 0;
static cmd_export_t cmds[] = {
{"acc_rad_request", (cmd_function)w_acc_radius_request, 1,
acc_api_fixup, free_acc_api_fixup,
REQUEST_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
ANY_ROUTE},
{0, 0, 0, 0, 0, 0}
};

@ -347,7 +347,7 @@ modparam("auth_db", "load_credentials", "$avp(i:123)=rpid;email_address")
<title><function moreinfo="none">www_authorize</function> usage</title>
<programlisting format="linespecific">
...
if (www_authorize("kamailio.org", "subscriber")) {
if (!www_authorize("kamailio.org", "subscriber")) {
www_challenge("kamailio.org", "1");
};
...

@ -559,11 +559,18 @@ static int mod_init(void)
return -1;
}
/* sanitize dlg_hash_zie */
if (dlg_hash_size < 1){
LM_WARN("hash_size is smaller "
"then 1 -> rounding from %d to 1\n",
dlg_hash_size);
dlg_hash_size = 1;
}
/* initialized the hash table */
for( n=0 ; n<(8*sizeof(n)) ; n++) {
if (dlg_hash_size==(1<<n))
break;
if (dlg_hash_size<(1<<n)) {
if (n && dlg_hash_size<(1<<n)) {
LM_WARN("hash_size is not a power "
"of 2 as it should be -> rounding from %d to %d\n",
dlg_hash_size, 1<<(n-1));
@ -1089,9 +1096,10 @@ static int w_dlg_get(struct sip_msg *msg, char *ci, char *ft, char *tt)
return -1;
}
dlg = get_dlg(&sc, &sf, &st, &dir, NULL);
dlg = get_dlg(&sc, &sf, &st, &dir);
if(dlg==NULL)
return -1;
/* set current dialog pointer - re-use ref increment from dlg_get() above */
current_dlg_pointer = dlg;
_dlg_ctx.dlg = dlg;
_dlg_ctx.dir = dir;
@ -1154,8 +1162,8 @@ static inline void internal_rpc_print_dlg(rpc_t *rpc, void *c, struct dlg_cell *
{
rpc_cb_ctx_t rpc_cb;
rpc->printf(c, "hash:%u:%u state:%u timestart:%u timeout:%u",
dlg->h_entry, dlg->h_id, dlg->state, dlg->start_ts, dlg->tl.timeout);
rpc->printf(c, "hash:%u:%u state:%u ref_count:%u timestart:%u timeout:%u",
dlg->h_entry, dlg->h_id, dlg->state, dlg->ref, dlg->start_ts, dlg->tl.timeout);
rpc->printf(c, "\tcallid:%.*s from_tag:%.*s to_tag:%.*s",
dlg->callid.len, dlg->callid.s,
dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
@ -1383,7 +1391,7 @@ static void rpc_end_dlg_entry_id(rpc_t *rpc, void *c) {
if (rpc->scan(c, "ddS", &h_entry, &h_id, &rpc_extra_hdrs) < 2) return;
dlg = lookup_dlg(h_entry, h_id, NULL);
dlg = lookup_dlg(h_entry, h_id);
if(dlg){
dlg_bye_all(dlg, (rpc_extra_hdrs.len>0)?&rpc_extra_hdrs:NULL);
unref_dlg(dlg, 1);

@ -403,6 +403,13 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
}while (nr_rows>0);
if (dlg_db_mode==DB_MODE_SHUTDOWN) {
if (dialog_dbf.delete(dialog_db_handle, 0, 0, 0, 0) < 0) {
LM_ERR("failed to clear dialog table\n");
goto error;
}
}
end:
dialog_dbf.free_result(dialog_db_handle, res);
return 0;

@ -534,52 +534,12 @@ static inline int pre_match_parse( struct sip_msg *req, str *callid,
*/
void dlg_onreq(struct cell* t, int type, struct tmcb_params *param)
{
struct dlg_cell *dlg;
str callid;
str ftag;
str ttag;
unsigned int dir;
unsigned int del;
struct sip_msg *req = param->req;
if((req->flags&dlg_flag)!=dlg_flag)
return;
if (current_dlg_pointer!=NULL)
return;
if (!detect_spirals)
goto create;
/* skip initial requests - they may end up here because of the
* preloaded route */
if ( (!req->to && parse_headers(req, HDR_TO_F,0)<0) || !req->to ) {
LM_ERR("bad request or missing TO hdr :-/\n");
return;
}
dlg = 0;
dir = DLG_DIR_NONE;
if (pre_match_parse( req, &callid, &ftag, &ttag, 0)<0) {
LM_WARN("pre-matching failed\n");
return;
}
dlg = get_dlg(&callid, &ftag, &ttag, &dir, &del);
if (del == 1) {
LM_DBG("dialog marked for deletion, ignoring\n");
return;
}
if (!dlg){
LM_DBG("Callid '%.*s' not found, must be a new dialog\n",
req->callid->body.len, req->callid->body.s);
goto create;
}
run_dlg_callbacks( DLGCB_SPIRALED, dlg, req, DLG_DIR_DOWNSTREAM, 0);
unref_dlg(dlg, 1);
return;
create:
dlg_new_dialog(req, t);
}
@ -598,6 +558,18 @@ static void unref_new_dialog(void *dialog)
dlg_onreply(0, TMCB_DESTROY, &p);
}
/*!
* \brief Unreference a dialog (small wrapper to take care of shutdown)
* \see unref_dlg
* \param dialog unreferenced dialog
*/
static void unreference_dialog(void *dialog)
{
// if the dialog table is gone, it means the system is shutting down.
if (!dialog || !d_table)
return;
unref_dlg((struct dlg_cell*)dialog, 1);
}
/*!
* \brief Dummy callback just to keep the compiler happy
@ -610,6 +582,65 @@ void dlg_tmcb_dummy(struct cell* t, int type, struct tmcb_params *param)
return;
}
/*!
* \brief Register a transaction on a dialog
* \param t transaction
* \param type type of the entered callback
* \param param saved dialog structure in the callback
*/
static int store_dlg_in_tm(struct sip_msg* msg,
struct cell* t,
struct dlg_cell *dlg)
{
if( !msg || msg == FAKED_REPLY || !t || !dlg)
{
LM_ERR("invalid parameter msg(%p), t(%p), dlg(%p)\n", msg, t, dlg);
return -1;
}
if(get_dialog_from_tm(t))
{
LM_NOTICE("dialog %p is already set for this transaction!\n",dlg);
return 1;
}
// facilitate referencing of dialog through TMCB_MAX
if( d_tmb.register_tmcb (msg,
t,
TMCB_MAX,
dlg_tmcb_dummy,
(void*)dlg, unreference_dialog)<0 )
{
LM_ERR("failed cache in T the shortcut to dlg %p\n",dlg);
return -3;
}
// registering succeeded, we must increase the reference counter
ref_dlg(dlg, 1);
return 0;
}
/*!
* \brief Callback to register a transaction on a dialog
* \param t transaction, unused
* \param type type of the entered callback
* \param param saved dialog structure in the callback
*/
static void store_dlg_in_tm_cb (struct cell* t,
int type,
struct tmcb_params *param)
{
struct dlg_cell *dlg = (struct dlg_cell *)(*param->param);
struct sip_msg* msg = param->rpl;
if (msg == NULL || msg == FAKED_REPLY)
{
msg = param->req;
}
store_dlg_in_tm (msg, t, dlg);
}
/*!
* \brief Create a new dialog from a sip message
@ -628,32 +659,26 @@ int dlg_new_dialog(struct sip_msg *msg, struct cell *t)
{
struct dlg_cell *dlg;
str s;
str req_uri;
str callid;
str ftag;
str ttag;
str req_uri;
unsigned int dir;
int spiral_detected;
if((msg->to==NULL && parse_headers(msg, HDR_TO_F,0)<0) || msg->to==NULL)
{
LM_ERR("bad request or missing TO hdr\n");
return -1;
}
s = get_to(msg)->tag_value;
if(s.s!=0 && s.len!=0)
if(current_dlg_pointer != NULL)
return -1;
if(msg->first_line.u.request.method_value==METHOD_CANCEL)
return -1;
if(parse_from_header(msg))
{
LM_ERR("bad request or missing FROM hdr\n");
if(pre_match_parse( msg, &callid, &ftag, &ttag, 0)<0) {
LM_WARN("pre-matching failed\n");
return -1;
}
if((msg->callid==NULL && parse_headers(msg,HDR_CALLID_F,0)<0)
|| msg->callid==NULL){
LM_ERR("bad request or missing CALLID hdr\n");
if(ttag.s!=0 && ttag.len!=0)
return -1;
}
s = msg->callid->body;
trim(&s);
if (pv_printf_s(msg, ruri_param_model, &req_uri)<0) {
LM_ERR("error - cannot print the r-uri format\n");
@ -661,17 +686,34 @@ int dlg_new_dialog(struct sip_msg *msg, struct cell *t)
}
trim(&req_uri);
/* some sanity checks */
if (s.len==0 || get_from(msg)->tag_value.len==0) {
LM_ERR("invalid request -> callid (%d) or from TAG (%d) empty\n",
s.len, get_from(msg)->tag_value.len);
return -1;
if (detect_spirals)
{
dir = DLG_DIR_NONE;
dlg = get_dlg(&callid, &ftag, &ttag, &dir);
if (dlg)
{
LM_DBG("Callid '%.*s' found, must be a spiraled request\n",
callid.len, callid.s);
spiral_detected = 1;
run_dlg_callbacks( DLGCB_SPIRALED, dlg, msg, DLG_DIR_DOWNSTREAM, 0);
// get_dlg with del==0 has incremented the ref count by 1
unref_dlg(dlg, 1);
goto finish;
}
}
spiral_detected = 0;
dlg = build_new_dlg(&s /*callid*/, &(get_from(msg)->uri) /*from uri*/,
&(get_to(msg)->uri) /*to uri*/,
&(get_from(msg)->tag_value)/*from_tag*/, &req_uri /*r-uri*/ );
if (dlg==0) {
dlg = build_new_dlg (&callid /*callid*/,
&(get_from(msg)->uri) /*from uri*/,
&(get_to(msg)->uri) /*to uri*/,
&ftag/*from_tag*/,
&req_uri /*r-uri*/ );
if (dlg==0)
{
LM_ERR("failed to create new dialog\n");
return -1;
}
@ -685,10 +727,10 @@ int dlg_new_dialog(struct sip_msg *msg, struct cell *t)
return -1;
}
set_current_dialog(msg, dlg);
_dlg_ctx.dlg = dlg;
link_dlg(dlg, 2/* extra ref for the callback and current dlg hook */);
link_dlg(dlg,0);
run_create_callbacks(dlg, msg);
/* first INVITE seen (dialog created, unconfirmed) */
if ( seq_match_mode!=SEQ_MATCH_NO_ID &&
@ -703,6 +745,8 @@ int dlg_new_dialog(struct sip_msg *msg, struct cell *t)
LM_ERR("failed to register TMCB\n");
goto error;
}
// increase reference counter because of registered callback
ref_dlg(dlg, 1);
dlg->lifetime = get_dlg_timeout(msg);
s.s = _dlg_ctx.to_route_name;
@ -713,23 +757,36 @@ int dlg_new_dialog(struct sip_msg *msg, struct cell *t)
if (_dlg_ctx.to_bye!=0)
dlg->dflags |= DLG_FLAG_TOBYE;
if ( d_tmb.register_tmcb( msg, t, TMCB_MAX,
dlg_tmcb_dummy, (void*)dlg, 0)<0 ) {
LM_ERR("failed cache in T the shortcut to dlg\n");
goto error;
}
#if 0
t->dialog_ctx = (void*) dlg;
#endif
if_update_stat( dlg_enable_stats, processed_dlgs, 1);
run_create_callbacks( dlg, msg);
finish:
if (t) {
// transaction exists ==> keep ref counter large enough to
// avoid premature cleanup and ensure proper dialog referencing
if (store_dlg_in_tm( msg, t, dlg) < 0) {
LM_ERR("failed to store dialog in transaction\n");
goto error;
}
}
else
{
// no transaction exists ==> postpone work until we see the
// request being forwarded statefully
if ( d_tmb.register_tmcb( msg, NULL, TMCB_REQUEST_FWDED,
store_dlg_in_tm_cb, (void*)dlg, NULL)<0 ) {
LM_ERR("failed to register callback for storing dialog in transaction\n");
}
}
if_update_stat( dlg_enable_stats, processed_dlgs, 1);
set_current_dialog(msg, dlg);
_dlg_ctx.dlg = dlg;
ref_dlg(dlg, 1);
return 0;
error:
unref_dlg(dlg,1);
profile_cleanup(msg, 0, NULL);
if (!spiral_detected)
unref_dlg(dlg,1); // undo ref regarding linking
return -1;
}
@ -792,21 +849,6 @@ static inline int update_cseqs(struct dlg_cell *dlg, struct sip_msg *req,
}
}
/*!
* \brief Unreference a dialog, small wrapper to care for shutdown
* \see unref_dlg
* \param dialog unreferenced dialog
*/
static void unreference_dialog(void *dialog)
{
// if the dialog table is gone, it means the system is shutting down.
if (!d_table)
return;
unref_dlg((struct dlg_cell*)dialog, 1);
}
/*!
* \brief Unreference a dialog from tm callback (another wrapper)
* \param t transaction, unused
@ -842,7 +884,6 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
str val, callid, ftag, ttag;
int h_entry, h_id, new_state, old_state, unref, event, timeout;
unsigned int dir;
unsigned int del;
int ret = 0;
if (current_dlg_pointer!=NULL)
@ -871,11 +912,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
if ( parse_dlg_rr_param( val.s, val.s+val.len, &h_entry, &h_id)<0 )
return;
dlg = lookup_dlg( h_entry, h_id, &del);
if (del == 1) {
LM_DBG("dialog marked for deletion, ignoring\n");
return;
}
dlg = lookup_dlg( h_entry, h_id);
if (dlg==0) {
LM_WARN("unable to find dialog for %.*s "
"with route param '%.*s' [%u:%u]\n",
@ -885,8 +922,8 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
if (seq_match_mode==SEQ_MATCH_STRICT_ID )
return;
} else {
// lookup_dlg has incremented the ref count by 1
if (pre_match_parse( req, &callid, &ftag, &ttag, 1)<0) {
// lookup_dlg has incremented the ref count by 1
unref_dlg(dlg, 1);
return;
}
@ -905,6 +942,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
dlg->tag[DLG_CALLER_LEG].len,
dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s,
dlg->tag[DLG_CALLEE_LEG].len);
// lookup_dlg has incremented the ref count by 1
unref_dlg(dlg, 1);
// Reset variables in order to do a lookup based on SIP-Elements.
@ -923,11 +961,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
return;
/* TODO - try to use the RR dir detection to speed up here the
* search -bogdan */
dlg = get_dlg(&callid, &ftag, &ttag, &dir, &del);
if (del == 1) {
LM_DBG("dialog marked for deletion, ignoring\n");
return;
}
dlg = get_dlg(&callid, &ftag, &ttag, &dir);
if (!dlg){
LM_DBG("Callid '%.*s' not found\n",
req->callid->body.len, req->callid->body.s);
@ -935,6 +969,15 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
}
}
/* set current dialog - re-use ref increment from dlg_get() above */
set_current_dialog( req, dlg);
_dlg_ctx.dlg = dlg;
if ( d_tmb.register_tmcb( req, NULL, TMCB_REQUEST_FWDED,
store_dlg_in_tm_cb, (void*)dlg, NULL)<0 ) {
LM_ERR("failed to store dialog in transaction during dialog creation for later reference\n");
}
/* run state machine */
switch ( req->first_line.u.request.method_value ) {
case METHOD_PRACK:
@ -953,10 +996,6 @@ 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;
/* set current dialog - it will keep a ref! */
set_current_dialog( req, dlg);
_dlg_ctx.dlg = dlg;
/* delay deletion of dialog until transaction has died off in order
* to absorb in-air messages */
if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
@ -992,12 +1031,6 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
unref++;
}
/* dialog terminated (BYE) */
run_dlg_callbacks( DLGCB_TERMINATED, dlg, req, dir, 0);
/* delete the dialog from DB */
if (dlg_db_mode)
remove_dialog_from_db(dlg);
unref_dlg(dlg, unref);
if_update_stat( dlg_enable_stats, active_dlgs, -1);
@ -1098,11 +1131,7 @@ void dlg_ontimeout( struct dlg_tl *tl)
dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
/* dialog timeout */
run_dlg_callbacks( DLGCB_EXPIRED, dlg, 0, DLG_DIR_NONE, 0);
/* delete the dialog from DB */
if (dlg_db_mode)
remove_dialog_from_db(dlg);
run_dlg_callbacks( DLGCB_EXPIRED, dlg, NULL, DLG_DIR_NONE, 0);
unref_dlg(dlg, unref+1);

@ -61,6 +61,7 @@
#include "dlg_hash.h"
#include "dlg_profile.h"
#include "dlg_req_within.h"
#include "dlg_db_handler.h"
#define MAX_LDG_LOCKS 2048
#define MIN_LDG_LOCKS 2
@ -70,6 +71,49 @@
struct dlg_table *d_table = 0;
/*!
* \brief Reference a dialog without locking
* \param _dlg dialog
* \param _cnt increment for the reference counter
*/
#define ref_dlg_unsafe(_dlg,_cnt) \
do { \
(_dlg)->ref += (_cnt); \
LM_DBG("ref dlg %p with %d -> %d\n", \
(_dlg),(_cnt),(_dlg)->ref); \
}while(0)
/*!
* \brief Unreference a dialog without locking
* \param _dlg dialog
* \param _cnt decrement for the reference counter
* \param _d_entry dialog entry
*/
#define unref_dlg_unsafe(_dlg,_cnt,_d_entry) \
do { \
(_dlg)->ref -= (_cnt); \
LM_DBG("unref dlg %p with %d -> %d\n",\
(_dlg),(_cnt),(_dlg)->ref);\
if ((_dlg)->ref<0) {\
LM_CRIT("bogus ref %d with cnt %d for dlg %p [%u:%u] "\
"with clid '%.*s' and tags '%.*s' '%.*s'\n",\
(_dlg)->ref, _cnt, _dlg,\
(_dlg)->h_entry, (_dlg)->h_id,\
(_dlg)->callid.len, (_dlg)->callid.s,\
(_dlg)->tag[DLG_CALLER_LEG].len,\
(_dlg)->tag[DLG_CALLER_LEG].s,\
(_dlg)->tag[DLG_CALLEE_LEG].len,\
(_dlg)->tag[DLG_CALLEE_LEG].s); \
}\
if ((_dlg)->ref<=0) { \
unlink_unsafe_dlg( _d_entry, _dlg);\
LM_DBG("ref <=0 for dialog %p\n",_dlg);\
destroy_dlg(_dlg);\
}\
}while(0)
/*!
* \brief Initialize the global dialog table
* \param size size of the table
@ -154,6 +198,10 @@ inline void destroy_dlg(struct dlg_cell *dlg)
run_dlg_callbacks( DLGCB_DESTROY , dlg, 0, DLG_DIR_NONE, 0);
/* delete the dialog from DB*/
if (dlg_db_mode)
remove_dialog_from_db(dlg);
if(dlg==get_current_dlg_pointer())
reset_current_dlg_pointer();
@ -370,18 +418,18 @@ error:
/*!
* \brief Lookup a dialog in the global list
*
* Note that the caller is responsible for decrementing (or reusing)
* the reference counter by one again iff a dialog has been found.
* \param h_entry number of the hash table entry
* \param h_id id of the hash table entry
* \return dialog on success, NULL on failure
*/
struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id, unsigned int *del)
struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id)
{
struct dlg_cell *dlg;
struct dlg_entry *d_entry;
if (del != NULL)
*del = 0;
if (h_entry>=d_table->size)
goto not_found;
@ -391,14 +439,7 @@ struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id, unsigned i
for( dlg=d_entry->first ; dlg ; dlg=dlg->next ) {
if (dlg->h_id == h_id) {
if (dlg->state==DLG_STATE_DELETED) {
if (del != NULL)
*del = 1;
dlg_unlock( d_table, d_entry);
goto not_found;
}
dlg->ref++;
LM_DBG("ref dlg %p with 1 -> %d\n", dlg, dlg->ref);
ref_dlg_unsafe(dlg, 1);
dlg_unlock( d_table, d_entry);
LM_DBG("dialog id=%u found on entry %u\n", h_id, h_entry);
return dlg;
@ -422,15 +463,11 @@ not_found:
* \return dialog structure on success, NULL on failure
*/
static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
str *callid, str *ftag, str *ttag, unsigned int *dir,
unsigned int *del)
str *callid, str *ftag, str *ttag, unsigned int *dir)
{
struct dlg_cell *dlg;
struct dlg_entry *d_entry;
if (del != NULL)
*del = 0;
d_entry = &(d_table->entries[h_entry]);
dlg_lock( d_table, d_entry);
@ -438,14 +475,7 @@ static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
for( dlg = d_entry->first ; dlg ; dlg = dlg->next ) {
/* Check callid / fromtag / totag */
if (match_dialog( dlg, callid, ftag, ttag, dir)==1) {
if (dlg->state==DLG_STATE_DELETED) {
if (del != NULL)
*del = 1;
dlg_unlock( d_table, d_entry);
goto not_found;
}
dlg->ref++;
LM_DBG("ref dlg %p with 1 -> %d\n", dlg, dlg->ref);
ref_dlg_unsafe(dlg, 1);
dlg_unlock( d_table, d_entry);
LM_DBG("dialog callid='%.*s' found\n on entry %u, dir=%d\n",
callid->len, callid->s,h_entry,*dir);
@ -454,8 +484,6 @@ static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
}
dlg_unlock( d_table, d_entry);
not_found:
LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
return 0;
}
@ -470,21 +498,22 @@ not_found:
* "The combination of the To tag, From tag, and Call-ID completely
* defines a peer-to-peer SIP relationship between [two UAs] and is
* referred to as a dialog."
* Note that the caller is responsible for decrementing (or reusing)
* the reference counter by one again iff a dialog has been found.
* \param callid callid
* \param ftag from tag
* \param ttag to tag
* \param dir direction
* \return dialog structure on success, NULL on failure
*/
struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir,
unsigned int *del)
struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir)
{
struct dlg_cell *dlg;
if ((dlg = internal_get_dlg(core_hash(callid, 0,
d_table->size), callid, ftag, ttag, dir, del)) == 0 &&
d_table->size), callid, ftag, ttag, dir)) == 0 &&
(dlg = internal_get_dlg(core_hash(callid, ttag->len
?ttag:0, d_table->size), callid, ftag, ttag, dir, del)) == 0) {
?ttag:0, d_table->size), callid, ftag, ttag, dir)) == 0) {
LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s);
return 0;
}
@ -514,57 +543,13 @@ void link_dlg(struct dlg_cell *dlg, int n)
d_entry->last = dlg;
}
dlg->ref += 1 + n;
LM_DBG("ref dlg %p with %d -> %d\n", dlg, n+1, dlg->ref);
ref_dlg_unsafe(dlg, 1+n);
dlg_unlock( d_table, d_entry);
return;
}
/*!
* \brief Reference a dialog without locking
* \param _dlg dialog
* \param _cnt increment for the reference counter
*/
#define ref_dlg_unsafe(_dlg,_cnt) \
do { \
(_dlg)->ref += (_cnt); \
LM_DBG("ref dlg %p with %d -> %d\n", \
(_dlg),(_cnt),(_dlg)->ref); \
}while(0)
/*!
* \brief Unreference a dialog without locking
* \param _dlg dialog
* \param _cnt decrement for the reference counter
*/
#define unref_dlg_unsafe(_dlg,_cnt,_d_entry) \
do { \
(_dlg)->ref -= (_cnt); \
LM_DBG("unref dlg %p with %d -> %d\n",\
(_dlg),(_cnt),(_dlg)->ref);\
if ((_dlg)->ref<0) {\
LM_CRIT("bogus ref %d with cnt %d for dlg %p [%u:%u] "\
"with clid '%.*s' and tags '%.*s' '%.*s'\n",\
(_dlg)->ref, _cnt, _dlg,\
(_dlg)->h_entry, (_dlg)->h_id,\
(_dlg)->callid.len, (_dlg)->callid.s,\
(_dlg)->tag[DLG_CALLER_LEG].len,\
(_dlg)->tag[DLG_CALLER_LEG].s,\
(_dlg)->tag[DLG_CALLEE_LEG].len,\
(_dlg)->tag[DLG_CALLEE_LEG].s); \
}\
if ((_dlg)->ref<=0) { \
unlink_unsafe_dlg( _d_entry, _dlg);\
LM_DBG("ref <=0 for dialog %p\n",_dlg);\
destroy_dlg(_dlg);\
}\
}while(0)
/*!
* \brief Refefence a dialog with locking
* \see ref_dlg_unsafe
@ -826,6 +811,11 @@ static inline int internal_mi_print_dlg(struct mi_node *rpl,
if (node1==0)
goto error;
p= int2str((unsigned long)dlg->ref, &len);
node1 = add_mi_node_child( node, MI_DUP_VALUE, "ref_count", 9, p, len);
if (node1==0)
goto error;
p= int2str((unsigned long)dlg->start_ts, &len);
node1 = add_mi_node_child(node,MI_DUP_VALUE,"timestart",9, p, len);
if (node1==0)
@ -869,11 +859,25 @@ static inline int internal_mi_print_dlg(struct mi_node *rpl,
if(node1 == 0)
goto error;
node1 = add_mi_node_child(node, 0,"caller_bind_addr",16,
dlg->bind_addr[DLG_CALLER_LEG]->sock_str.s,
if (dlg->bind_addr[DLG_CALLER_LEG]) {
node1 = add_mi_node_child(node, 0,
"caller_bind_addr",16,
dlg->bind_addr[DLG_CALLER_LEG]->sock_str.s,
dlg->bind_addr[DLG_CALLER_LEG]->sock_str.len);
if(node1 == 0)
goto error;
} else {
node1 = add_mi_node_child(node, 0,
"caller_bind_addr",16,0,0);
}
if (dlg->bind_addr[DLG_CALLEE_LEG]) {
node1 = add_mi_node_child(node, 0,
"callee_bind_addr",16,
dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.s,
dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.len);
} else {
node1 = add_mi_node_child(node, 0,
"callee_bind_addr",16,0,0);
}
node1 = add_mi_node_child(node, MI_DUP_VALUE, "to_uri", 6,
dlg->to_uri.s, dlg->to_uri.len);
@ -903,18 +907,6 @@ static inline int internal_mi_print_dlg(struct mi_node *rpl,
if(node1 == 0)
goto error;
if (dlg->bind_addr[DLG_CALLEE_LEG]) {
node1 = add_mi_node_child(node, 0,
"callee_bind_addr",16,
dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.s,
dlg->bind_addr[DLG_CALLEE_LEG]->sock_str.len);
} else {
node1 = add_mi_node_child(node, 0,
"callee_bind_addr",16,0,0);
}
if(node1 == 0)
goto error;
if (with_context) {
node1 = add_mi_node_child(node, 0, "context", 7, 0, 0);
if(node1 == 0)

@ -250,12 +250,14 @@ int dlg_set_toroute(struct dlg_cell *dlg, str *route);
/*!
* \brief Lookup a dialog in the global list
*
* Note that the caller is responsible for decrementing (or reusing)
* the reference counter by one again iff a dialog has been found.
* \param h_entry number of the hash table entry
* \param h_id id of the hash table entry
* \param del unless null, flag that is set if dialog is in "deleted" state
* \return dialog on success, NULL on failure
*/
struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id, unsigned int *del);
struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id);
/*!
@ -266,14 +268,15 @@ struct dlg_cell* lookup_dlg( unsigned int h_entry, unsigned int h_id, unsigned i
* "The combination of the To tag, From tag, and Call-ID completely
* defines a peer-to-peer SIP relationship between [two UAs] and is
* referred to as a dialog."
* Note that the caller is responsible for decrementing (or reusing)
* the reference counter by one again iff a dialog has been found.
* \param callid callid
* \param ftag from tag
* \param ttag to tag
* \param dir direction
* \param del unless null, flag that is set if dialog is in "deleted" state
* \return dialog structure on success, NULL on failure
*/
struct dlg_cell* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir, unsigned int *del);
struct dlg_cell* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
/*!

@ -327,17 +327,33 @@ int profile_cleanup( struct sip_msg *msg, unsigned int flags, void *param )
}
struct dlg_cell* get_dialog_from_tm(struct cell *t)
{
if (t==NULL || t==T_UNDEFINED)
return NULL;
struct tm_callback* x = (struct tm_callback*)(t->tmcb_hl.first);
while(x){
membar_depends();
if (x->types==TMCB_MAX && x->callback==dlg_tmcb_dummy){
return (struct dlg_cell*)(x->param);
}
x=x->next;
}
return NULL;
}
/*!
* \brief Get the current dialog for a message, if exists
* \param msg SIP message
* \return NULL if called in REQUEST_ROUTE, pointer to dialog ctx otherwise
*/
static struct dlg_cell *get_current_dialog(struct sip_msg *msg)
struct dlg_cell *get_current_dialog(struct sip_msg *msg)
{
struct cell *trans;
struct tm_callback* x;
if (is_route_type(REQUEST_ROUTE)) {
if (is_route_type(REQUEST_ROUTE|BRANCH_ROUTE)) {
/* use the per-process static holder */
if (msg->id==current_dlg_msg_id)
return current_dlg_pointer;
@ -348,18 +364,7 @@ static struct dlg_cell *get_current_dialog(struct sip_msg *msg)
return NULL;
} else {
/* use current transaction to get dialog */
trans = d_tmb.t_gett();
if (trans==NULL || trans==T_UNDEFINED)
return NULL;
x=(struct tm_callback*)(trans->tmcb_hl.first);
while(x){
membar_depends();
if (x->types==TMCB_MAX && x->callback==dlg_tmcb_dummy){
return (struct dlg_cell*)(x->param);
}
x=x->next;
}
return NULL;
return get_dialog_from_tm(d_tmb.t_gett());
}
}
@ -460,6 +465,9 @@ void set_current_dialog(struct sip_msg *msg, struct dlg_cell *dlg)
}
current_pending_linkers = NULL;
current_dlg_pointer = dlg;
/* do not increase reference counter here, let caller handle it
* (yes, this is somewhat ugly) */
}

@ -33,6 +33,8 @@
#include "../../parser/msg_parser.h"
#include "../../locking.h"
#include "../../str.h"
#include "../../modules/tm/h_table.h"
/*!
@ -83,6 +85,10 @@ struct dlg_cell *get_current_dlg_pointer(void);
void reset_current_dlg_pointer(void);
struct dlg_cell* get_dialog_from_tm(struct cell *t);
struct dlg_cell *get_current_dialog(struct sip_msg *msg);
/*!
* \brief Add profile definitions to the global list
* \see new_dlg_profile

@ -318,7 +318,7 @@ struct mi_root * mi_terminate_dlg(struct mi_root *cmd_tree, void *param ){
LM_DBG("h_entry %u h_id %u\n", h_entry, h_id);
dlg = lookup_dlg(h_entry, h_id, NULL);
dlg = lookup_dlg(h_entry, h_id);
// lookup_dlg has incremented the reference count

@ -133,9 +133,9 @@ int insert_dlg_timer(struct dlg_tl *tl, int interval)
lock_get( d_timer->lock);
if (tl->next!=0 || tl->prev!=0) {
lock_release( d_timer->lock);
LM_CRIT("Trying to insert a bogus dlg tl=%p tl->next=%p tl->prev=%p\n",
tl, tl->next, tl->prev);
lock_release( d_timer->lock);
return -1;
}
tl->timeout = get_ticks()+interval;
@ -202,14 +202,13 @@ int update_dlg_timer(struct dlg_tl *tl, int timeout)
{
lock_get( d_timer->lock);
if ( tl->next ) {
if (tl->prev==0) {
lock_release( d_timer->lock);
return -1;
}
remove_dialog_timer_unsafe(tl);
if (tl->next==0 || tl->prev==0) {
LM_CRIT("Trying to update a bogus dlg tl=%p tl->next=%p tl->prev=%p\n",
tl, tl->next, tl->prev);
lock_release( d_timer->lock);
return -1;
}
remove_dialog_timer_unsafe( tl );
tl->timeout = get_ticks()+timeout;
insert_dialog_timer_unsafe( tl );

@ -341,9 +341,9 @@ modparam("dialog", "dlg_match_mode", 1)
<example>
<title>Set <varname>detect_spirals</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("dialog", "detect_spirals", 1)
...
...
modparam("dialog", "detect_spirals", 1)
...
</programlisting>
</example>
</section>

@ -52,7 +52,8 @@
</listitem>
<listitem>
<para><emphasis>DLGCB_CONFIRMED</emphasis> - called when the
dialog is confirmed (2xx replied) - it's a per dialog type.
dialog is confirmed (2xx replied) and the setup-concluding ACK
message from the caller has been seen - it's a per dialog type.
</para>
</listitem>
<listitem>

@ -349,7 +349,6 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
if (he==0)
{
LM_ERR("could not resolve %.*s\n", puri.host.len, puri.host.s);
pkg_free(hn);
goto err;
}
/* Free the hostname */
@ -841,7 +840,8 @@ void destroy_list(int list_id)
dest->uri.s = NULL;
}
}
shm_free(sp->dlist);
if (sp->dlist != NULL)
shm_free(sp->dlist);
sp = sp->next;
}
@ -1954,9 +1954,9 @@ int ds_next_dst(struct sip_msg *msg, int mode)
{
prev_avp = search_first_avp(dstid_avp_type, dstid_avp_name,
&avp_value, &st);
if(prev_avp!=NULL)
if(prev_avp==NULL)
{
LM_ERR("cannot uid for dst addr\n");
LM_ERR("cannot find uid avp for destination address\n");
return -1;
}
if(ds_load_replace(msg, &avp_value.s)<0)

@ -117,6 +117,10 @@ int get_username_domain(struct sip_msg *msg, group_check_p gcp,
}
turi = &puri;
break;
default: {
LM_ERR("incorrect check id %d\n", gcp->id);
return -1;
}
}
if (gcp->id != 4) {

@ -108,7 +108,7 @@ int ht_db_load_table(ht_t *ht, str *dbtable, int mode)
{
db_key_t db_cols[4] = {&ht_db_name_column, &ht_db_ktype_column,
&ht_db_vtype_column, &ht_db_value_column};
db_key_t db_ord = &ht_db_ktype_column;
db_key_t db_ord = &ht_db_name_column;
db1_res_t* db_res = NULL;
str kname;
str pname;
@ -183,64 +183,54 @@ int ht_db_load_table(ht_t *ht, str *dbtable, int mode)
cnt++;
/* not NULL values enforced in table definition ?!?! */
kname.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val);
if(kname.s==NULL) {
LM_ERR("null key in row %d\n", i);
goto error;
}
kname.len = strlen(kname.s);
ktype = RES_ROWS(db_res)[i].values[1].val.int_val;
if(ktype==0 && last_ktype==1)
if(last_ktype==1)
{
snprintf(ht_name_buf, HT_NAME_BUF_SIZE, "%.*s%.*s",
pname.len, pname.s, ht_array_size_suffix.len,
ht_array_size_suffix.s);
hname.s = ht_name_buf;
hname.len = strlen(ht_name_buf);
val.n = n+1;
if(ht_set_cell(ht, &hname, 0, &val, mode))
if(pname.len>0
&& (pname.len!=kname.len
|| strncmp(pname.s, kname.s, pname.len)!=0))
{
LM_ERR("error adding array size to hash table.\n");
goto error;
/* new key name, last was an array => add its size */
snprintf(ht_name_buf, HT_NAME_BUF_SIZE, "%.*s%.*s",
pname.len, pname.s, ht_array_size_suffix.len,
ht_array_size_suffix.s);
hname.s = ht_name_buf;
hname.len = strlen(ht_name_buf);
val.n = n;
if(ht_set_cell(ht, &hname, 0, &val, mode))
{
LM_ERR("error adding array size to hash table.\n");
goto error;
}
pname.len = 0;
pname.s = "";
n = 0;
}
pname.len = 0;
pname.s = "";
n = 0;
}
last_ktype = ktype;
pname = kname;
if(ktype==1)
{
if(pname.len!=kname.len
|| strncmp(pname.s, kname.s, pname.len))
{
/* add count */
if(pname.len > 0)
{
/* perhaps some opt can be done here */
snprintf(ht_name_buf, HT_NAME_BUF_SIZE, "%.*s%.*s",
pname.len, pname.s, ht_array_size_suffix.len,
ht_array_size_suffix.s);
hname.s = ht_name_buf;
hname.len = strlen(ht_name_buf);
val.n = n+1;
if(ht_set_cell(ht, &hname, 0, &val, mode))
{
LM_ERR("error adding array size to hash table\n");
goto error;
}
}
/* reset */
pname = kname;
n=0;
} else {
n++;
}
snprintf(ht_name_buf, HT_NAME_BUF_SIZE, "%.*s[%d]",
kname.len, kname.s, n);
hname.s = ht_name_buf;
hname.len = strlen(ht_name_buf);
n++;
} else {
hname = kname;
}
last_ktype = ktype;
vtype = RES_ROWS(db_res)[i].values[2].val.int_val;
kvalue.s = (char*)(RES_ROWS(db_res)[i].values[3].val.string_val);
if(kvalue.s==NULL) {
LM_ERR("null value in row %d\n", i);
goto error;
}
kvalue.len = strlen(kvalue.s);
/* add to hash */
@ -272,7 +262,7 @@ int ht_db_load_table(ht_t *ht, str *dbtable, int mode)
ht_array_size_suffix.s);
hname.s = ht_name_buf;
hname.len = strlen(ht_name_buf);
val.n = n+1;
val.n = n;
if(ht_set_cell(ht, &hname, 0, &val, mode))
{
LM_ERR("error adding array size to hash table.\n");

@ -176,7 +176,6 @@ int pv_get_ht_cell_expire(struct sip_msg *msg, pv_param_t *param,
pv_value_t *res)
{
str htname;
ht_cell_t *htc=NULL;
ht_pv_t *hpv;
unsigned int now;
@ -196,7 +195,7 @@ int pv_get_ht_cell_expire(struct sip_msg *msg, pv_param_t *param,
if(ht_get_cell_expire(hpv->ht, &htname, &now)!=0)
return pv_get_null(msg, param, res);
/* integer */
return pv_get_uintval(msg, param, res, htc->value.n);
return pv_get_uintval(msg, param, res, now);
}
int pv_set_ht_cell_expire(struct sip_msg* msg, pv_param_t *param,

@ -437,7 +437,7 @@ static int mod_init(void)
*/
static int child_init(int rank)
{
if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN)
if (rank==PROC_INIT || rank==PROC_TCP_MAIN)
return 0; /* do nothing for the main process */
if (imc_dbf.init==0)

@ -326,13 +326,22 @@ int imc_handle_join(struct sip_msg* msg, imc_cmd_t *cmd,
build_inform:
/* send info message */
body.s = imc_body_buf;
body.len = snprintf(body.s, IMC_BUF_SIZE, "*** <%.*s> has joined the room",
member->uri.len, member->uri.s);
if(member!=NULL)
{
body.len = snprintf(body.s, IMC_BUF_SIZE,
"*** <%.*s@%.*s> has joined the room",
src->user.len, src->user.s, src->host.len, src->host.s);
} else {
body.len = snprintf(body.s, IMC_BUF_SIZE,
"*** <%.*s@%.*s> attempted to join the room",
src->user.len, src->user.s, src->host.len, src->host.s);
}
if(body.len>0)
imc_room_broadcast(room, &all_hdrs, &body);
if(body.len>=IMC_BUF_SIZE)
LM_ERR("member name %.*s truncated\n", member->uri.len, member->uri.s);
LM_ERR("member name %.*s@%.*s truncated\n",
src->user.len, src->user.s, src->host.len, src->host.s);
done:
if(room!=NULL)

@ -48,6 +48,7 @@
#include <signal.h>
#include "../../resolve.h"
#include "../../cfg/cfg_struct.h"
#include "mi_datagram.h"
#include "datagram_fnc.h"
#include "mi_datagram_parser.h"
@ -434,6 +435,9 @@ void mi_datagram_server(int rx_sock, int tx_sock)
f = 0;
while(1) { /*read the datagram*/
/* update the local config framework structures */
cfg_update();
memset(mi_buf, 0, DATAGRAM_SOCK_BUF_SIZE);
reply_addr_len = sizeof(reply_addr);

@ -56,6 +56,7 @@
#include "../../lib/kmi/mi.h"
#include "../../ip_addr.h"
#include "../../pt.h"
#include "../../cfg/cfg_struct.h"
#include "mi_datagram.h"
#include "datagram_fnc.h"
#include "mi_datagram_parser.h"
@ -253,6 +254,8 @@ static int mi_mod_init(void)
done:
/* add space for extra processes */
register_procs(mi_procs[0].no);
/* add child to update local config framework structures */
cfg_register_child(mi_procs[0].no);
return 0;
}
@ -282,6 +285,11 @@ static int mi_child_init(int rank)
return -1; /* error */
if(pid==0) {
/* child */
/* initialize the config framework */
if (cfg_child_init())
return -1;
datagram_process(i);
return 0;
}

@ -47,6 +47,7 @@
#include "../../lib/kmi/mi.h"
#include "../../mem/mem.h"
#include "../../mem/shm_mem.h"
#include "../../cfg/cfg_struct.h"
#include "mi_fifo.h"
#include "fifo_fnc.h"
#include "mi_parser.h"
@ -409,6 +410,9 @@ void mi_fifo_server(FILE *fifo_stream)
FILE *reply_stream;
while(1) {
/* update the local config framework structures */
cfg_update();
reply_stream = NULL;
/* commands must look this way ':<command>:[filename]' */

@ -46,6 +46,7 @@
#include "../../pt.h"
#include "../../mem/mem.h"
#include "../../mem/shm_mem.h"
#include "../../cfg/cfg_struct.h"
#include "../../lib/kmi/mi.h"
#include "mi_fifo.h"
#include "mi_parser.h"
@ -174,6 +175,9 @@ static int mi_mod_init(void)
/* add space for one extra process */
register_procs(1);
/* add child to update local config framework structures */
cfg_register_child(1);
return 0;
}
@ -196,6 +200,11 @@ static int mi_child_init(int rank)
return -1; /* error */
if(pid==0){
/* child */
/* initialize the config framework */
if (cfg_child_init())
return -1;
fifo_process(1);
}
}

@ -65,6 +65,7 @@
#include "../../pt.h"
#include "../../mem/mem.h"
#include "../../mem/shm_mem.h"
#include "../../cfg/cfg_struct.h"
xmlrpc_env env;
xmlrpc_value * xr_response;
@ -134,6 +135,9 @@ static int mod_init(void)
/* add space for extra processes */
register_procs(1);
/* add child to update local config framework structures */
cfg_register_child(1);
return 0;
}
@ -146,6 +150,11 @@ static int child_init(int rank)
return -1; /* error */
if(pid==0){
/* child */
/* initialize the config framework */
if (cfg_child_init())
return -1;
xmlrpc_process(1);
}
}

@ -35,6 +35,7 @@
#include "../../mem/shm_mem.h"
#include "../../locking.h"
#include "../../ut.h"
#include "../../cfg/cfg_struct.h"
#include "xr_writer.h"
#include "xr_parser.h"
#include "mi_xmlrpc.h"
@ -177,6 +178,9 @@ xmlrpc_value* default_method (xmlrpc_env* env,
LM_DBG("starting up.....\n");
/* update the local config framework structures */
cfg_update();
f = lookup_mi_cmd((char*)methodName, strlen(methodName));
if ( f == 0 ) {

@ -1809,7 +1809,7 @@ mod_init(void)
LM_NOTICE("using 10 seconds for keepalive_interval\n");
keepalive_interval = 10;
}
register_procs(1);
register_dummy_timers(1);
return 0;
}

@ -649,7 +649,7 @@ mod_init(void)
init_sip_ping();
}
register_procs(natping_processes);
register_dummy_timers(natping_processes);
}
/* Prepare 1918 networks list */

@ -208,9 +208,9 @@ void path_rr_callback(struct sip_msg *_m, str *r_param, void *cb_param)
{
param_hooks_t hooks;
param_t *params;
if (parse_params(r_param, CLASS_CONTACT, &hooks, &params) != 0) {
LM_ERR("failed to parse route parameters '%.*s'\n", r_param->len, r_param->s);
LM_ERR("failed to parse route parametes\n");
return;
}

File diff suppressed because it is too large Load Diff

@ -12,7 +12,7 @@ LIBS=
DEFS+=-I/usr/include/libxml2 -I$(LOCALBASE)/include/libxml2 \
-I$(LOCALBASE)/include
LIBS+=-L/usr/include/lib -L$(LOCALBASE)/lib -lxml2
LIBS+=-L$(LOCALBASE)/lib -lxml2
DEFS+=-DOPENSER_MOD_INTERFACE

@ -50,10 +50,12 @@ struct presentity;
goto error
#define CONT_COPY(buf, dest, source)\
do{ \
dest.s= (char*)buf+ size;\
memcpy(dest.s, source.s, source.len);\
dest.len= source.len;\
size+= source.len;
size+= source.len; \
} while(0);
#define PKG_MEM_TYPE 1<< 1
#define SHM_MEM_TYPE 1<< 2

@ -716,6 +716,14 @@ int pres_update_status(subs_t subs, str reason, db_key_t* query_cols,
query_vals[q_wuser_col].val.str_val= subs.from_user;
query_vals[q_wdomain_col].val.str_val= subs.from_domain;
/* if status is no longer ACTIVE, switch to terminated */
if(subs.status!=status && status==ACTIVE_STATUS)
{
subs.status = TERMINATED_STATUS;
subs.reason.s = get_status_str(TERMINATED_STATUS);
subs.reason.len = strlen(subs.reason.s);
}
update_vals[u_status_col].val.int_val= subs.status;
update_vals[u_reason_col].val.str_val= subs.reason;

@ -354,15 +354,18 @@ int update_presentity(struct sip_msg* msg, presentity_t* presentity, str* body,
(int)time(NULL);
n_query_cols++;
if( presentity->sender)
query_cols[n_query_cols] = &str_sender_col;
query_vals[n_query_cols].type = DB1_STR;
query_vals[n_query_cols].nul = 0;
if(presentity->sender)
{
query_cols[n_query_cols] = &str_sender_col;
query_vals[n_query_cols].type = DB1_STR;
query_vals[n_query_cols].nul = 0;
query_vals[n_query_cols].val.str_val.s = presentity->sender->s;
query_vals[n_query_cols].val.str_val.len = presentity->sender->len;
n_query_cols++;
} else {
query_vals[n_query_cols].val.str_val.s = "";
query_vals[n_query_cols].val.str_val.len = 0;
}
n_query_cols++;
query_cols[n_query_cols] = &str_body_col;
query_vals[n_query_cols].type = DB1_BLOB;

@ -512,10 +512,10 @@ int handle_publish(struct sip_msg* msg, char* sender_uri, char* str2)
unsupported_event:
LM_ERR("Missing or unsupported event header field value\n");
LM_WARN("Missing or unsupported event header field value\n");
if(msg->event && msg->event->body.s && msg->event->body.len>0)
LM_ERR("\tevent=[%.*s]\n", msg->event->body.len, msg->event->body.s);
LM_ERR(" event=[%.*s]\n", msg->event->body.len, msg->event->body.s);
reply_code= BAD_EVENT_CODE;
reply_str= pu_489_rpl;

@ -12,7 +12,7 @@ LIBS=
DEFS+=-I/usr/include/libxml2 -I$(LOCALBASE)/include/libxml2 \
-I$(LOCALBASE)/include
LIBS+=-L$(SYSBASE)/include/lib -L$(LOCALBASE)/lib -lxml2
LIBS+=-L$(LOCALBASE)/lib -lxml2
DEFS+=-DOPENSER_MOD_INTERFACE

@ -11,7 +11,7 @@ NAME= pua_xmpp.so
LIBS=
DEFS+=-I/usr/include/libxml2 -I$(LOCALBASE)/include/libxml2 -I$(LOCALBASE)/include
LIBS+=-L/usr/include/lib -L$(LOCALBASE)/lib -lxml2
LIBS+=-L$(LOCALBASE)/lib -lxml2
DEFS+=-DOPENSER_MOD_INTERFACE

@ -87,7 +87,7 @@ int Notify2Xmpp(struct sip_msg* msg, char* s1, char* s2)
if(msg->to->parsed != NULL)
{
pto = (struct to_body*)msg->to->parsed;
LM_ERR("'To' header ALREADY PARSED:<%.*s>\n",pto->uri.len,pto->uri.s);
LM_DBG("'To' header ALREADY PARSED:<%.*s>\n",pto->uri.len,pto->uri.s);
}
else
{
@ -415,7 +415,8 @@ int build_xmpp_content(str* to_uri, str* from_uri, str* body, str* id,
goto error;
}
if(xmlStrcasecmp((unsigned char*)note, (unsigned char*)"away")== 0)
if((xmlStrcasecmp((unsigned char*)note, (unsigned char*)"away")== 0)||
(xmlStrcasecmp((unsigned char*)note, (unsigned char*)"On the phone")== 0))
{
new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show",
BAD_CAST "away");
@ -456,12 +457,14 @@ int build_xmpp_content(str* to_uri, str* from_uri, str* body, str* id,
LM_ERR("while adding node: idle\n");
goto error;
}
}
else */
}*/
else
if((xmlStrcasecmp((unsigned char*)note,
(unsigned char*)"dnd")== 0)||
(xmlStrcasecmp((unsigned char*)note,
(unsigned char*)"do not disturb")== 0))
(unsigned char*)"do not disturb")== 0)||
(xmlStrcasecmp((unsigned char*)note,
(unsigned char*)"Busy (DND)")== 0))
{
new_node = xmlNewChild(xmpp_root, NULL, BAD_CAST "show",
BAD_CAST "dnd");
@ -471,6 +474,8 @@ int build_xmpp_content(str* to_uri, str* from_uri, str* body, str* id,
goto error;
}
}
else
LM_DBG("Not Found Status\n");
/* adding status node */

@ -76,13 +76,13 @@ void pres_Xmpp2Sip(char *msg, int type, void *param)
{
LM_DBG("type attribut not present\n");
build_publish(pres_node, -1);
if(presence_subscribe(pres_node, 3600, XMPP_SUBSCRIBE)< 0)
/* if(presence_subscribe(pres_node, 3600, XMPP_SUBSCRIBE)< 0)
{
LM_ERR("when sending subscribe for presence");
xmlFree(pres_type);
goto error;
}
*/
/* send subscribe after publish because in xmpp subscribe message
* comes only when a new contact is inserted in buddy list */
@ -91,13 +91,13 @@ void pres_Xmpp2Sip(char *msg, int type, void *param)
if(strcmp(pres_type, "unavailable")== 0)
{
build_publish(pres_node, 0);
if(presence_subscribe(pres_node, 3600, XMPP_SUBSCRIBE)< 0)
/* else subscribe for one hour*/
/* if(presence_subscribe(pres_node, 0, XMPP_SUBSCRIBE)< 0)
{
LM_ERR("when unsubscribing for presence");
xmlFree(pres_type);
goto error;
}
*/
}
else
@ -243,13 +243,13 @@ str* build_pidf(xmlNodePtr pres_node, char* uri, char* resource)
if(show_cont)
{
if(strcmp(show_cont, "xa")== 0)
status= "not available";
status= "Away";
else
if(strcmp(show_cont, "chat")== 0)
status= "free for chat";
status= "Online";
else
if(strcmp(show_cont, "dnd")== 0)
status= "do not disturb";
status= "Busy (DND)";
else
status= show_cont;
}
@ -264,24 +264,25 @@ str* build_pidf(xmlNodePtr pres_node, char* uri, char* resource)
goto error;
}
*/
node = xmlNewChild(root_node, NULL, BAD_CAST "note",
BAD_CAST status_cont);
node = xmlNewChild(tuple_node, NULL, BAD_CAST "note",
BAD_CAST status);
if(node== NULL)
{
LM_ERR("while adding node\n");
goto error;
}
}else
} else {
if(show_cont)
{
node = xmlNewChild(root_node, NULL, BAD_CAST "note",
node = xmlNewChild(tuple_node, NULL, BAD_CAST "note",
BAD_CAST status);
if(node== NULL)
{
LM_ERR("while adding node\n");
goto error;
}
}
}
}
if(show_cont)
{
@ -295,23 +296,6 @@ str* build_pidf(xmlNodePtr pres_node, char* uri, char* resource)
goto error;
}
}
node= xmlNewChild(person_node, NULL, BAD_CAST "activities",
BAD_CAST 0);
if(node== NULL)
{
LM_ERR("while adding node\n");
goto error;
}
if( xmlNewChild(person_node, NULL, BAD_CAST "note",
BAD_CAST status )== NULL)
{
LM_ERR("while adding node\n");
goto error;
}
}

@ -23,6 +23,7 @@
#include <errno.h>
#include "../../dprint.h"
#include "../../cfg/cfg_struct.h"
#include "purple.h"
#include "purplepipe.h"
@ -231,6 +232,9 @@ void pipe_reader(gpointer data, gint fd, PurpleInputCondition condition) {
return;
}
/* update the local config framework structures */
cfg_update();
switch (cmd->type) {
case PURPLE_MESSAGE_CMD:
LM_DBG("received message cmd via pipe from <%s> to <%s>\n", cmd->message.from, cmd->message.to);

@ -30,6 +30,7 @@
#include "../../parser/parse_content.h"
#include "../../parser/parse_from.h"
#include "../../modules/tm/tm_load.h"
#include "../../cfg/cfg_struct.h"
#include "../pua/pua_bind.h"
#include "../pua/pidf.h"
@ -219,6 +220,8 @@ static int init(void) {
/* add space for one extra process */
register_procs(1);
/* add child to update local config framework structures */
cfg_register_child(1);
return 0;
}
@ -236,6 +239,9 @@ static int child_init(int rank)
return -1; /* error */
if(pid==0){
/* child */
/* initialize the config framework */
if (cfg_child_init())
return -1;
runprocs(1);
}
}

@ -23,6 +23,7 @@
#include "../../dprint.h"
#include "../../str.h"
#include "../../cfg/cfg_struct.h"
#include "../../modules/tm/tm_load.h"
#include "../pua/pua_bind.h"
#include "../pua/pidf.h"
@ -41,6 +42,9 @@ int purple_send_sip_msg(char *to, char *from, char *msg) {
char hdr_buf[512], ruri_buf[512];
uac_req_t uac_r;
/* update the local config framework structures */
cfg_update();
ruri.s = ruri_buf;
ruri.len = snprintf(ruri_buf, sizeof(ruri_buf), "%s;proto=purple", to);
@ -210,10 +214,13 @@ int purple_send_sip_publish(char *from, char *tupleid, enum purple_publish_basic
char pres_buff[512];
publ_info_t publ;
str pres_uri;
/* update the local config framework structures */
cfg_update();
memset(&publ, 0, sizeof(publ_info_t));
str pres_uri;
pres_uri.s = pres_buff;
pres_uri.len = sprintf(pres_buff, "%s;proto=purple", from);

@ -395,7 +395,7 @@ int pv_get_sndto(struct sip_msg *msg, pv_param_t *param,
(int)snd_inf->len);
default:
/* 0 - ip */
s.s = su2a(snd_inf->to, sizeof(*snd_inf->to));
s.s = suip2a(snd_inf->to, sizeof(*snd_inf->to));
s.len = strlen(s.s);
return pv_get_strval(msg, param, res, &s);
}

@ -880,6 +880,7 @@ int tr_eval_nameaddr(struct sip_msg *msg, tr_param_t *tp, int subtype,
pv_value_t *val)
{
str sv;
int ret;
if(val==NULL || (!(val->flags&PV_VAL_STR)) || val->rs.len<=0)
return -1;
@ -909,8 +910,14 @@ int tr_eval_nameaddr(struct sip_msg *msg, tr_param_t *tp, int subtype,
/* parse params */
sv = _tr_nameaddr_str;
if (parse_nameaddr(&sv, &_tr_nameaddr)<0)
return -1;
ret = parse_nameaddr(&sv, &_tr_nameaddr);
if (ret < 0) {
if(ret != -3) return -1;
/* -3 means no "<" found so treat whole nameaddr as an URI */
_tr_nameaddr.uri = _tr_nameaddr_str;
_tr_nameaddr.name = _tr_empty;
_tr_nameaddr.len = _tr_nameaddr_str.len;
}
}
memset(val, 0, sizeof(pv_value_t));

@ -472,11 +472,12 @@ str* constr_multipart_body(db1_res_t* result, char** cid_array,
int i, length= 0;
db_row_t *row;
db_val_t *row_vals;
char* content_id= NULL;
str content_id = {0, 0};
str body= {0, 0};
str ctype= {0, 0};
int antet_len;
str content_type= {0, 0};
int chunk_len;
str* multi_body= NULL;
str bstr = {0, 0};
LM_DBG("start\n");
buf= pkg_malloc(size* sizeof(char));
@ -485,7 +486,8 @@ str* constr_multipart_body(db1_res_t* result, char** cid_array,
ERR_MEM(PKG_MEM_STR);
}
antet_len= COMPUTE_ANTET_LEN (boundary_string);
bstr.s = boundary_string;
bstr.len = strlen(bstr.s);
for(i= 0; i< result->n; i++)
{
@ -498,29 +500,37 @@ str* constr_multipart_body(db1_res_t* result, char** cid_array,
body.s= (char*)row_vals[pres_state_col].val.string_val;
body.len= strlen(body.s);
trim(&body);
ctype.s = (char*)row_vals[content_type_col].val.string_val;
ctype.len = strlen(ctype.s);
if(length+ antet_len+ body.len+ 4 > size)
{
REALLOC_BUF
}
length+= sprintf(buf+ length, "--%s\r\n\r\n", boundary_string);
length+= sprintf(buf+ length, "Content-Transfer-Encoding: binary\r\n");
content_id= cid_array[i];
if(content_id== NULL)
content_type.s = (char*)row_vals[content_type_col].val.string_val;
content_type.len = strlen(content_type.s);
content_id.s= cid_array[i];
if(content_id.s== NULL)
{
LM_ERR("No cid found in array for uri= %s\n",
row_vals[resource_uri_col].val.string_val);
goto error;
}
content_id.len = strlen(content_id.s);
length+= sprintf(buf+ length, "Content-ID: <%s>\r\n",content_id);
chunk_len = 4 + bstr.len
+ 35
+ 16 + content_id.len
+ 18 + content_type.len
+ 4 + body.len + 8;
if(length + chunk_len >= size)
{
REALLOC_BUF
}
length+= sprintf(buf+ length, "--%.*s\r\n",
bstr.len, bstr.s);
length+= sprintf(buf+ length, "Content-Transfer-Encoding: binary\r\n");
length+= sprintf(buf+ length, "Content-ID: <%.*s>\r\n",
content_id.len, content_id.s);
length+= sprintf(buf+ length, "Content-Type: %.*s\r\n\r\n",
ctype.len, ctype.s);
length+= sprintf(buf+length,"%.*s\r\n\r\n", body.len, body.s);
content_type.len, content_type.s);
length+= sprintf(buf+length,"%.*s\r\n\r\n",
body.len, body.s);
}
if(length+ strlen( boundary_string)+ 7> size )

@ -46,7 +46,6 @@
if(buf== NULL) \
{ ERR_MEM("constr_multipart_body");}
#define COMPUTE_ANTET_LEN(boundary_string) (strlen( boundary_string)+ MAX_HEADERS_LENGTH + 6)
int send_full_notify(subs_t* subs, xmlNodePtr rl_node,
int version, str* rl_uri, unsigned int hash_code);

@ -48,19 +48,6 @@
* */
static str su_200_rpl = str_init("OK");
#define CONT_COPY(buf, dest, source)\
dest.s= (char*)buf+ size;\
memcpy(dest.s, source.s, source.len);\
dest.len= source.len;\
size+= source.len;
#define CONT_COPY_1 (buf, dest_s, dest_len, source_s, source_len)\
dest_s= (char*)buf+ size;\
memcpy(dest_s, source_s, source_len);\
dest_len= source_len;\
size+= source_len;
int parse_subs_state(str auth_state, str** reason, int* expires)
{
str str_exp;
@ -240,16 +227,6 @@ int rls_handle_notify(struct sip_msg* msg, char* c1, char* c2)
LM_ERR("unrecognized event package\n");
goto error;
}
if(pua_get_record_id(&dialog, &res_id)< 0) // verify if within a stored dialog
{
LM_ERR("occured when trying to get record id\n");
goto error;
}
if(res_id== 0)
{
LM_ERR("record not found\n");
goto error;
}
/* extract the subscription state */
hdr = msg->headers;
@ -276,6 +253,24 @@ int rls_handle_notify(struct sip_msg* msg, char* c1, char* c2)
LM_ERR("while parsing 'Subscription-State' header\n");
goto error;
}
if(pua_get_record_id(&dialog, &res_id)< 0) // verify if within a stored dialog
{
LM_ERR("occured when trying to get record id\n");
goto error;
}
if(res_id==0)
{
LM_DBG("presence dialog record not found\n");
/* if it is a NOTIFY for a terminated SUBSCRIBE dialog in RLS, then
* the module might not have the dialog structure anymore
* - just send 200ok, it is harmless
*/
if(auth_flag==TERMINATED_STATE)
goto done;
LM_ERR("no presence dialog record for non-TERMINATED state\n");
goto error;
}
if(msg->content_type== NULL || msg->content_type->body.s== NULL)
{
LM_DBG("cannot find content type header header\n");
@ -408,9 +403,11 @@ done:
goto error;
}
pkg_free(res_id->s);
pkg_free(res_id);
if(res_id!=NULL)
{
pkg_free(res_id->s);
pkg_free(res_id);
}
return 1;
error:
@ -472,8 +469,11 @@ void timer_send_notify(unsigned int ticks,void *param)
unsigned int hash_code= 0;
int len;
int size= BUF_REALLOC_SIZE, buf_len= 0;
char* buf= NULL, *auth_state= NULL, *boundary_string= NULL, *cid= NULL;
int contor= 0, auth_state_flag, antet_len;
char* buf= NULL, *auth_state= NULL, *boundary_string= NULL;
str cid = {0,0};
str content_type = {0,0};
int contor= 0, auth_state_flag;
int chunk_len;
str bstr= {0, 0};
str rlmi_cont= {0, 0}, multi_cont;
subs_t* s, *dialog= NULL;
@ -547,7 +547,6 @@ void timer_send_notify(unsigned int ticks,void *param)
ERR_MEM(PKG_MEM_STR);
}
antet_len= COMPUTE_ANTET_LEN(bstr.s);
LM_DBG("found %d records with updated state\n", result->n);
for(i= 0; i< result->n; i++)
{
@ -676,7 +675,8 @@ void timer_send_notify(unsigned int ticks,void *param)
while(1)
{
contor++;
cid= NULL;
cid.s= NULL;
cid.len= 0;
instance_node= xmlNewChild(resource_node, NULL,
BAD_CAST "instance", NULL);
if(instance_node== NULL)
@ -697,8 +697,8 @@ void timer_send_notify(unsigned int ticks,void *param)
if(auth_state_flag & ACTIVE_STATE)
{
cid= generate_cid(resource_uri, strlen(resource_uri));
xmlNewProp(instance_node, BAD_CAST "cid", BAD_CAST cid);
cid.s= generate_cid(resource_uri, strlen(resource_uri));
xmlNewProp(instance_node, BAD_CAST "cid", BAD_CAST cid.s);
}
else
if(auth_state_flag & TERMINATED_STATE)
@ -708,18 +708,28 @@ void timer_send_notify(unsigned int ticks,void *param)
}
/* add in the multipart buffer */
if(cid)
if(cid.s)
{
if(buf_len+ antet_len+ pres_state.len+ 4 > size)
cid.len = strlen(cid.s);
content_type.s = (char*)row_vals[content_type_col].val.string_val;
content_type.len = strlen(content_type.s);
chunk_len = 4 + bstr.len
+ 35
+ 16 + cid.len
+ 18 + content_type.len
+ 4 + pres_state.len + 8;
if(buf_len + chunk_len >= size)
{
REALLOC_BUF
}
buf_len+= sprintf(buf+ buf_len, "--%s\r\n", bstr.s);
buf_len+= sprintf(buf+ buf_len, "--%.*s\r\n", bstr.len,
bstr.s);
buf_len+= sprintf(buf+ buf_len,
"Content-Transfer-Encoding: binary\r\n");
buf_len+= sprintf(buf+ buf_len, "Content-ID: <%s>\r\n", cid);
buf_len+= sprintf(buf+ buf_len, "Content-Type: %s\r\n\r\n",
row_vals[content_type_col].val.string_val);
buf_len+= sprintf(buf+ buf_len, "Content-ID: <%.*s>\r\n",
cid.len, cid.s);
buf_len+= sprintf(buf+ buf_len, "Content-Type: %.*s\r\n\r\n",
content_type.len, content_type.s);
buf_len+= sprintf(buf+buf_len,"%.*s\r\n\r\n", pres_state.len,
pres_state.s);
}

@ -90,7 +90,7 @@ xmlNodePtr rls_get_by_service_uri(xmlDocPtr doc, str* uri)
val = XMLNodeGetAttrContentByName(node, "uri");
if(val!=NULL)
{
if((uri->len==strlen(val)) && (strcmp(val, uri->s)==0))
if((uri->len==strlen(val)) && (strncmp(val, uri->s, uri->len)==0))
{
xmlFree(val);
return node;
@ -241,13 +241,17 @@ int rls_get_service_list(str *service_uri, str *user, str *domain,
*service_node = rls_get_by_service_uri(xmldoc, service_uri);
if(*service_node==NULL)
{
LM_ERR("service uri %.*s not found in rl document for user"
LM_DBG("service uri %.*s not found in rl document for user"
" sip:%.*s@%.*s\n", service_uri->len, service_uri->s,
user->len, user->s, domain->len, domain->s);
goto error;
rootdoc = NULL;
if(xmldoc!=NULL)
xmlFreeDoc(xmldoc);
}
else
{
*rootdoc = xmldoc;
}
*rootdoc = xmldoc;
rls_dbf.free_result(rls_db, result);
if(xcapdoc!=NULL)
@ -621,7 +625,7 @@ int rls_handle_subscribe(struct sip_msg* msg, char* s1, char* s2)
if(send_full_notify(&subs, service_node, subs.version, &subs.pres_uri,
hash_code)<0)
{
LM_ERR("failed sending full state sotify\n");
LM_ERR("failed sending full state notify\n");
goto error;
}
/* send subscribe requests for all in the list */

@ -118,7 +118,7 @@ static int mod_init(void)
return -1;
}
} else {
register_procs(1);
register_dummy_timers(1);
}
it = it->next;
}

@ -38,6 +38,7 @@
#include "../../mem/shm_mem.h" /*shm_malloc*/
#include "../../dprint.h" /*LM_**/
#include "../../locking.h"
#include "../../cfg/cfg_struct.h"
#include "seas.h"
#include "ha.h"
@ -129,6 +130,9 @@ int dispatcher_main_loop(void)
spawn_pinger();
while(1){
/* update the local config framework structures */
cfg_update();
if(sig_flag==SIGCHLD){
while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
if (WIFEXITED(chld_status)){

@ -37,6 +37,7 @@
#include "../../modules/tm/tm_load.h" /*load_tm_api*/
#include "../../modules/tm/h_table.h" /*cell*/
#include "../../modules/tm/t_lookup.h" /*T_UNDEFINED*/
#include "../../cfg/cfg_struct.h"
#include "encode_msg.h" /*encode_msg*/
@ -681,6 +682,9 @@ static int seas_init(void)
if(0>parse_cluster_cfg())
goto error;
register_procs(1);
/* add child to update local config framework structures */
cfg_register_child(1);
return 0;
error:
for(i=0;i<2;i++)
@ -728,6 +732,10 @@ static int seas_child_init(int rank)
/*dispatcher child. we leave writing end open so that new childs spawned
* by event dispatcher can also write to pipe.. */
/* initialize the config framework */
if (cfg_child_init())
return -1;
/* close(write_pipe); */
return dispatcher_main_loop();
}

@ -374,6 +374,7 @@ int ring_filter(struct sip_msg *msg, unsigned int flags, void *bar)
* \return 0
*/
int ring_fixup(void ** param, int param_no) {
int ring_timeout = cfg_get(siputils, siputils_cfg, ring_timeout);
if (ring_timeout == 0) {
LM_ERR("ring_insert_callid functionality deactivated, you need to set a positive ring_timeout\n");
return -1;

@ -38,7 +38,6 @@
extern gen_lock_t *ring_lock;
extern unsigned int ring_timeout;
/*!

@ -79,6 +79,7 @@
#include "snmpstats.h"
#include "snmpstats_globals.h"
#include "../../timer.h"
#include "../../cfg/cfg_struct.h"
#include <net-snmp/net-snmp-config.h>
#include <net-snmp/net-snmp-includes.h>
@ -340,6 +341,8 @@ static int mod_init(void)
/* add space for one extra process */
register_procs(1);
/* add child to update local config framework structures */
cfg_register_child(1);
return 0;
}
@ -363,6 +366,10 @@ static int mod_child_init(int rank)
return -1; /* error */
if(pid==0){
/* child */
/* initialize the config framework */
if (cfg_child_init())
return -1;
agentx_child(1);
return 0;
}

@ -65,6 +65,7 @@
#include "snmpMIBNotifications.h"
#include "../../dprint.h"
#include "../../cfg/cfg_struct.h"
static int keep_running;
@ -110,6 +111,9 @@ static int initialize_agentx(void)
keep_running = 1;
while(keep_running) {
/* update the local config framework structures */
cfg_update();
agent_check_and_process(1); /* 0 == don't block */
}

@ -103,7 +103,7 @@ int search_api(struct sip_msg *msg, str *regex){
/*
* Function to load the textops api.
*/
int load_textops(struct textops_binds *tob){
int bind_textops(textops_api_t *tob){
if(tob==NULL){
LM_WARN("textops_binds: Cannot load textops API into a NULL pointer\n");
return -1;

@ -37,31 +37,31 @@ typedef int (*search_t)(struct sip_msg*, str*);
/*
* Struct with the textops api.
*/
struct textops_binds{
typedef struct textops_binds {
append_hf_t append_hf; // Append a header to the message.
remove_hf_t remove_hf; // Remove a header with the specified name from the message.
search_append_t search_append; // Append a str after a match of the specified regex.
search_t search; // Check if the regex matches a part of the message.
};
} textops_api_t;
typedef int (*load_textops_f)(struct textops_binds*);
typedef int (*bind_textops_f)(textops_api_t*);
/*
* function exported by module - it will load the other functions
*/
int load_textops(struct textops_binds*);
int bind_textops(textops_api_t*);
/*
* Function to be called direclty from other modules to load
* the textops API.
*/
inline static int load_textops_api(struct textops_binds *tob){
load_textops_f load_textops_exports;
if(!(load_textops_exports=(load_textops_f)find_export("load_textops",0,0))){
LM_ERR("Failed to import load_textops\n");
inline static int load_textops_api(textops_api_t *tob){
bind_textops_f bind_textops_exports;
if(!(bind_textops_exports=(bind_textops_f)find_export("bind_textops",0,0))){
LM_ERR("Failed to import bind_textops\n");
return -1;
}
return load_textops_exports(tob);
return bind_textops_exports(tob);
}
#endif /*TEXT_OPS_API_H_*/

@ -247,6 +247,9 @@ static cmd_export_t cmds[]={
fixup_spve_spve, 0,
REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
{"bind_textops", (cmd_function)bind_textops, 0, 0, 0,
0},
{0,0,0,0,0,0}
};

@ -29,6 +29,7 @@ Daniel-Constantin Mierla
3.1. t_cancel_branches(which)
3.2. t_cancel_callid(callid, cseq, flag)
3.3. t_reply_callid(callid, cseq, code, reason)
3.4. t_flush_flags()
4. Exported pseudo-variables
5. Exported MI Functions
@ -57,6 +58,7 @@ Daniel-Constantin Mierla
1.1. t_cancel_branches usage
1.2. t_cancel_callid usage
1.3. t_reply_callid usage
1.4. t_flush_flags usage
Chapter 1. Admin Guide
@ -73,6 +75,7 @@ Chapter 1. Admin Guide
3.1. t_cancel_branches(which)
3.2. t_cancel_callid(callid, cseq, flag)
3.3. t_reply_callid(callid, cseq, code, reason)
3.4. t_flush_flags()
4. Exported pseudo-variables
5. Exported MI Functions
@ -124,6 +127,7 @@ Chapter 1. Admin Guide
3.1. t_cancel_branches(which)
3.2. t_cancel_callid(callid, cseq, flag)
3.3. t_reply_callid(callid, cseq, code, reason)
3.4. t_flush_flags()
3.1. t_cancel_branches(which)
@ -182,6 +186,19 @@ if (t_reply_callid("123qaz", "5", "458", "Replied remotely")) {
}
...
3.4. t_flush_flags()
Flush the flags from current SIP message into the already created
transaction. It make sense only in routing block if the transaction was
created via t_newtran() and the flags have been altered since.
This function can be used from ANY_ROUTE .
Example 1.4. t_flush_flags usage
...
t_flush_flags();
...
4. Exported pseudo-variables
* $T_branch_idx

@ -168,6 +168,27 @@ if (t_reply_callid("123qaz", "5", "458", "Replied remotely")) {
xlog("transaction replied\n");
}
...
</programlisting>
</example>
</section>
<section>
<title>
<function moreinfo="none">t_flush_flags()</function>
</title>
<para>
Flush the flags from current SIP message into the already created
transaction. It make sense only in routing block if the transaction was
created via t_newtran() and the flags have been altered since.
</para>
<para>
This function can be used from ANY_ROUTE .
</para>
<example>
<title><function>t_flush_flags</function> usage</title>
<programlisting format="linespecific">
...
t_flush_flags();
...
</programlisting>
</example>
</section>

@ -53,6 +53,8 @@ static int t_reply_callid(struct sip_msg* msg, char *cid, char *cseq,
char *rc, char *rs);
static int fixup_reply_callid(void** param, int param_no);
static int t_flush_flags(struct sip_msg* msg, char*, char* );
/* statistic variables */
stat_var *tm_rcv_rpls;
stat_var *tm_rld_rpls;
@ -135,6 +137,8 @@ static cmd_export_t cmds[]={
fixup_cancel_callid, 0, ANY_ROUTE },
{"t_reply_callid", (cmd_function)t_reply_callid, 4,
fixup_reply_callid, 0, ANY_ROUTE },
{"t_flush_flags", (cmd_function)t_flush_flags, 0, 0,
0, ANY_ROUTE },
{0,0,0,0,0,0}
};
@ -398,6 +402,23 @@ static int t_reply_callid(struct sip_msg* msg, char *cid, char *cseq,
return -1;
}
/**
*
*/
static int t_flush_flags(struct sip_msg* msg, char *foo, char *bar)
{
struct cell *t;
t=_tmx_tmb.t_gett();
if ( t==0 || t==T_UNDEFINED) {
LM_ERR("failed to flush flags - no transaction found\n");
return -1;
}
t->uas.request->flags = msg->flags;
return 1;
}
#ifdef STATISTICS
/*** tm stats ***/

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

Loading…
Cancel
Save