New upstream version 5.2.5

changes/49/34149/1 upstream/5.2.5
Marco Capetta 6 years ago
parent fafb27fb0b
commit efce85a240

File diff suppressed because it is too large Load Diff

@ -75,12 +75,12 @@ def traverse_routes(_level, _name):
if len(sys.argv) < 2:
raise "usage: %s configuration-file [max_depth]" % sys.argv[0]
raise Exception('wrong number of arguments\nusage: ' + sys.argv[0] + ' configuration-file [max_depth]')
if len(sys.argv) == 3:
max_depth = int(sys.argv[2])
cfg = file(sys.argv[1], "r")
if cfg == None:
raise "Missing config file"
if cfg is None:
raise Exception ('Missing config file')
line = cfg.readline()
rt = routes
while line:
@ -90,40 +90,40 @@ while line:
main_match = re_main_route.search(line)
def_match = re_def_route.search(line)
call_match = re_call_route.search(line)
if not call_match == None:
if not call_match is None:
log("CALL: " + line)
name = call_match.group(2)
log(rname +":"+name)
rt[rname].append(name)
elif not def_match == None:
elif not def_match is None:
log("DEF: " + line)
rtype = def_match.group(1)
rname = def_match.group(3)
if rtype == "failure_":
rt = f_routes
if rname == None:
if rname is None:
rname = "failure"
elif rtype == "onreply_":
rt = r_routes
if rname == None:
if rname is None:
rname = "onreply"
elif rtype == "onsend_":
rt = s_routes
if rname == None:
if rname is None:
rname = "onsend"
elif rtype == "branch_":
rt = b_routes
if rname == None:
if rname is None:
rname = "branch"
elif rtype == "event_":
rt = e_routes
if rname == None:
if rname is None:
rname = "event"
else:
rt = routes
log(rname)
rt[rname] = []
elif not main_match == None:
elif not main_match is None:
log("MAIN: " + line)
rtype = main_match.group(1)
if rtype == "failure_":

@ -4,7 +4,7 @@
# Maintainer: Nathan Angelacos <nangel@alpinelinux.org>
pkgname=kamailio
pkgver=5.2.4
pkgver=5.2.5
pkgrel=0
# If building from a git snapshot, specify the gitcommit

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,3 +1,9 @@
kamailio (5.2.5) unstable; urgency=medium
* version set 5.2.5
-- Victor Seva <vseva@debian.org> Thu, 10 Oct 2019 09:45:29 +0200
kamailio (5.2.4) unstable; urgency=medium
* version set 5.2.4

@ -1,5 +1,5 @@
%define name kamailio
%define ver 5.2.4
%define ver 5.2.5
%define rel dev1.0%{dist}
%if 0%{?fedora} == 27
@ -102,6 +102,56 @@
%bcond_without xmlrpc
%endif
%if 0%{?fedora} == 31
%define dist_name fedora
%define dist_version %{?fedora}
%bcond_without cnxcc
%bcond_with dnssec
%bcond_without geoip
%bcond_without http_async_client
%bcond_without ims
%bcond_without jansson
%bcond_without json
%bcond_without lua
%bcond_without kazoo
%bcond_without memcached
%bcond_without mongodb
%bcond_without perl
%bcond_without phonenum
%bcond_without python3
%bcond_without rabbitmq
%bcond_without redis
%bcond_without ruby
%bcond_without sctp
%bcond_without websocket
%bcond_without xmlrpc
%endif
%if 0%{?fedora} == 99
%define dist_name fedora
%define dist_version %{?fedora}
%bcond_without cnxcc
%bcond_with dnssec
%bcond_without geoip
%bcond_without http_async_client
%bcond_without ims
%bcond_without jansson
%bcond_without json
%bcond_without lua
%bcond_without kazoo
%bcond_without memcached
%bcond_without mongodb
%bcond_without perl
%bcond_without phonenum
%bcond_without python3
%bcond_without rabbitmq
%bcond_without redis
%bcond_without ruby
%bcond_without sctp
%bcond_without websocket
%bcond_without xmlrpc
%endif
%if 0%{?centos_ver} == 6
%define dist_name centos
%define dist_version %{?centos}
@ -780,7 +830,9 @@ Requires: python3, kamailio = %ver
BuildRequires: python3, python3-devel
%endif
%endif
%if 0%{?fedora}
BuildRequires: python2-devel
%endif
%description python
Python extensions for Kamailio.
@ -1099,21 +1151,9 @@ UUID module for Kamailio.
sed -i -e 's:#!/usr/bin/python:#!%{__python2}:' utils/kamctl/dbtextdb/dbtextdb.py
%endif
ln -s ../obs pkg/kamailio/fedora/27
ln -s ../obs pkg/kamailio/fedora/28
ln -s ../obs pkg/kamailio/fedora/29
ln -s ../obs pkg/kamailio/fedora/30
ln -s ../obs pkg/kamailio/rhel/6
ln -s ../obs pkg/kamailio/rhel/7
ln -s ../obs pkg/kamailio/opensuse/1315
ln -s ../obs pkg/kamailio/opensuse/1330
ln -s ../obs pkg/kamailio/opensuse/1500
ln -s ../obs pkg/kamailio/opensuse/1550
ln -s ../obs pkg/kamailio/centos/6
ln -s ../obs pkg/kamailio/centos/7
%build
ln -s ../obs pkg/kamailio/%{dist_name}/%{dist_version}
%if 0%{?fedora} || 0%{?suse_version}
export FREERADIUS=1
%endif

@ -32,27 +32,32 @@
<path project="Fedora:EPEL:6" repository="RHEL"/>
<arch>x86_64</arch>
</repository>
<repository name="Fedora_29">
<path project="Fedora:29" repository="update"/>
<path project="Fedora:29" repository="standard"/>
<repository name="Fedora_Rawhide">
<path project="Fedora:Rawhide" repository="standard"/>
<arch>x86_64</arch>
</repository>
<repository name="Fedora_28">
<path project="Fedora:28" repository="update"/>
<path project="Fedora:28" repository="standard"/>
<repository name="Fedora_30">
<path project="Fedora:30" repository="update"/>
<path project="Fedora:30" repository="standard"/>
<arch>x86_64</arch>
<arch>i586</arch>
<arch>armv7l</arch>
<arch>aarch64</arch>
<arch>ppc64le</arch>
</repository>
<repository name="Fedora_27">
<path project="Fedora:27" repository="update"/>
<path project="Fedora:27" repository="standard"/>
<repository name="Fedora_29">
<path project="Fedora:29" repository="update"/>
<path project="Fedora:29" repository="standard"/>
<arch>x86_64</arch>
</repository>
<repository name="CentOS_7">
<path project="CentOS:CentOS-7" repository="standard"/>
<path project="CentOS:CentOS-7" repository="update"/>
<path project="Fedora:EPEL:7" repository="CentOS"/>
<arch>x86_64</arch>
</repository>
<repository name="CentOS_6">
<path project="CentOS:CentOS-6" repository="standard"/>
<path project="CentOS:CentOS-6" repository="update"/>
<path project="Fedora:EPEL:6" repository="CentOS"/>
<arch>x86_64</arch>

@ -8,6 +8,8 @@ After=mysqld.service
[Service]
Type=simple
User=kamailio
Group=kamailio
WorkingDirectory=/run/sipcapture
Environment='CFGFILE=/etc/kamailio/kamailio-sipcapture.cfg'
Environment='SHM_MEMORY=32'
@ -18,8 +20,6 @@ PIDFile=/run/sipcapture/sipcapture.pid
# ExecStart requires a full absolute path
ExecStart=/usr/sbin/kamailio -DD -P /run/sipcapture/sipcapture.pid -f $CFGFILE -m $SHM_MEMORY -M $PKG_MEMORY
Restart=on-failure
User=kamailio
Group=daemon
[Install]

@ -1 +1 @@
D /run/sipcapture 0700 kamailio daemon -
D /run/sipcapture 0700 kamailio kamailio -

@ -1,5 +1,5 @@
%define name kamailio
%define ver 5.2.4
%define ver 5.2.5
%define rel 0
%define _sharedir %{_prefix}/share

@ -1,5 +1,5 @@
%define name kamailio
%define ver 5.2.4
%define ver 5.2.5
%define rel 0
%define _sharedir %{_prefix}/share

@ -106,7 +106,7 @@ INSTALL_FLAVOUR=$(FLAVOUR)
# version number
VERSION = 5
PATCHLEVEL = 2
SUBLEVEL = 4
SUBLEVEL = 5
EXTRAVERSION =
# memory manager switcher
@ -178,6 +178,42 @@ CC_EXTRA_OPTS ?=
# extra LD command line options
LD_EXTRA_OPTS ?=
# enable workaround for libssl 1.1+ to set shared mutex attribute
LIBSSL_SET_MUTEX_SHARED ?=
ifneq ($(LIBSSL_SET_MUTEX_SHARED), 1)
ifeq ($(CROSS_COMPILE),)
LIBSSL_PKGCONFIG=$(shell \
if pkg-config --exists libssl; then \
echo 'pkg-config libssl'; \
fi)
endif
ifneq ($(LIBSSL_PKGCONFIG),)
# numerical version (good for comparisons: A.B.C => A*1000000+B*1000+C)
LIBSSL_VERNUM:= $(shell $(LIBSSL_PKGCONFIG) --modversion | sed -e 's/^[^0-9]*//' \
-e 's/^\([0-9][0-9]*\(\.[0-9][0-9]*\)*\).*$$/\1/g' | \
(IFS=. read A B C D; R=0; \
[ -n "$$A" ] && R=`expr $$R \* 1000 + $$A` && \
[ -n "$$B" ] && R=`expr $$R \* 1000 + $$B` && \
[ -n "$$C" ] && R=`expr $$R \* 1000 + $$C`; echo $$R ) )
# libssl version greater or equal than 1.1
ifeq ($(shell [ $(LIBSSL_VERNUM) -ge 1001000 ] && echo libssl11plus), libssl11plus)
LIBSSL_SET_MUTEX_SHARED := 1
endif
endif
endif
ifeq ($(LIBSSL_SET_MUTEX_SHARED), 1)
CC_EXTRA_OPTS+= -pthread -DKSR_PTHREAD_MUTEX_SHARED
LD_EXTRA_OPTS+= -pthread -rdynamic -ldl -Wl,-Bsymbolic-functions
endif
ifeq ($(OS), solaris)
#use GNU versions
INSTALL ?= ginstall

@ -2,6 +2,6 @@
* DO NOT EDIT IT
*/
#define REPO_VER "759867"
#define REPO_HASH "759867"
#define REPO_VER "62d35f"
#define REPO_HASH "62d35f"
#define REPO_STATE ""

@ -1922,14 +1922,24 @@ static void pp_ifdef()
static void pp_else()
{
if(pp_sptr==0) {
LM_WARN("invalid position for preprocessor directive 'else'"
" - at %s line %d\n", (finame)?finame:"cfg", line);
return;
}
pp_ifdef_stack[pp_sptr-1] ^= 1;
pp_update_state();
}
static void pp_endif()
{
pp_sptr--;
pp_ifdef_level_update(-1);
if(pp_sptr==0) {
LM_WARN("invalid position for preprocessor directive 'else'"
" - at %s line %d\n", (finame)?finame:"cfg", line);
return;
}
pp_sptr--;
pp_update_state();
}

@ -682,7 +682,7 @@ cfg_group_inst_t *cfg_extend_array(cfg_group_meta_t *meta, cfg_group_t *group,
if (i > 0)
memcpy( new_array,
old_array,
inst_size * i);
(size_t) inst_size * i);
memset((char*)new_array + inst_size * i, 0, inst_size);
*new_group = (cfg_group_inst_t *)((char*)new_array + inst_size * i);
@ -691,7 +691,7 @@ cfg_group_inst_t *cfg_extend_array(cfg_group_meta_t *meta, cfg_group_t *group,
if (i < meta->num)
memcpy( (char*)new_array + inst_size * (i + 1),
(char*)old_array + inst_size * i,
inst_size * (meta->num - i));
(size_t) inst_size * (meta->num - i));
return new_array;
}

@ -357,7 +357,7 @@ int daemonize(char* name, int status_wait)
fprintf(pid_stream, "%i\n", (int)pid);
fclose(pid_stream);
if(chown(pid_file, pid_uid, pid_gid)<0) {
LM_ERR("failed to chwon PID file: %s\n", strerror(errno));
LM_ERR("failed to chown PID file: %s\n", strerror(errno));
goto error;
}
}
@ -385,7 +385,7 @@ int daemonize(char* name, int status_wait)
fprintf(pid_stream, "%i\n", (int)pid);
fclose(pid_stream);
if(chown(pgid_file, pid_uid, pid_gid)<0) {
LM_ERR("failed to chwon PGID file: %s\n", strerror(errno));
LM_ERR("failed to chown PGID file: %s\n", strerror(errno));
goto error;
}
}

@ -30,48 +30,69 @@
#define FAKED_SIP_MSG "OPTIONS sip:you@kamailio.org SIP/2.0\r\nVia: SIP/2.0/UDP 127.0.0.1\r\nFrom: <sip:you@kamailio.org>;tag=123\r\nTo: <sip:you@kamailio.org>\r\nCall-ID: 123\r\nCSeq: 1 OPTIONS\r\nContent-Length: 0\r\n\r\n"
#define FAKED_SIP_MSG_LEN (sizeof(FAKED_SIP_MSG)-1)
static char _faked_sip_buf[FAKED_SIP_MSG_LEN+1];
static struct sip_msg _faked_msg;
static char _faked_sip_buf[BUF_SIZE];
static int _faked_sip_buf_init = 0;
static sip_msg_t _faked_msg;
static unsigned int _faked_msg_no = 0;
int faked_msg_init(void)
static unsigned int faked_msg_get_next_id(void)
{
if(_faked_msg_no>0)
return 0;
/* init faked sip msg */
_faked_msg_no += ((_faked_msg_no+1)==0)?2:1;
return _faked_msg_no;
}
static void faked_msg_buf_init(void)
{
if(_faked_sip_buf_init!=0) {
return;
}
memcpy(_faked_sip_buf, FAKED_SIP_MSG, FAKED_SIP_MSG_LEN);
_faked_sip_buf[FAKED_SIP_MSG_LEN] = '\0';
_faked_sip_buf_init = 1;
}
static int faked_msg_init_new(sip_msg_t *fmsg)
{
faked_msg_buf_init();
memset(&_faked_msg, 0, sizeof(struct sip_msg));
/* init faked sip msg */
memset(fmsg, 0, sizeof(sip_msg_t));
_faked_msg.buf=_faked_sip_buf;
_faked_msg.len=FAKED_SIP_MSG_LEN;
fmsg->buf=_faked_sip_buf;
fmsg->len=FAKED_SIP_MSG_LEN;
_faked_msg.set_global_address=default_global_address;
_faked_msg.set_global_port=default_global_port;
fmsg->set_global_address=default_global_address;
fmsg->set_global_port=default_global_port;
if (parse_msg(_faked_msg.buf, _faked_msg.len, &_faked_msg)!=0)
{
LM_ERR("parse_msg failed\n");
if (parse_msg(fmsg->buf, fmsg->len, fmsg)!=0) {
LM_ERR("parse faked msg failed\n");
return -1;
}
_faked_msg.rcv.proto = PROTO_UDP;
_faked_msg.rcv.src_port = 5060;
_faked_msg.rcv.src_ip.u.addr32[0] = 0x7f000001;
_faked_msg.rcv.src_ip.af = AF_INET;
_faked_msg.rcv.src_ip.len = 4;
_faked_msg.rcv.dst_port = 5060;
_faked_msg.rcv.dst_ip.u.addr32[0] = 0x7f000001;
_faked_msg.rcv.dst_ip.af = AF_INET;
_faked_msg.rcv.dst_ip.len = 4;
fmsg->rcv.proto = PROTO_UDP;
fmsg->rcv.src_port = 5060;
fmsg->rcv.src_ip.u.addr32[0] = 0x7f000001;
fmsg->rcv.src_ip.af = AF_INET;
fmsg->rcv.src_ip.len = 4;
fmsg->rcv.dst_port = 5060;
fmsg->rcv.dst_ip.u.addr32[0] = 0x7f000001;
fmsg->rcv.dst_ip.af = AF_INET;
fmsg->rcv.dst_ip.len = 4;
return 0;
}
static inline sip_msg_t* faked_msg_next_id(int mode)
int faked_msg_init(void)
{
if(_faked_msg_no>0) {
return 0;
}
return faked_msg_init_new(&_faked_msg);
}
static inline sip_msg_t* faked_msg_build_next(int mode)
{
_faked_msg.id = 1 + _faked_msg_no++;
_faked_msg.id = faked_msg_get_next_id();
_faked_msg.pid = my_pid();
memset(&_faked_msg.tval, 0, sizeof(struct timeval));
if(mode) clear_branches();
@ -80,12 +101,12 @@ static inline sip_msg_t* faked_msg_next_id(int mode)
sip_msg_t* faked_msg_next(void)
{
return faked_msg_next_id(0);
return faked_msg_build_next(0);
}
sip_msg_t* faked_msg_next_clear(void)
{
return faked_msg_next_id(1);
return faked_msg_build_next(1);
}
sip_msg_t* faked_msg_get_next(void)
@ -104,6 +125,19 @@ sip_msg_t* faked_msg_get_next_clear(void)
return faked_msg_next_clear();
}
int faked_msg_get_new(sip_msg_t *fmsg)
{
clear_branches();
if(faked_msg_init_new(fmsg)<0) {
return -1;
}
fmsg->id = faked_msg_get_next_id();
fmsg->pid = my_pid();
memset(&fmsg->tval, 0, sizeof(struct timeval));
return 0;
}
int faked_msg_match(sip_msg_t *tmsg)
{
return ( tmsg == &_faked_msg ) ? 1 : 0;

@ -29,6 +29,7 @@ sip_msg_t* faked_msg_next(void);
sip_msg_t* faked_msg_get_next(void);
sip_msg_t* faked_msg_next_clear(void);
sip_msg_t* faked_msg_get_next_clear(void);
int faked_msg_get_new(sip_msg_t *fmsg);
int faked_msg_match(sip_msg_t *tmsg);
#endif

@ -471,6 +471,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
prev_send_sock=0;
err=0;
memset(&dns_srv_h, 0, sizeof(struct dns_srv_handle));
#endif
buf=0;

@ -136,9 +136,18 @@ static inline int msg_send_buffer(struct dest_info* dst, char* buf, int len,
outb.s = buf;
outb.len = len;
if(!(flags&1)) {
evp.data = (void*)&outb;
evp.dst = dst;
sr_event_exec(SREV_NET_DATA_OUT, &evp);
if(sr_event_enabled(SREV_NET_DATA_OUT)) {
outb.s = (char*)pkg_malloc(len + 1);
if(outb.s==NULL) {
LM_ERR("failed to clone outgoing buffer\n");
return -1;
}
memcpy(outb.s, buf, len);
outb.s[len] = '\0';
evp.data = (void*)&outb;
evp.dst = dst;
sr_event_exec(SREV_NET_DATA_OUT, &evp);
}
}
if(outb.s==NULL) {

@ -420,6 +420,7 @@ static inline void su2ip_addr(struct ip_addr* ip, union sockaddr_union* su)
break;
default:
LM_CRIT("unknown address family %d\n", su->s.sa_family);
memset(ip, 0, sizeof(ip_addr_t));
}
}

@ -839,6 +839,12 @@ static int sr_kemi_core_is_method_in(sip_msg_t *msg, str *vmethod)
return SR_KEMI_TRUE;
}
break;
case 'U':
case 'u':
if(imethod==METHOD_UPDATE) {
return SR_KEMI_TRUE;
}
break;
case 'K':
case 'k':
if(imethod==METHOD_KDMQ) {
@ -863,6 +869,8 @@ static int sr_kemi_core_is_method_in(sip_msg_t *msg, str *vmethod)
return SR_KEMI_TRUE;
}
break;
default:
LM_WARN("unsupported method flag: %c\n", vmethod->s[i]);
}
}
return SR_KEMI_FALSE;

@ -32,6 +32,17 @@
#include <resolv.h>
#include <string.h>
/*
* Older glibc < 2.25 does not include T_OPT in nameser_compat.h yet.
* On alpine linux musl library it is also not defined. There is no
* musl feature test macro, so we look for glibc instead.
*/
#if (defined __GLIBC__ && __GLIBC__ == 2 && __GLIBC_MINOR__ < 25) || !defined __GLIBC__
#ifndef T_OPT
#define T_OPT ns_t_opt
#endif
#endif
#include "resolve.h"
#include "compiler_opt.h"
#include "dprint.h"
@ -937,6 +948,12 @@ again:
*last=rd;
last=&(rd->next);
break;
case T_OPT:
/* skip DNS extensions, e.g. EDNS0 */
rd->rdata=0;
*last=rd;
last=&(rd->next);
break;
default:
LM_ERR("unknown type %d\n", rtype);
rd->rdata=0;

@ -992,7 +992,6 @@ static int build_iface_list(void)
struct rtgenmsg g;
} req;
int seq = 0;
int rtn = 0;
struct nlmsghdr* nlp;
struct ifaddrmsg *ifi;

@ -1136,18 +1136,31 @@ again:
su2ip_addr(&ip, &my_name);
find_socket:
#ifdef USE_TLS
if (unlikely(type==PROTO_TLS))
if (unlikely(type==PROTO_TLS)) {
*res_si=find_si(&ip, 0, PROTO_TLS);
else
#endif
} else {
*res_si=find_si(&ip, 0, PROTO_TCP);
}
#else
*res_si=find_si(&ip, 0, PROTO_TCP);
#endif
if (unlikely(*res_si==0)){
LM_WARN("%s: could not find corresponding"
" listening socket for %s, using default...\n",
su2a(server, sizeof(*server)), ip_addr2a(&ip));
#ifdef USE_TLS
if (unlikely(type==PROTO_TLS)) {
if (server->s.sa_family==AF_INET) *res_si=sendipv4_tls;
else *res_si=sendipv6_tls;
} else {
if (server->s.sa_family==AF_INET) *res_si=sendipv4_tcp;
else *res_si=sendipv6_tcp;
}
#else
if (server->s.sa_family==AF_INET) *res_si=sendipv4_tcp;
else *res_si=sendipv6_tcp;
#endif
}
*res_local_addr=*from;
return s;

@ -635,12 +635,12 @@ static inline int str2int(str* _s, unsigned int* _r)
{
int i;
if (_s == NULL) return -1;
if (_r == NULL) return -1;
*_r = 0;
if (_s == NULL) return -1;
if (_s->len < 0) return -1;
if (_s->s == NULL) return -1;
*_r = 0;
for(i = 0; i < _s->len; i++) {
if ((_s->s[i] >= '0') && (_s->s[i] <= '9')) {
*_r *= 10;

@ -336,6 +336,12 @@
#define USE_DST_BLACKLIST_STATS_STR ""
#endif
#ifdef KSR_PTHREAD_MUTEX_SHARED
#define KSR_PTHREAD_MUTEX_SHARED_STR ", TLS_PTHREAD_MUTEX_SHARED"
#else
#define KSR_PTHREAD_MUTEX_SHARED_STR ""
#endif
#define SER_COMPILE_FLAGS \
STATS_STR EXTRA_DEBUG_STR USE_TCP_STR USE_TLS_STR \
USE_SCTP_STR CORE_TLS_STR TLS_HOOKS_STR USE_RAW_SOCKS_STR \
@ -350,7 +356,8 @@
USE_SYSV_SEM_STR USE_COMP_STR USE_DNS_CACHE_STR USE_DNS_FAILOVER_STR \
DNS_WATCHDOG_SUPPORT_STR USE_NAPTR_STR USE_DST_BLACKLIST_STR \
HAVE_RESOLV_RES_STR SYSLOG_CALLBACK_SUPPORT_STR MYSQL_FAKE_NULL_STR \
USE_DST_BLACKLIST_STATS_STR USE_DNS_CACHE_STATS_STR
USE_DST_BLACKLIST_STATS_STR USE_DNS_CACHE_STATS_STR \
KSR_PTHREAD_MUTEX_SHARED_STR
#endif

@ -100,12 +100,13 @@ static int parse_db_url(struct db_id* id, const str* url)
ST_USER_HOST, /* Username or hostname */
ST_PASS_PORT, /* Password or port part */
ST_HOST, /* Hostname part */
ST_HOST6, /* Hostname part IPv6 */
ST_PORT, /* Port part */
ST_DB /* Database part */
};
enum state st;
unsigned int len, i, j, a, foundanother;
unsigned int len, i, j, a, foundanother, ipv6_flag=0;
const char* begin;
char* prev_token;
@ -188,6 +189,11 @@ static int parse_db_url(struct db_id* id, const str* url)
begin = url->s + i + 1;
break;
case '[':
st = ST_HOST6;
begin = url->s + i + 1;
break;
case '/':
if (dupl_string(&id->host, begin, url->s + i) < 0) goto err;
if (dupl_string_name(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
@ -224,19 +230,33 @@ static int parse_db_url(struct db_id* id, const str* url)
case ST_HOST:
switch(url->s[i]) {
case '[':
st = ST_HOST6;
begin = url->s + i + 1;
break;
case ':':
st = ST_PORT;
if (dupl_string(&id->host, begin, url->s + i) < 0) goto err;
if (dupl_string(&id->host, begin, url->s + i - ipv6_flag) < 0) goto err;
begin = url->s + i + 1;
break;
case '/':
if (dupl_string(&id->host, begin, url->s + i) < 0) goto err;
if (dupl_string(&id->host, begin, url->s + i - ipv6_flag) < 0) goto err;
if (dupl_string_name(&id->database, url->s + i + 1, url->s + len) < 0) goto err;
return 0;
}
break;
case ST_HOST6:
switch(url->s[i]) {
case ']':
ipv6_flag = 1;
st = ST_HOST;
break;
}
break;
case ST_PORT:
switch(url->s[i]) {
case '/':

@ -30,6 +30,12 @@
* sip router core part.
*/
#ifdef KSR_PTHREAD_MUTEX_SHARED
#define _GNU_SOURCE
#include <pthread.h>
#include <dlfcn.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
@ -1563,12 +1569,20 @@ int main_loop(void)
/* get first ipv4/ipv6 socket*/
if ((si->address.af==AF_INET)&&
((sendipv4_tls==0) ||
(sendipv4_tls->flags&(SI_IS_LO|SI_IS_MCAST))))
(sendipv4_tls->flags&(SI_IS_LO|SI_IS_MCAST)))) {
sendipv4_tls=si;
if(sendipv4_tcp==0) {
sendipv4_tcp=si;
}
}
if( ((sendipv6_tls==0) ||
(sendipv6_tls->flags&(SI_IS_LO|SI_IS_MCAST))) &&
(si->address.af==AF_INET6))
(si->address.af==AF_INET6)) {
sendipv6_tls=si;
if(sendipv6_tcp==0) {
sendipv6_tcp=si;
}
}
}
}
#endif /* USE_TLS */
@ -2716,3 +2730,72 @@ error:
}
return -1;
}
#ifdef KSR_PTHREAD_MUTEX_SHARED
/**
* code to set PTHREAD_PROCESS_SHARED attribute for phtread mutex to cope
* with libssl 1.1+ thread-only mutex initialization
*/
#define SYMBOL_EXPORT __attribute__((visibility("default")))
int SYMBOL_EXPORT pthread_mutex_init (pthread_mutex_t *__mutex,
const pthread_mutexattr_t *__mutexattr)
{
static int (*real_pthread_mutex_init)(pthread_mutex_t *__mutex,
const pthread_mutexattr_t *__mutexattr) = 0;
pthread_mutexattr_t attr;
int ret;
if (!real_pthread_mutex_init) {
real_pthread_mutex_init = dlsym(RTLD_NEXT, "pthread_mutex_init");
if (!real_pthread_mutex_init) {
return -1;
}
}
if (__mutexattr) {
pthread_mutexattr_t attr = *__mutexattr;
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
return real_pthread_mutex_init(__mutex, &attr);
}
pthread_mutexattr_init(&attr);
pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
ret = real_pthread_mutex_init(__mutex, &attr);
pthread_mutexattr_destroy(&attr);
return ret;
}
int SYMBOL_EXPORT pthread_rwlock_init (pthread_rwlock_t *__restrict __rwlock,
const pthread_rwlockattr_t *__restrict __attr)
{
static int (*real_pthread_rwlock_init)(pthread_rwlock_t *__restrict __rwlock,
const pthread_rwlockattr_t *__restrict __attr) = 0;
pthread_rwlockattr_t attr;
int ret;
if (!real_pthread_rwlock_init) {
real_pthread_rwlock_init = dlsym(RTLD_NEXT, "pthread_rwlock_init");
if (!real_pthread_rwlock_init) {
return -1;
}
}
if (__attr) {
pthread_rwlockattr_t attr = *__attr;
pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
return real_pthread_rwlock_init(__rwlock, &attr);
}
pthread_rwlockattr_init(&attr);
pthread_rwlockattr_setpshared(&attr, PTHREAD_PROCESS_SHARED);
ret = real_pthread_rwlock_init(__rwlock, &attr);
pthread_rwlockattr_destroy(&attr);
return ret;
}
#endif

@ -684,7 +684,8 @@ modparam("acc", "early_media", 1)
6.2. failed_transaction_flag (integer)
Per transaction flag which says if the transaction should be accounted
also in case of failure (status>=300).
also in case of failure (SIP status code >= 300). This flag triggers
accouting when the whole transaction fails (on the server side).
Default value is not-set (no flag).
@ -818,12 +819,12 @@ modparam("acc", "log_flag", 2)
Request flag which needs to be set to account missed calls via syslog.
This can be used to e.g. account failures during the call setup phase
from the callee side, for example if you do forking to several
from the callee (client) side, for example if you do forking to several
destinations.
Keep in mind that this flag is reset after processing. Therefore it is
necessary to set it again e.g. in a failure_route if you do serial
forking and want to log all attempts.
Keep in mind that this flag is reset after branch completion. Therefore
it is necessary to set it again e.g. in a failure_route if you do
serial forking and want to log all attempts.
Default value is not-set (no flag).
@ -882,8 +883,14 @@ modparam("acc", "db_flag", 2)
6.16. db_missed_flag (integer)
Request flag which needs to be set to account missed calls -- database
specific.
Request flag which needs to be set to account missed calls via
database. This can be used to e.g. account failures during the call
setup phase from the callee (client) side, for example if you do
forking to several destinations.
Keep in mind that this flag is reset after branch completion. Therefore
it is necessary to set it again e.g. in a failure_route if you do
serial forking and want to log all attempts.
Default value is not-set (no flag).

@ -489,7 +489,9 @@ modparam("acc", "early_media", 1)
<title><varname>failed_transaction_flag</varname> (integer)</title>
<para>
Per transaction flag which says if the transaction should be
accounted also in case of failure (status>=300).
accounted also in case of failure (SIP status code >= 300).
This flag triggers accouting when the whole transaction fails
(on the server side).
</para>
<para>
Default value is not-set (no flag).
@ -679,12 +681,12 @@ modparam("acc", "log_flag", 2)
<para>
Request flag which needs to be set to account missed calls via syslog.
This can be used to e.g. account failures during the call setup phase
from the callee side, for example if you do forking to several
from the callee (client) side, for example if you do forking to several
destinations.
</para>
<para>
Keep in mind that this flag is reset after processing. Therefore it is
necessary to set it again e.g. in a failure_route if you do serial
Keep in mind that this flag is reset after branch completion. Therefore
it is necessary to set it again e.g. in a failure_route if you do serial
forking and want to log all attempts.
</para>
<para>
@ -775,8 +777,15 @@ modparam("acc", "db_flag", 2)
<section id="acc.p.db_missed_flag">
<title><varname>db_missed_flag</varname> (integer)</title>
<para>
Request flag which needs to be set to account missed
calls -- database specific.
Request flag which needs to be set to account missed calls via database.
This can be used to e.g. account failures during the call setup phase
from the callee (client) side, for example if you do forking to several
destinations.
</para>
<para>
Keep in mind that this flag is reset after branch completion. Therefore
it is necessary to set it again e.g. in a failure_route if you do serial
forking and want to log all attempts.
</para>
<para>
Default value is not-set (no flag).

@ -201,7 +201,7 @@ PerlInterpreter *parser_init(void) {
perl_construct(new_perl);
argv[0] = ""; argc++; /* First param _needs_ to be empty */
/* Possible Include path extension by modparam */
if (modpath && (strlen(modpath) > 0)) {
modpathset_start = argc;
@ -262,6 +262,8 @@ PerlInterpreter *parser_init(void) {
*
*/
int unload_perl(PerlInterpreter *p) {
/* clean and reset everything */
PL_perl_destruct_level = 1;
perl_destruct(p);
perl_free(p);
@ -276,26 +278,26 @@ int unload_perl(PerlInterpreter *p) {
*/
int perl_reload(void)
{
PerlInterpreter *new_perl;
new_perl = parser_init();
if (new_perl) {
if(my_perl) {
unload_perl(my_perl);
my_perl = new_perl;
}
my_perl = parser_init();
#ifdef PERL_EXIT_DESTRUCT_END
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;
#else
#warning Perl 5.8.x should be used. Please upgrade.
#warning This binary will be unsupported.
PL_exit_flags |= PERL_EXIT_EXPECTED;
PL_exit_flags |= PERL_EXIT_EXPECTED;
#endif
if(my_perl) {
LM_DBG("new perl interpreter initialized\n");
return 0;
} else {
return -1;
LM_CRIT("failed to initialize a new perl interpreter - exiting\n");
exit(-1);
}
}
@ -380,6 +382,7 @@ static void destroy(void)
}
static int app_perl_reset_n = 0;
/**
* count executions and rest interpreter
*
@ -400,8 +403,10 @@ int app_perl_reset_interpreter(void)
if(_ap_exec_cycles<=*_ap_reset_cycles)
return 0;
if(perl_destroy_func)
call_argv(perl_destroy_func, G_DISCARD | G_NOARGS, args);
if(perl_destroy_func) {
call_argv(perl_destroy_func, G_DISCARD | G_NOARGS | G_EVAL, args);
LM_DBG("perl destroy function executed\n");
}
gettimeofday(&t1, NULL);
if (perl_reload()<0) {
@ -411,10 +416,11 @@ int app_perl_reset_interpreter(void)
}
gettimeofday(&t2, NULL);
LM_INFO("perl interpreter has been reset [%d/%d] (%d.%06d => %d.%06d)\n",
app_perl_reset_n++;
LM_INFO("perl interpreter has been reset [%d/%d] (%d.%06d => %d.%06d) (n: %d)\n",
_ap_exec_cycles, *_ap_reset_cycles,
(int)t1.tv_sec, (int)t1.tv_usec,
(int)t2.tv_sec, (int)t2.tv_usec);
(int)t2.tv_sec, (int)t2.tv_usec, app_perl_reset_n);
_ap_exec_cycles = 0;
return 0;

@ -269,16 +269,16 @@ PyObject *sr_apy_kemi_exec_func_ex(sr_kemi_t *ket, PyObject *self,
}
LM_DBG("params[%d] for: %.*s are int-int-int: [%d] [%d] [%d]\n",
i, fname.len, fname.s, vps[0].n, vps[1].n, vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "iis:kemi-param-nns", &vps[0].n,
&vps[1].n, &vps[2].s.s)) {
LM_ERR("unable to retrieve int-int-str params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are int-int-str: [%d] [%d] [%.*s]\n", i,
fname.len, fname.s, vps[0].n, vps[1].n, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "iis:kemi-param-nns", &vps[0].n,
&vps[1].n, &vps[2].s.s)) {
LM_ERR("unable to retrieve int-int-str params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are int-int-str: [%d] [%d] [%.*s]\n", i,
fname.len, fname.s, vps[0].n, vps[1].n, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "isi:kemi-param-nsn", &vps[0].n,
@ -289,6 +289,18 @@ PyObject *sr_apy_kemi_exec_func_ex(sr_kemi_t *ket, PyObject *self,
vps[1].s.len = strlen(vps[1].s.s);
LM_DBG("params[%d] for: %.*s are int-str-int: [%d] [%.*s] [%d]\n", i,
fname.len, fname.s, vps[0].n, vps[1].s.len, vps[1].s.s, vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "iss:kemi-param-nss", &vps[0].n,
&vps[1].s.s, &vps[2].s.s)) {
LM_ERR("unable to retrieve int-str-str param %d\n", i);
return sr_kemi_apy_return_false();
}
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are int-str-str: [%d] [%.*s]"
" [%.*s]\n", i, fname.len, fname.s,
vps[0].n, vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "sii:kemi-param-snn", &vps[0].s.s,
@ -300,6 +312,19 @@ PyObject *sr_apy_kemi_exec_func_ex(sr_kemi_t *ket, PyObject *self,
LM_DBG("params[%d] for: %.*s are str-int: [%.*s] [%d] [%d]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s, vps[1].n,
vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "sis:kemi-param-ssn", &vps[0].s.s,
&vps[1].n, &vps[2].s.s)) {
LM_ERR("unable to retrieve str-int-str param %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are str-str-int: [%.*s] [%d] [%.*s]\n",
i, fname.len, fname.s,
vps[0].s.len, vps[0].s.s,
vps[1].n, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "ssi:kemi-param-ssn", &vps[0].s.s,
@ -323,7 +348,7 @@ PyObject *sr_apy_kemi_exec_func_ex(sr_kemi_t *ket, PyObject *self,
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are str-str-int: [%.*s] [%.*s]"
LM_DBG("params[%d] for: %.*s are str-str-str: [%.*s] [%.*s]"
" [%.*s]\n", i, fname.len, fname.s,
vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s);

@ -277,15 +277,15 @@ PyObject *sr_apy_kemi_exec_func_ex(sr_kemi_t *ket, PyObject *self, PyObject *arg
LM_DBG("params[%d] for: %.*s are int-int-int: [%d] [%d] [%d]\n",
i, fname.len, fname.s, vps[0].n, vps[1].n, vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_STR) {
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "iis:kemi-param-nns", &vps[0].n,
&vps[1].n, &vps[2].s.s)) {
&vps[1].n, &vps[2].s.s)) {
LM_ERR("unable to retrieve int-int-str params %d\n", i);
return sr_kemi_apy_return_false();
}
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are int-int-str: [%d] [%d] [%.*s]\n", i,
fname.len, fname.s, vps[0].n, vps[1].n, vps[2].s.len, vps[2].s.s);
fname.len, fname.s, vps[0].n, vps[1].n, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "isi:kemi-param-nsn", &vps[0].n,
@ -296,6 +296,18 @@ PyObject *sr_apy_kemi_exec_func_ex(sr_kemi_t *ket, PyObject *self, PyObject *arg
vps[1].s.len = strlen(vps[1].s.s);
LM_DBG("params[%d] for: %.*s are int-str-int: [%d] [%.*s] [%d]\n", i,
fname.len, fname.s, vps[0].n, vps[1].s.len, vps[1].s.s, vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_INT && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "iss:kemi-param-nss", &vps[0].n,
&vps[1].s.s, &vps[2].s.s)) {
LM_ERR("unable to retrieve int-str-str param %d\n", i);
return sr_kemi_apy_return_false();
}
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are int-str-str: [%d] [%.*s]"
" [%.*s]\n", i, fname.len, fname.s,
vps[0].n, vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "sii:kemi-param-snn", &vps[0].s.s,
@ -307,6 +319,19 @@ PyObject *sr_apy_kemi_exec_func_ex(sr_kemi_t *ket, PyObject *self, PyObject *arg
LM_DBG("params[%d] for: %.*s are str-int: [%.*s] [%d] [%d]\n", i,
fname.len, fname.s, vps[0].s.len, vps[0].s.s, vps[1].n,
vps[2].n);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_INT
&& ket->ptypes[2]==SR_KEMIP_STR) {
if(!PyArg_ParseTuple(args, "sis:kemi-param-ssn", &vps[0].s.s,
&vps[1].n, &vps[2].s.s)) {
LM_ERR("unable to retrieve str-int-str param %d\n", i);
return sr_kemi_apy_return_false();
}
vps[0].s.len = strlen(vps[0].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are str-str-int: [%.*s] [%d] [%.*s]\n",
i, fname.len, fname.s,
vps[0].s.len, vps[0].s.s,
vps[1].n, vps[2].s.len, vps[2].s.s);
} else if(ket->ptypes[0]==SR_KEMIP_STR && ket->ptypes[1]==SR_KEMIP_STR
&& ket->ptypes[2]==SR_KEMIP_INT) {
if(!PyArg_ParseTuple(args, "ssi:kemi-param-ssn", &vps[0].s.s,
@ -330,7 +355,7 @@ PyObject *sr_apy_kemi_exec_func_ex(sr_kemi_t *ket, PyObject *self, PyObject *arg
vps[0].s.len = strlen(vps[0].s.s);
vps[1].s.len = strlen(vps[1].s.s);
vps[2].s.len = strlen(vps[2].s.s);
LM_DBG("params[%d] for: %.*s are str-str-int: [%.*s] [%.*s]"
LM_DBG("params[%d] for: %.*s are str-str-str: [%.*s] [%.*s]"
" [%.*s]\n", i, fname.len, fname.s,
vps[0].s.len, vps[0].s.s,
vps[1].s.len, vps[1].s.s, vps[2].s.len, vps[2].s.s);

@ -1380,7 +1380,7 @@ static int attr_hdr_body2attrs2(struct sip_msg* msg, char* header_, char* prefix
static int attr_hdr_body2attrs_fixup(void **param, int param_no)
{
char *c, *params;
hdr_name_t *h;
hdr_name_t *h = NULL;
int n;
str *s;
if(param_no == 1) {
@ -1427,6 +1427,7 @@ static int attr_hdr_body2attrs_fixup(void **param, int param_no)
LOG(L_ERR, "attr_hdr_body2attrs_fixup: bad field param "
"modifier near '%s'\n",
params);
pkg_free(h);
return E_CFG;
}
params++;
@ -1434,6 +1435,7 @@ static int attr_hdr_body2attrs_fixup(void **param, int param_no)
if(!h->val_types) {
LOG(L_ERR, "attr_hdr_body2attrs_fixup: no field param modifier "
"specified\n");
pkg_free(h);
return E_CFG;
}
} else {

@ -141,6 +141,7 @@ int nio_msg_sent(sr_event_param_t *evp)
int_str avp_value;
struct usr_avp *avp;
struct run_act_ctx ra_ctx;
str nbuf = STR_NULL;
obuf = (str*)evp->data;
@ -163,7 +164,15 @@ int nio_msg_sent(sr_event_param_t *evp)
if(avp!=NULL && is_avp_str_val(avp)) {
msg.buf = avp_value.s.s;
msg.len = avp_value.s.len;
obuf->s = nio_msg_update(&msg, (unsigned int*)&obuf->len);
nbuf.s = nio_msg_update(&msg, (unsigned int*)&nbuf.len);
if(nbuf.s!=NULL) {
LM_DBG("new outbound buffer generated\n");
pkg_free(obuf->s);
obuf->s = nbuf.s;
obuf->len = nbuf.len;
} else {
LM_ERR("failed to generate new outbound buffer\n");
}
} else {
LM_WARN("no value set for AVP %.*s, using unmodified message\n",
nio_msg_avp_param.len, nio_msg_avp_param.s);

@ -61,6 +61,13 @@ Chapter 1. Admin Guide
1. Overview
Note: the module requires old version of external library, not
compiling with those available out of the stock in the Linux
distributions. It is going to be kept for a while in case someone wants
to pick it up and upgrade. Also, the module was never extensively
tested, therefore take the appropriate actions in case you plan to use
it.
Db_cassandra is one of the Kamailio database modules. It does not
export any functions executable from the configuration scripts, but it
exports a subset of functions using the database API, and thus, other

@ -16,6 +16,13 @@
<section>
<title>Overview</title>
<para>
Note: the module requires old version of external library, not compiling
with those available out of the stock in the Linux distributions. It is
going to be kept for a while in case someone wants to pick it up and
upgrade. Also, the module was never extensively tested, therefore take
the appropriate actions in case you plan to use it.
</para>
<para>
Db_cassandra is one of the &kamailio; database modules. It does
not export any functions executable from the configuration scripts,

@ -89,7 +89,7 @@ static int db_mysql_submit_query(const db1_con_t* _h, const str* _s)
}
}
/*
* We're doing later a query anyway that will reset the timout of the server,
* We're doing later a query anyway that will reset the timeout of the server,
* so it makes sense to set the timestamp value to the actual time in order
* to prevent unnecessary pings.
*/

@ -95,12 +95,13 @@ static int parse_mysql_uri(struct my_uri* res, str* uri)
ST_USER_HOST, /* Username or hostname */
ST_PASS_PORT, /* Password or port part */
ST_HOST, /* Hostname part */
ST_HOST6, /* Hostname part IPv6 */
ST_PORT, /* Port part */
ST_DB /* Database part */
};
enum state st;
int i;
int i, ipv6_flag=0;
const char* begin;
char* prev_token;
@ -156,6 +157,11 @@ static int parse_mysql_uri(struct my_uri* res, str* uri)
begin = uri->s + i + 1;
break;
case '[':
st = ST_HOST6;
begin = uri->s + i + 1;
break;
case '/':
if (dupl_string(&res->host, begin, uri->s + i) < 0) goto err;
if (dupl_string(&res->database, uri->s + i + 1, uri->s + uri->len) < 0) goto err;
@ -184,19 +190,33 @@ static int parse_mysql_uri(struct my_uri* res, str* uri)
case ST_HOST:
switch(uri->s[i]) {
case '[':
st = ST_HOST6;
begin = uri->s + i + 1;
break;
case ':':
st = ST_PORT;
if (dupl_string(&res->host, begin, uri->s + i) < 0) goto err;
if (dupl_string(&res->host, begin, uri->s + i - ipv6_flag) < 0) goto err;
begin = uri->s + i + 1;
break;
case '/':
if (dupl_string(&res->host, begin, uri->s + i) < 0) goto err;
if (dupl_string(&res->host, begin, uri->s + i - ipv6_flag) < 0) goto err;
if (dupl_string(&res->database, uri->s + i + 1, uri->s + uri->len) < 0) goto err;
return 0;
}
break;
case ST_HOST6:
switch(uri->s[i]) {
case ']':
ipv6_flag = 1;
st = ST_HOST;
break;
}
break;
case ST_PORT:
switch(uri->s[i]) {
case '/':

@ -109,12 +109,13 @@ static int parse_postgres_uri(struct pg_uri *res, str *uri)
ST_USER_HOST, /* Username or hostname */
ST_PASS_PORT, /* Password or port part */
ST_HOST, /* Hostname part */
ST_HOST6, /* Hostname part IPv6 */
ST_PORT, /* Port part */
ST_DB /* Database part */
};
enum state st;
int i;
int i, ipv6_flag=0;
const char *begin;
char *prev_token;
@ -172,6 +173,11 @@ static int parse_postgres_uri(struct pg_uri *res, str *uri)
begin = uri->s + i + 1;
break;
case '[':
st = ST_HOST6;
begin = uri->s + i + 1;
break;
case '/':
if(memchr(uri->s + i + 1, '/', uri->len - i - 1)
!= NULL)
@ -212,9 +218,14 @@ static int parse_postgres_uri(struct pg_uri *res, str *uri)
case ST_HOST:
switch(uri->s[i]) {
case '[':
st = ST_HOST6;
begin = uri->s + i + 1;
break;
case ':':
st = ST_PORT;
if(dupl_string(&res->host, begin, uri->s + i) < 0)
if(dupl_string(&res->host, begin, uri->s + i - ipv6_flag) < 0)
goto err;
begin = uri->s + i + 1;
break;
@ -223,7 +234,7 @@ static int parse_postgres_uri(struct pg_uri *res, str *uri)
if(memchr(uri->s + i + 1, '/', uri->len - i - 1)
!= NULL)
break;
if(dupl_string(&res->host, begin, uri->s + i) < 0)
if(dupl_string(&res->host, begin, uri->s + i - ipv6_flag) < 0)
goto err;
if(dupl_string(&res->database, uri->s + i + 1,
uri->s + uri->len)
@ -233,6 +244,15 @@ static int parse_postgres_uri(struct pg_uri *res, str *uri)
}
break;
case ST_HOST6:
switch(uri->s[i]) {
case ']':
ipv6_flag = 1;
st = ST_HOST;
break;
}
break;
case ST_PORT:
switch(uri->s[i]) {
case '/':

@ -235,6 +235,7 @@ loadmodule "db_redis.so"
#!define DBURL_ACC "redis://127.0.0.1:6379/6"
#!define DBURL_AUTH "redis://127.0.0.1:6379/7"
#!define DBURL_PERM "redis://127.0.0.1:6379/8"
#!define DBURL_DLG "redis://127.0.0.1:6379/9"
...
modparam("db_redis", "schema_path", "/usr/share/kamailio/db_redis/kamailio")
modparam("db_redis", "keys", "version=entry:table_name")
@ -242,6 +243,9 @@ modparam("db_redis", "keys", "location=entry:ruid&usrdom:username,domain&timer:p
artition,keepalive")
modparam("db_redis", "keys", "acc=entry:callid,time_hires&cid:callid")
modparam("db_redis", "keys", "subscriber=entry:username,domain")
modparam("db_redis", "keys", "dialog=entry:hash_entry,hash_id&cid:callid")
modparam("db_redis", "keys", "dialog_vars=entry:hash_entry,hash_id,dialog_key&di
alog:hash_entry,hash_id")
...
modparam("usrloc", "db_url", DBURL_USRLOC)
...
@ -250,6 +254,8 @@ modparam("acc_db", "db_url", DBURL_ACC)
modparam("auth_db", "db_url", DBURL_AUTH)
...
modparam("permissions", "db_url", DBURL_PERM)
...
modparam("dialog", "db_url", DBURL_DLG)
...
Samples adding records for address table using 'redis-cli':

@ -226,12 +226,15 @@ loadmodule "db_redis.so"
#!define DBURL_ACC "redis://127.0.0.1:6379/6"
#!define DBURL_AUTH "redis://127.0.0.1:6379/7"
#!define DBURL_PERM "redis://127.0.0.1:6379/8"
#!define DBURL_DLG "redis://127.0.0.1:6379/9"
...
modparam("db_redis", "schema_path", "/usr/share/kamailio/db_redis/kamailio")
modparam("db_redis", "keys", "version=entry:table_name")
modparam("db_redis", "keys", "location=entry:ruid&amp;usrdom:username,domain&amp;timer:partition,keepalive")
modparam("db_redis", "keys", "acc=entry:callid,time_hires&amp;cid:callid")
modparam("db_redis", "keys", "subscriber=entry:username,domain")
modparam("db_redis", "keys", "dialog=entry:hash_entry,hash_id&amp;cid:callid")
modparam("db_redis", "keys", "dialog_vars=entry:hash_entry,hash_id,dialog_key&amp;dialog:hash_entry,hash_id")
...
modparam("usrloc", "db_url", DBURL_USRLOC)
...
@ -240,6 +243,8 @@ modparam("acc_db", "db_url", DBURL_ACC)
modparam("auth_db", "db_url", DBURL_AUTH)
...
modparam("permissions", "db_url", DBURL_PERM)
...
modparam("dialog", "db_url", DBURL_DLG)
...
</programlisting>
</example>

@ -12,18 +12,12 @@ Edited by
Bogdan-Andrei Iancu
Edited by
Carsten Bock
Edited by
Alex Balashov
<abalashov@evaristesys.com>
Edited by
Olle E. Johansson
<oej@edvina.net>
@ -1381,10 +1375,11 @@ modparam("dialog", "h_id_start", 5)
selected at startup, then incremented by 1 for each new dialog. Setting
h_id_start and h_id_step to non-default values should be done when
using dlg_db_load_callid(...) or dlg_db_load_extra() to load dialog
records generated by another Kamailio instance, making also sure that
those Kamailio nstances are not going to generate overalapping dialog
hash id values by using different h_id_start and the same h_id_step
(h_id_step has to be greater than the maximum value of h_id_start).
records generated by another Kamailio instance. Pay attention to ensure
that those Kamailio instances are not going to generate overlapping
dialog hash id values by using different h_id_start and the same
h_id_step (h_id_step has to be greater than the maximum value of
h_id_start).
Default value is “1”.
@ -1917,9 +1912,9 @@ kamcmd dlg.list_ctx
RPC Command Format:
...
kamcmd dlg.list abcdrssfrs122444@192.168.1.1 AAdfeEFF33
kamcmd dlg.dlg_list abcdrssfrs122444@192.168.1.1 AAdfeEFF33
...
kamcmd dlg.list abcdrssfrs122444@192.168.1.1
kamcmd dlg.dlg_list abcdrssfrs122444@192.168.1.1
...
9.4. dlg.dlg_list_ctx
@ -2217,36 +2212,36 @@ Chapter 3. Frequently Asked Questions
3.1.
What happened with “use_tight_match” parameter?
What happened with “use_tight_match” parameter?
The parameter was removed with version 1.3 as the option of tight
matching became mandatory and not configurable. Now, the tight matching
is done all the time (when using DID matching).
The parameter was removed with version 1.3 as the option of tight
matching became mandatory and not configurable. Now, the tight matching
is done all the time (when using DID matching).
3.2.
Where can I find more about Kamailio?
Where can I find more about Kamailio?
Take a look at https://www.kamailio.org/.
Take a look at https://www.kamailio.org/.
3.3.
Where can I post a question about this module?
Where can I post a question about this module?
First at all check if your question was already answered on one of our
mailing lists:
* User Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
* Developer Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev
First at all check if your question was already answered on one of our
mailing lists:
* User Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
* Developer Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev
E-mails regarding any stable Kamailio release should be sent to
<sr-users@lists.kamailio.org> and e-mails regarding development
versions should be sent to <sr-dev@lists.kamailio.org>.
E-mails regarding any stable Kamailio release should be sent to
<sr-users@lists.kamailio.org> and e-mails regarding development
versions should be sent to <sr-dev@lists.kamailio.org>.
3.4.
How can I report a bug?
How can I report a bug?
Please follow the guidelines provided at:
https://github.com/kamailio/kamailio/issues.
Please follow the guidelines provided at:
https://github.com/kamailio/kamailio/issues.

@ -707,7 +707,6 @@ static int mod_init(void)
}
}
destroy_dlg_callbacks( DLGCB_LOADED );
/* timer process to send keep alive requests */
if(dlg_ka_timer>0 && dlg_ka_interval>0)

@ -232,6 +232,23 @@ void run_create_callbacks(struct dlg_cell *dlg, struct sip_msg *msg)
return;
}
void run_dlg_load_callbacks(struct dlg_cell *dlg)
{
struct dlg_callback *cb;
if (load_cbs && load_cbs!=POINTER_CLOSED_MARKER) {
for ( cb=load_cbs->first; cb; cb=cb->next ) {
params.req = NULL;
params.rpl = NULL;
params.direction = DLG_DIR_NONE;
params.param = &cb->param;
cb->callback( dlg, DLGCB_LOADED, &params );
}
}
return;
}
void run_dlg_callbacks( int type ,
struct dlg_cell *dlg,

@ -109,6 +109,7 @@ void run_dlg_callbacks( int type ,
void run_load_callbacks( void );
void run_dlg_load_callbacks(struct dlg_cell *dlg);
/*!
* \brief Function that returns valid SIP message from given dialog callback parameter struct

@ -364,6 +364,7 @@ int dlg_cseq_msg_sent(sr_event_param_t *evp)
struct via_body *via;
hdr_field_t *hfk = NULL;
sr_cfgenv_t *cenv = NULL;
str nbuf = STR_NULL;
obuf = (str*)evp->data;
memset(&msg, 0, sizeof(sip_msg_t));
@ -520,11 +521,13 @@ int dlg_cseq_msg_sent(sr_event_param_t *evp)
}
}
/* replace old msg content */
obuf->s = pkg_malloc((tbuf_len+1)*sizeof(char));
if(obuf->s==NULL) {
nbuf.s = pkg_malloc((tbuf_len+1)*sizeof(char));
if(nbuf.s==NULL) {
LM_ERR("not enough memory for new message\n");
goto done;
}
pkg_free(obuf->s);
obuf->s = nbuf.s;
memcpy(obuf->s, tbuf, tbuf_len);
obuf->s[tbuf_len] = 0;
obuf->len = tbuf_len;

@ -40,6 +40,7 @@
#include "../../core/counters.h"
#include "dlg_hash.h"
#include "dlg_var.h"
#include "dlg_cb.h"
#include "dlg_profile.h"
#include "dlg_db_handler.h"
@ -452,7 +453,7 @@ int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows,
dlg_set_toroute(dlg, &toroute_name);
GET_STR_VALUE(xdata, values, 21, 0, 0);
if(xdata.s!=NULL && dlg->state!=DLG_STATE_DELETED)
if(xdata.len > 0 && xdata.s!=NULL && dlg->state!=DLG_STATE_DELETED)
{
srjson_InitDoc(&jdoc, NULL);
jdoc.buf = xdata;
@ -488,6 +489,7 @@ int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows,
get_ticks());
dlg->dflags = 0;
if(mode!=0) {
if(loaded_extra<DLG_MAX_DB_LOAD_EXTRA) {
dbuid[loaded_extra].h_entry = dlg->h_entry;
@ -497,6 +499,8 @@ int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows,
dlg->dflags |= DLG_FLAG_DB_LOAD_EXTRA;
loaded_extra_more = 1;
}
/* if loading at runtime run the callbacks for the loaded dialog */
run_dlg_load_callbacks(dlg);
}
next_dialog:
;

@ -1428,7 +1428,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
} else if (ret > 0) {
LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] "
"with clid '%.*s' and tags '%.*s' '%.*s'\n",
dlg, dlg->h_entry, dlg->h_id,
dlg->callid.len, dlg->callid.s,
@ -1451,7 +1451,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param)
goto done;
}
if ( (event==DLG_EVENT_REQ || event==DLG_EVENT_REQACK)
if ( (event==DLG_EVENT_REQ || event==DLG_EVENT_REQACK || event==DLG_EVENT_REQPRACK)
&& (new_state==DLG_STATE_CONFIRMED || new_state==DLG_STATE_EARLY)) {
timeout = get_dlg_timeout(req);

@ -208,7 +208,7 @@ void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps){
dlg->tag[DLG_CALLER_LEG].len, dlg->tag[DLG_CALLER_LEG].s,
dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s);
} else if (ret > 0) {
LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] "
"with clid '%.*s' and tags '%.*s' '%.*s'\n",
dlg, dlg->h_entry, dlg->h_id,
dlg->callid.len, dlg->callid.s,

@ -1582,8 +1582,8 @@ modparam("dialog", "h_id_start", 5)
dialog. Setting h_id_start and h_id_step to non-default values
should be done when using dlg_db_load_callid(...) or
dlg_db_load_extra() to load dialog records generated by another
&kamailio; instance, making also sure that those &kamailio;
nstances are not going to generate overalapping dialog hash id
&kamailio; instance. Pay attention to ensure that those &kamailio;
instances are not going to generate overlapping dialog hash id
values by using different h_id_start and the same h_id_step
(h_id_step has to be greater than the maximum value of h_id_start).
</para>
@ -2428,9 +2428,9 @@ if(has_totag()) {
<para>RPC Command Format:</para>
<programlisting format="linespecific">
...
&kamcmd; dlg.list abcdrssfrs122444@192.168.1.1 AAdfeEFF33
&kamcmd; dlg.dlg_list abcdrssfrs122444@192.168.1.1 AAdfeEFF33
...
&kamcmd; dlg.list abcdrssfrs122444@192.168.1.1
&kamcmd; dlg.dlg_list abcdrssfrs122444@192.168.1.1
...
</programlisting>
</section>

@ -37,6 +37,7 @@
#include "../../core/dprint.h"
#include "../../core/ut.h"
#include "../../core/cfg/cfg_struct.h"
#include "../../core/receive.h"
#include "../../core/kemi.h"
#include "../../core/fmsg.h"
@ -150,8 +151,10 @@ int evapi_run_cfg_route(evapi_env_t *evenv, int rt, str *rtname)
if((rt<0) && (_evapi_event_callback.s==NULL || _evapi_event_callback.len<=0))
return 0;
fmsg = faked_msg_next();
memcpy(&tmsg, fmsg, sizeof(sip_msg_t));
if(faked_msg_get_new(&tmsg)<0) {
LM_ERR("failed to get a new faked message\n");
return -1;
}
fmsg = &tmsg;
evapi_set_msg_env(fmsg, evenv);
backup_rt = get_route_type();
@ -170,6 +173,9 @@ int evapi_run_cfg_route(evapi_env_t *evenv, int rt, str *rtname)
}
set_route_type(backup_rt);
evapi_set_msg_env(fmsg, NULL);
/* free the structure -- it is a clone of faked msg */
free_sip_msg(fmsg);
ksr_msg_env_reset();
return 0;
}

@ -338,6 +338,7 @@ int gzc_msg_sent(sr_event_param_t *evp)
unsigned long olen;
unsigned long nlen;
int ret;
str nbuf = STR_NULL;
obuf = (str*)evp->data;
memset(&msg, 0, sizeof(sip_msg_t));
@ -383,7 +384,15 @@ int gzc_msg_sent(sr_event_param_t *evp)
goto done;
}
obuf->s = gzc_msg_update(&msg, (unsigned int*)&obuf->len);
nbuf.s = gzc_msg_update(&msg, (unsigned int*)&nbuf.len);
if(nbuf.s!=NULL) {
LM_DBG("new outbound buffer generated\n");
pkg_free(obuf->s);
obuf->s = nbuf.s;
obuf->len = nbuf.len;
} else {
LM_ERR("failed to generate new outbound buffer\n");
}
done:
free_sip_msg(&msg);

@ -62,39 +62,25 @@ int init_http_m_table(unsigned int size)
unsigned int build_hash_key(void *p)
{
str *hash_str;
char *pointer_str;
int len;
str hash_str;
char pointer_str[20];
unsigned int hash;
pointer_str = (char *)pkg_malloc(sizeof(p) + 1);
if (pointer_str==0) {
LM_ERR("no more pkg mem\n");
hash_str.len = snprintf(pointer_str, 20, "%p", p);
if(hash_str.len<=0 || hash_str.len>=20) {
LM_ERR("failed to print the pointer address\n");
return 0;
}
LM_DBG("received id %p (%d)-> %s (%d)\n", p, (int)sizeof(p), pointer_str,
hash_str.len);
sprintf(pointer_str, "%p", p);
len = strlen(pointer_str);
LM_DBG("received id %p (%d)-> %s (%d)\n", p, (int)sizeof(p), pointer_str, len);
hash_str.s = pointer_str;
hash_str = (str *)pkg_malloc(sizeof(str));
if (hash_str==0) {
LM_ERR("no more pkg mem\n");
pkg_free(pointer_str);
return 0;
}
hash_str->s = pointer_str;
hash_str->len = len;
hash = core_hash(hash_str, 0, hash_size);
hash = core_hash(&hash_str, 0, hash_size);
LM_DBG("hash for %p is %d\n", p, hash);
pkg_free(pointer_str);
pkg_free(hash_str);
return hash;
}

@ -981,7 +981,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) {
dlg->from_tag.len, dlg->from_tag.s);
} else if (ret > 0) {
LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] "
"with clid '%.*s' and tags '%.*s' \n",
dlg, dlg->h_entry, dlg->h_id,
dlg->callid.len, dlg->callid.s,
@ -1020,7 +1020,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) {
dlg->from_tag.len, dlg->from_tag.s);
} else if (ret > 0) {
LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] "
"with clid '%.*s' and tags '%.*s' \n",
dlg, dlg->h_entry, dlg->h_id,
dlg->callid.len, dlg->callid.s,
@ -1056,7 +1056,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) {
dlg->from_tag.len, dlg->from_tag.s);
} else if (ret > 0) {
LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] "
"with clid '%.*s' and tags '%.*s' \n",
dlg, dlg->h_entry, dlg->h_id,
dlg->callid.len, dlg->callid.s,

@ -190,7 +190,7 @@ void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps) {
dlg, dlg->h_entry, dlg->h_id,
dlg->callid.len, dlg->callid.s);
} else if (ret > 0) {
LM_WARN("inconsitent dlg timer data on dlg %p [%u:%u] "
LM_WARN("inconsistent dlg timer data on dlg %p [%u:%u] "
"with clid '%.*s'\n",
dlg, dlg->h_entry, dlg->h_id,
dlg->callid.len, dlg->callid.s);

@ -189,22 +189,30 @@ static int isc_check_session_desc(ims_spt *spt, struct sip_msg *msg) {
*/
static int isc_check_ruri(ims_spt *spt, struct sip_msg *msg) {
char buf[256];
char buf2[256];
regex_t comp;
if (spt->request_uri.len >= sizeof(buf)) {
LM_ERR("RURI \"%.*s\" is to long to be processed (max %d bytes)\n", spt->request_uri.len, spt->request_uri.s, (int) (sizeof(buf) - 1));
LM_ERR("RURI regexp \"%.*s\" is too long to be compiled (max %d bytes)\n", spt->request_uri.len, spt->request_uri.s, (int) (sizeof(buf) - 1));
return FALSE;
}
if (msg->first_line.u.request.uri.len >= sizeof(buf2)) {
LM_ERR("RURI \"%.*s\" is too long to be processed (max %d bytes)\n", msg->first_line.u.request.uri.len, msg->first_line.u.request.uri.s, (int) (sizeof(buf2) - 1));
return FALSE;
}
/* compile the regex for content */
memcpy(buf, spt->request_uri.s, spt->request_uri.len);
buf[spt->request_uri.len] = 0;
if(regcomp(&(comp), buf, REG_ICASE | REG_EXTENDED) != 0) {
if (regcomp(&(comp), buf, REG_ICASE | REG_EXTENDED) != 0) {
LM_ERR("Error compiling the following regexp for RURI content: %.*s\n", spt->request_uri.len, spt->request_uri.s);
return FALSE;
}
if (regexec(&(comp), buf, 0, NULL, 0) == 0) //regex match
memcpy(buf2, msg->first_line.u.request.uri.s, msg->first_line.u.request.uri.len);
buf2[msg->first_line.u.request.uri.len] = 0;
if (regexec(&(comp), buf2, 0, NULL, 0) == 0) //regex match
{
regfree(&(comp));
return TRUE;

@ -104,8 +104,8 @@ int rx_send_str(str *rx_session_id) {
if (auth->u.auth.state == AUTH_ST_DISCON) {
// If we are in DISCON is because an STR was already sent
// so just wait for STA or for Grace Timout to happen
LM_DBG("Hmmm, auth session already in disconnected state\n");
// so just wait for STA or for Grace Timeout to happen
LM_DBG("auth session already in disconnected state\n");
cdpb.AAASessionsUnlock(auth->hash);
return CSCF_RETURN_FALSE;
}

@ -1,4 +1,4 @@
IMS Usrloc PCSCF Module
IMS Registrar SCSCF Module
Jason Penton
@ -810,28 +810,28 @@ Chapter 2. Frequently Asked Questions
2.1.
Where can I find more about Kamailio?
Where can I find more about Kamailio?
Take a look at https://www.kamailio.org/.
Take a look at https://www.kamailio.org/.
2.2.
Where can I post a question about this module?
Where can I post a question about this module?
First at all check if your question was already answered on one of our
mailing lists:
* User Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
* Developer Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev
First at all check if your question was already answered on one of our
mailing lists:
* User Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
* Developer Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev
E-mails regarding any stable Kamailio release should be sent to
<sr-users@lists.kamailio.org> and e-mails regarding development
versions should be sent to <sr-dev@lists.kamailio.org>.
E-mails regarding any stable Kamailio release should be sent to
<sr-users@lists.kamailio.org> and e-mails regarding development
versions should be sent to <sr-dev@lists.kamailio.org>.
2.3.
How can I report a bug?
How can I report a bug?
Please follow the guidelines provided at:
https://github.com/kamailio/kamailio/issues.
Please follow the guidelines provided at:
https://github.com/kamailio/kamailio/issues.

@ -7,7 +7,7 @@
]>
<book>
<bookinfo>
<title>IMS Usrloc PCSCF Module</title>
<title>IMS Registrar SCSCF Module</title>
<productname class="trade">&kamailioname;</productname>

@ -0,0 +1,434 @@
IMS Usrloc SCSCF Module
Jason Penton
Smile Communications
Edited by
Richard Good
Smile Communications
Yasin Caner
Copyright © 2012 Smile Communications
__________________________________________________________________
Table of Contents
1. Admin Guide
1. Overview
2. Dependencies
2.1. Kamailio Modules
3. Parameters
3.1. db_url (string)
3.2. db_mode (string)
3.3. maxcontact (int)
3.4. maxcontact_3gpp (int)
3.5. maxcontact_behaviour (int)
3.6. max_subscribes(int)
3.7. sub_dialog_hash_size(int)
3.8. timer_procs(int)
3.9. timer_interval (int)
3.10. desc_time_order (int)
3.11. matching_mode (int)
3.12. cseq_delay (int)
3.13. fetch_rows(int)
3.14. hash_size (string)
3.15. subs_hash_size (int)
3.16. contacts_hash_size (integer)
3.17. nat_bflag (integer)
3.18. contact_delete_delay (int)
3.19. support_wildcardPSI (int)
3.20. unreg_validity (int)
3.21. user_data_xsd (string)
4. RPC Commands
4.1. ulscscf.status
4.2. ulscscf.showimpu
4.3. ulscscf.snapshot
2. Frequently Asked Questions
List of Examples
1.1. Set db_urlparameter
1.2. Set db_mode(int)
1.3. Set maxcontactparameter
1.4. Set maxcontact_3gppparameter
1.5. Set maxcontact_behaviour parameter
1.6. Set subscription_expires_rangeparameter
1.7. Setsub_dialog_hash_sizeparameter
1.8. Settimer_procsparameter
1.9. Set timer_intervalparameter
1.10. Set desc_time_orderparameter
1.11. Set matching_modeparameter
1.12. Set scscf_nameparameter
1.13. Set fetch_rowsparameter
1.14. Set hash_sizeparameter
1.15. Set subs_hash_sizeparameter
1.16. Set contacts_hash_sizeparameter
1.17. Set nat_bflagparameter
1.18. Set contact_delete_delayparameter
1.19. Set support_wildcardPSI parameter
1.20. Set unreg_validity parameter
1.21. Set unreg_validity parameter
Chapter 1. Admin Guide
Table of Contents
1. Overview
2. Dependencies
2.1. Kamailio Modules
3. Parameters
3.1. db_url (string)
3.2. db_mode (string)
3.3. maxcontact (int)
3.4. maxcontact_3gpp (int)
3.5. maxcontact_behaviour (int)
3.6. max_subscribes(int)
3.7. sub_dialog_hash_size(int)
3.8. timer_procs(int)
3.9. timer_interval (int)
3.10. desc_time_order (int)
3.11. matching_mode (int)
3.12. cseq_delay (int)
3.13. fetch_rows(int)
3.14. hash_size (string)
3.15. subs_hash_size (int)
3.16. contacts_hash_size (integer)
3.17. nat_bflag (integer)
3.18. contact_delete_delay (int)
3.19. support_wildcardPSI (int)
3.20. unreg_validity (int)
3.21. user_data_xsd (string)
4. RPC Commands
4.1. ulscscf.status
4.2. ulscscf.showimpu
4.3. ulscscf.snapshot
1. Overview
This module serves as a storage engine for SCSCF contacts, much like
the standard Kamailio module that is usrloc, is a storage engine for
standard SIP contacts.
2. Dependencies
2.1. Kamailio Modules
2.1. Kamailio Modules
The following modules must be loaded before this module:
* TM
* Presence
* IMS dialog
3. Parameters
3.1. db_url (string)
3.2. db_mode (string)
3.3. maxcontact (int)
3.4. maxcontact_3gpp (int)
3.5. maxcontact_behaviour (int)
3.6. max_subscribes(int)
3.7. sub_dialog_hash_size(int)
3.8. timer_procs(int)
3.9. timer_interval (int)
3.10. desc_time_order (int)
3.11. matching_mode (int)
3.12. cseq_delay (int)
3.13. fetch_rows(int)
3.14. hash_size (string)
3.15. subs_hash_size (int)
3.16. contacts_hash_size (integer)
3.17. nat_bflag (integer)
3.18. contact_delete_delay (int)
3.19. support_wildcardPSI (int)
3.20. unreg_validity (int)
3.21. user_data_xsd (string)
3.1. db_url (string)
database URL for storing impu/contacts records
Example 1.1. Set db_urlparameter
modparam("ims_usrloc_scscf", "db_url", "mysql//username:password@localho
st/scscf")
3.2. db_mode (string)
This is the database mode to be used for the SCSCF usrloc data
persistent storage. Currently this module supports the Write-Back
scheme only.
* 0 - This disables database completely. Only memory will be used.
Contacts will not survive restart.
* 1 - Write-Backend scheme. All changes are made to memory and
database synchronization is done in the timer
Default value is 0.
Example 1.2. Set db_mode(int)
...
modparam("ims_usrloc_scscf", "db_mode", 1)
3.3. maxcontact (int)
The parameter can be used to limit the number of contact for each impu
Default value is 0(max)
Example 1.3. Set maxcontactparameter
...
modparam("ims_usrloc_scscf", "maxcontact", 10)
3.4. maxcontact_3gpp (int)
The parameter can be used to limit the number of 3GPP contact for each
impu
Default value is 0.(max)
Example 1.4. Set maxcontact_3gppparameter
...
modparam("ims_usrloc_scscf", "maxcontact_3gpp", 0)
3.5. maxcontact_behaviour (int)
Behaviour of usrloc , after impu reach max contacts limit.
* 0 - Disabled
* 1 - Reject after reaching limit.
* 2 - Overwrite
Default value is 0.
Example 1.5. Set maxcontact_behaviour parameter
...
modparam("ims_usrloc_scscf", "maxcontact_behaviour", 2)
3.6. max_subscribes(int)
Max number of subscribes allowed per watcher for each IMPU
Default value is 0.
Example 1.6. Set subscription_expires_rangeparameter
...
modparam("ims_usrloc_scscf", "max_subscribes", 2)
3.7. sub_dialog_hash_size(int)
Subscriber dialog hash table size
Default value is 10.
Example 1.7. Setsub_dialog_hash_sizeparameter
...
modparam("ims_usrloc_scscf", "sub_dialog_hash_size", 512)
3.8. timer_procs(int)
process number of handling registeration
Default value is 0
Example 1.8. Settimer_procsparameter
...
modparam("ims_usrloc_scscf", "timer_procs", 5)
3.9. timer_interval (int)
Number of seconds between two timer runs. The module uses a timer to
delete expired contacts, synchronize with database and other tasks,
that need to be run periodically
Default value is 90
Example 1.9. Set timer_intervalparameter
...
modparam("ims_usrloc_scscf", "timer_interval", 120)
3.10. desc_time_order (int)
If the user's contacts should be kept timestamp ordered; otherwise the
contact will be ordered based on q value. Non 0 value means true.
Default value is timestamp ordering not enabled
Example 1.10. Set desc_time_orderparameter
...
modparam("ims_usrloc_scscf", "desc_time_order", 1)
3.11. matching_mode (int)
What contact matching algorithm to be used.
* 0 - Contact Only matching
* 1 - Contact and Callid Matching
* 2 - Contact and Path header matching
* 3 - Only contact IP and Port Matching
Default value is 0.
Example 1.11. Set matching_modeparameter
...
modparam("ims_usrloc_scscf", "matching_mode", 0)
3.12. cseq_delay (int)
Delay (in seconds) for accepting as retransmissions register requests
with same Call-ID and Cseq.
Default value is 20.
Example 1.12. Set scscf_nameparameter
...
modparam("ims_usrloc_scscf", "cseq_delay", 20)
3.13. fetch_rows(int)
The number of the rows to be fetched at once from database when loading
the location records.
Default value is 2000.
Example 1.13. Set fetch_rowsparameter
...
modparam("ims_usrloc_scscf", "fetch_rows", 3000)
3.14. hash_size (string)
The number of entries of the hash table used by usrloc
Default value 512
Example 1.14. Set hash_sizeparameter
...
modparam("ims_usrloc_scscf", "hash_size", 512)
3.15. subs_hash_size (int)
The number of entries of the hash table used by usrloc to store the ims
subscribe records
Default value 512
Example 1.15. Set subs_hash_sizeparameter
...
modparam("ims_usrloc_scscf", "subs_hash_size", 512)
3.16. contacts_hash_size (integer)
The number of entries of the hash table used by usrloc to store the
contact records
Default value is 512
Example 1.16. Set contacts_hash_sizeparameter
...
modparam("ims_usrloc_scscf", "contacts_hash_size", 512)
3.17. nat_bflag (integer)
NAT marker to handle natted registration
Default value is 0
Example 1.17. Set nat_bflagparameter
modparam("ims_usrloc_scscf", "nat_bflag", 3)
3.18. contact_delete_delay (int)
If contact is put into delay delete state ,this is how long we delay
before deleting
Default value is 30
Example 1.18. Set contact_delete_delayparameter
modparam("ims_usrloc_scscf", "contact_delete_delay", 32)
3.19. support_wildcardPSI (int)
Wildcard Public-Service-Identity (RFC5002). it will be actived by
setting 1
Default value is 0.(disabled)
Example 1.19. Set support_wildcardPSI parameter
modparam("ims_usrloc_scscf", "support_wildcardPSI", 0)
3.20. unreg_validity (int)
Default validity time in seconds for unregister assignment to SCSCF
Default value is 1800
Example 1.20. Set unreg_validity parameter
modparam("ims_usrloc_scscf", "unreg_validity", 0)
3.21. user_data_xsd (string)
Default value is 1800
Example 1.21. Set unreg_validity parameter
modparam("ims_usrloc_scscf", "user_data_xsd", "/usr/local/etc/kamailio/C
xDataType_Rel6.xsd")
4. RPC Commands
4.1. ulscscf.status
4.2. ulscscf.showimpu
4.3. ulscscf.snapshot
Exported RPC commands.
4.1. ulscscf.status
4.2. ulscscf.showimpu
4.3. ulscscf.snapshot
Chapter 2. Frequently Asked Questions
2.1. Where can I find more about Kamailio?
2.2. Where can I post a question about this module?
2.3. How can I report a bug?
2.1.
Where can I find more about Kamailio?
Take a look at https://www.kamailio.org/.
2.2.
Where can I post a question about this module?
First at all check if your question was already answered on one of our
mailing lists:
* User Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-users
* Developer Mailing List -
https://lists.kamailio.org/cgi-bin/mailman/listinfo/sr-dev
E-mails regarding any stable Kamailio release should be sent to
<sr-users@lists.kamailio.org> and e-mails regarding development
versions should be sent to <sr-dev@lists.kamailio.org>.
2.3.
How can I report a bug?
Please follow the guidelines provided at:
https://github.com/kamailio/kamailio/issues.

@ -0,0 +1,4 @@
docs = ims_usrloc_scscf.xml
docbook_dir = ../../../../doc/docbook
include $(docbook_dir)/Makefile.module

@ -0,0 +1,62 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
%docentities;
]>
<book>
<bookinfo>
<title>IMS Usrloc SCSCF Module</title>
<productname class="trade">&kamailioname;</productname>
<authorgroup>
<author>
<firstname>Jason Penton</firstname>
<surname/>
<affiliation>
<orgname>Smile Communications</orgname>
</affiliation>
<address>
<email>jason.penton@smilecoms.com</email>
</address>
</author>
<editor>
<firstname>Richard</firstname>
<surname>Good</surname>
<affiliation>
<orgname>Smile Communications</orgname>
</affiliation>
<address>
<email>richard.good@smilecoms.com</email>
</address>
</editor>
<editor>
<firstname>Yasin</firstname>
<surname>Caner</surname>
</editor>
</authorgroup>
<copyright>
<year>2012</year>
<holder>Smile Communications</holder>
</copyright>
</bookinfo>
<toc/>
<xi:include href="ims_usrloc_scscf_admin.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
<xi:include href="ims_usrloc_scscf_faq.xml"
xmlns:xi="http://www.w3.org/2001/XInclude"/>
</book>

@ -0,0 +1,340 @@
<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
%docentities;
]>
<!-- Module User's Guide -->
<chapter>
<title>&adminguide;</title>
<section>
<title>Overview</title>
<para>This module serves as a storage engine for SCSCF contacts, much like the standard Kamailio module that is usrloc, is a storage engine for standard SIP contacts.</para>
</section>
<section>
<title>Dependencies</title>
<section>
<title>&kamailio; Modules</title>
<para>The following modules must be loaded before this module:
<itemizedlist>
<listitem>
<para><emphasis>TM</emphasis></para>
</listitem>
<listitem>
<para><emphasis>Presence</emphasis></para>
</listitem>
<listitem>
<para><emphasis>IMS dialog</emphasis></para>
</listitem>
</itemizedlist>
</para>
</section>
</section>
<section>
<title>Parameters</title>
<section id="ims_usrloc_scscf.p.db_url">
<title><varname>db_url</varname> (string)</title>
<para>database <acronym>URL</acronym> for storing impu/contacts records</para>
<example>
<title>Set <varname>db_url</varname>parameter</title>
<programlisting format="linespecific">
modparam("ims_usrloc_scscf", "db_url", "mysql//username:password@localhost/scscf")
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.db_mode">
<title><varname>db_mode</varname> (string)</title>
<para>This is the database mode to be used for the SCSCF usrloc data persistent storage. Currently this module supports the Write-Back scheme only.</para>
<itemizedlist>
<listitem>
<para>
0 - This disables database completely. Only memory will be used.
Contacts will not survive restart.
</para>
</listitem>
<listitem>
<para>
1 - Write-Backend scheme. All changes are made to memory and database synchronization is done in the timer
</para>
</listitem>
</itemizedlist>
<para><emphasis> Default value is 0. </emphasis></para>
<example>
<title>Set <varname>db_mode</varname>(int)</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "db_mode", 1)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.maxcontact">
<title>maxcontact (int)</title>
<para>The parameter can be used to limit the number of contact for each impu</para>
<para><emphasis>Default value is 0(max)</emphasis></para>
<example>
<title>Set <varname>maxcontact</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "maxcontact", 10)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.maxcontact_3gpp">
<title>maxcontact_3gpp (int)</title>
<para>The parameter can be used to limit the number of 3GPP contact for each impu</para>
<para><emphasis> Default value is 0.(max) </emphasis></para>
<example>
<title>Set <varname>maxcontact_3gpp</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "maxcontact_3gpp", 0)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.maxcontact_behaviour">
<title>maxcontact_behaviour (int)</title>
<para>Behaviour of usrloc , after impu reach max contacts limit.</para>
<itemizedlist>
<listitem>
<para>
0 - Disabled
</para>
</listitem>
<listitem>
<para>
1 - Reject after reaching limit.
</para>
</listitem>
<listitem>
<para>
2 - Overwrite
</para>
</listitem>
</itemizedlist>
<para><emphasis> Default value is 0. </emphasis></para>
<example>
<title>Set <varname>maxcontact_behaviour</varname>
parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "maxcontact_behaviour", 2)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.max_subscribes">
<title>max_subscribes(int)</title>
<para>Max number of subscribes allowed per watcher for each IMPU </para>
<para><emphasis> Default value is 0. </emphasis></para>
<example>
<title>Set <varname>subscription_expires_range</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "max_subscribes", 2)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.sub_dialog_hash_size">
<title>sub_dialog_hash_size(int)</title>
<para>Subscriber dialog hash table size</para>
<para><emphasis> Default value is 10. </emphasis></para>
<example>
<title>Set<varname>sub_dialog_hash_size</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "sub_dialog_hash_size", 512)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.timer_procs">
<title>timer_procs(int)</title>
<para>process number of handling registeration </para>
<para><emphasis> Default value is 0 </emphasis></para>
<example>
<title>Set<varname>timer_procs</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "timer_procs", 5)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.timer_interval">
<title>timer_interval (int)</title>
<para>Number of seconds between two timer runs. The module uses a timer to delete expired contacts,
synchronize with database and other tasks, that need to be run periodically</para>
<para><emphasis> Default value is 90 </emphasis></para>
<example>
<title>Set <varname>timer_interval</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "timer_interval", 120)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.desc_time_order">
<title>desc_time_order (int)</title>
<para>If the user's contacts should be kept timestamp ordered; otherwise the contact will be ordered based on q value. Non 0 value means true.</para>
<para><emphasis> Default value is timestamp ordering not enabled </emphasis></para>
<example>
<title>Set <varname>desc_time_order</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "desc_time_order", 1)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.matching_mode">
<title>matching_mode (int)</title>
<para>What contact matching algorithm to be used.</para>
<itemizedlist>
<listitem>
<para>
0 - Contact Only matching
</para>
</listitem>
<listitem>
<para>
1 - Contact and Callid Matching
</para>
</listitem>
<listitem>
<para>
2 - Contact and Path header matching
</para>
</listitem>
<listitem>
<para>
3 - Only contact IP and Port Matching
</para>
</listitem>
</itemizedlist>
<para><emphasis> Default value is 0. </emphasis></para>
<example>
<title>Set <varname>matching_mode</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "matching_mode", 0)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.cseq_delay">
<title>cseq_delay (int)</title>
<para>Delay (in seconds) for accepting as retransmissions register requests with same Call-ID and Cseq.</para>
<para><emphasis> Default value is 20. </emphasis></para>
<example>
<title>Set <varname>scscf_name</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "cseq_delay", 20)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.fetch_rows">
<title>fetch_rows(int)</title>
<para>The number of the rows to be fetched at once from database when loading the location records.</para>
<para><emphasis> Default value is 2000. </emphasis></para>
<example>
<title>Set <varname>fetch_rows</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "fetch_rows", 3000)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.hash_size">
<title>hash_size (string)</title>
<para>The number of entries of the hash table used by usrloc </para>
<para><emphasis> Default value 512</emphasis></para>
<example>
<title>Set <varname>hash_size</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "hash_size", 512)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.subs_hash_size">
<title>subs_hash_size (int)</title>
<para>The number of entries of the hash table used by usrloc to store the ims subscribe records</para>
<para><emphasis> Default value 512</emphasis></para>
<example>
<title>Set <varname>subs_hash_size</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "subs_hash_size", 512)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.contacts_hash_size">
<title>contacts_hash_size (integer)</title>
<para>The number of entries of the hash table used by usrloc to store the contact records</para>
<para><emphasis> Default value is 512</emphasis></para>
<example>
<title>Set <varname>contacts_hash_size</varname>parameter</title>
<programlisting format="linespecific">...
modparam("ims_usrloc_scscf", "contacts_hash_size", 512)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.nat_bflag">
<title>nat_bflag (integer)</title>
<para>NAT marker to handle natted registration</para>
<para><emphasis> Default value is 0 </emphasis></para>
<example>
<title>Set <varname>nat_bflag</varname>parameter</title>
<programlisting format="linespecific">
modparam("ims_usrloc_scscf", "nat_bflag", 3)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.contact_delete_delay">
<title>contact_delete_delay (int)</title>
<para>If contact is put into delay delete state ,this is how long we delay before deleting </para>
<para><emphasis> Default value is 30</emphasis></para>
<example>
<title>Set <varname>contact_delete_delay</varname>parameter</title>
<programlisting format="linespecific">
modparam("ims_usrloc_scscf", "contact_delete_delay", 32)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.support_wildcardPSI">
<title>support_wildcardPSI (int)</title>
<para>Wildcard Public-Service-Identity (RFC5002). it will be actived by setting 1 </para>
<para><emphasis> Default value is 0.(disabled) </emphasis></para>
<example>
<title>Set <varname>support_wildcardPSI</varname> parameter</title>
<programlisting format="linespecific">
modparam("ims_usrloc_scscf", "support_wildcardPSI", 0)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.unreg_validity">
<title>unreg_validity (int)</title>
<para>Default validity time in seconds for unregister assignment to SCSCF </para>
<para><emphasis> Default value is 1800 </emphasis></para>
<example>
<title>Set <varname>unreg_validity</varname> parameter</title>
<programlisting format="linespecific">
modparam("ims_usrloc_scscf", "unreg_validity", 0)
</programlisting>
</example>
</section>
<section id="ims_usrloc_scscf.p.user_data_xsd">
<title>user_data_xsd (string)</title>
<para> </para>
<para><emphasis> Default value is 1800 </emphasis></para>
<example>
<title>Set <varname>unreg_validity</varname> parameter</title>
<programlisting format="linespecific">
modparam("ims_usrloc_scscf", "user_data_xsd", "/usr/local/etc/kamailio/CxDataType_Rel6.xsd")
</programlisting>
</example>
</section>
</section>
<section>
<title>RPC Commands</title>
<para>Exported RPC commands.</para>
<section id="ims_usrloc_scscf.r.status">
<title>ulscscf.status</title>
<para></para>
</section>
<section id="ims_usrloc_scscf.r.showimpu">
<title>ulscscf.showimpu</title>
<para></para>
</section>
<section id="ims_usrloc_scscf.r.snapshot">
<title>ulscscf.snapshot</title>
<para></para>
</section>
</section>
</chapter>

@ -0,0 +1,58 @@
<?xml version="1.0" encoding='ISO-8859-1'?>
<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.4//EN"
"http://www.oasis-open.org/docbook/xml/4.4/docbookx.dtd" [
<!-- Include general documentation entities -->
<!ENTITY % docentities SYSTEM "../../../../doc/docbook/entities.xml">
%docentities;
]>
<!-- Module FAQ -->
<chapter>
<title>&faqguide;</title>
<qandaset defaultlabel="number">
<qandaentry>
<question>
<para>Where can I find more about &kamailio;?</para>
</question>
<answer>
<para>
Take a look at &kamailiohomelink;.
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>Where can I post a question about this module?</para>
</question>
<answer>
<para>
First at all check if your question was already answered on one of
our mailing lists:
</para>
<itemizedlist>
<listitem>
<para>User Mailing List - &kamailiouserslink;</para>
</listitem>
<listitem>
<para>Developer Mailing List - &kamailiodevlink;</para>
</listitem>
</itemizedlist>
<para>
E-mails regarding any stable &kamailio; release should be sent to
&kamailiousersmail; and e-mails regarding development versions
should be sent to &kamailiodevmail;.
</para>
</answer>
</qandaentry>
<qandaentry>
<question>
<para>How can I report a bug?</para>
</question>
<answer>
<para>
Please follow the guidelines provided at:
&kamailiobugslink;.
</para>
</answer>
</qandaentry>
</qandaset>
</chapter>

@ -1,2 +0,0 @@
* "Reliable" Notifications (implement using requests, and failover on error; ignore non-error responses) ?
* Implement timout for non-Linux systems

@ -40,6 +40,7 @@ int k_sd_journal_send_xavp(str *rname)
if (!rxavp || rxavp->val.type != SR_XTYPE_XAVP) {
LM_ERR("not a valid xavp: %.*s?\n", rname->len, rname->s);
return -1;
}
/* first, count xavp nodes */

@ -14,8 +14,6 @@ Daniel-Constantin Mierla
<miconda@gmail.com>
Edited by
Juha Heinanen
<jh@tutpro.com>
@ -510,7 +508,7 @@ modparam("msilo", "expire_time", 36000)
module keeps each request send by itself for a new online user and if
the reply is 2xx then the message is deleted from database.
Default value is “30”.
Default value is “60”.
Example 1.21. Set the “check_time” parameter
...
@ -537,7 +535,7 @@ modparam("msilo", "send_time", 60)
Number of “check_time” cycles when to check if there are expired
messages in database.
Default value is “5”.
Default value is “10”.
Example 1.23. Set the “clean_period” parameter
...

@ -465,7 +465,7 @@ modparam("msilo", "expire_time", 36000)
</para>
<para>
<emphasis>
Default value is <quote>30</quote>.
Default value is <quote>60</quote>.
</emphasis>
</para>
<example>
@ -509,7 +509,7 @@ modparam("msilo", "send_time", 60)
</para>
<para>
<emphasis>
Default value is <quote>5</quote>.
Default value is <quote>10</quote>.
</emphasis>
</para>
<example>

@ -1951,6 +1951,8 @@ static void nh_timer(unsigned int ticks, void *timer_idx)
+ iteration,
natping_processes * natping_interval, options);
if(rval < 0) {
if(buf != NULL)
pkg_free(buf);
LM_ERR("failed to fetch contacts\n");
goto done;
}

@ -278,7 +278,6 @@ str* get_domain(pdt_tree_t *pt, str *sp, int *plen)
*plen = len;
return domain;
}
/**
@ -287,7 +286,7 @@ str* get_domain(pdt_tree_t *pt, str *sp, int *plen)
str* pdt_get_domain(pdt_tree_t *pl, str* sdomain, str *code, int *plen)
{
pdt_tree_t *it;
int len;
int len = 0;
str *domain=NULL;
if(pl==NULL || sdomain==NULL || sdomain->s==NULL || code == NULL
@ -300,13 +299,14 @@ str* pdt_get_domain(pdt_tree_t *pl, str* sdomain, str *code, int *plen)
it = pl;
while(it!=NULL && str_strcmp(&it->sdomain, sdomain)<0)
it = it->next;
if(it==NULL || str_strcmp(&it->sdomain, sdomain)>0)
return NULL;
domain = get_domain(it, code, &len);
if(plen!=NULL)
*plen = len;
*plen = len;
return domain;
}

@ -26,6 +26,7 @@ Daniel-Constantin Mierla
3. Parameters
3.1. smode (int)
3.2. resid (str)
4. Functions
@ -37,8 +38,9 @@ Daniel-Constantin Mierla
List of Examples
1.1. Set smode parameter
1.2. phonenum_match usage
1.3. phonenum_match_cn usage
1.2. Set resid parameter
1.3. phonenum_match usage
1.4. phonenum_match_cn usage
Chapter 1. Admin Guide
@ -53,6 +55,7 @@ Chapter 1. Admin Guide
3. Parameters
3.1. smode (int)
3.2. resid (str)
4. Functions
@ -95,10 +98,11 @@ Chapter 1. Admin Guide
3. Parameters
3.1. smode (int)
3.2. resid (str)
3.1. smode (int)
Phone number search mode.
Phone number search mode (not in use yet).
Default value is “0”.
@ -107,6 +111,23 @@ Chapter 1. Admin Guide
modparam("phonenum", "smode", 0)
...
3.2. resid (str)
Preregister result container id during initialization, enabling the use
of the module in KEMI scripts. In native Kamailio.cfg file,
registration is done when parsing config and finding variables.
Default value is “” (empty).
Example 1.2. Set resid parameter
...
modparam("phonenum", "resid", "src")
...
if(phonenum_match("1-484-555-8888", "src")) {
...
}
...
4. Functions
4.1. phonenum_match(num, pvc)
@ -115,14 +136,14 @@ modparam("phonenum", "smode", 0)
4.1. phonenum_match(num, pvc)
Match num against the libphonenumber and set the attributes inside the
pvc container. The function has to be called before accessing a key
via: $phn(pvc=>key).
pvc result container. The function has to be called before accessing a
key via: $phn(pvc=>key).
The parameters can be static strings or strings with variables.
It can be used from ANY_ROUTE.
Example 1.2. phonenum_match usage
Example 1.3. phonenum_match usage
...
if(phonenum_match("1-484-555-8888", "src")) {
if($phn(src=>valid)==1) {
@ -144,7 +165,7 @@ if(phonenum_match("1-484-555-8888", "src")) {
It can be used from ANY_ROUTE.
Example 1.3. phonenum_match_cn usage
Example 1.4. phonenum_match_cn usage
...
if(phonenum_match_cn("1-484-555-8888", "US", "src")) {
if($phn(src=>valid)==1) {

@ -71,7 +71,7 @@
<section id="phonenum.p.smode">
<title><varname>smode</varname> (int)</title>
<para>
Phone number search mode.
Phone number search mode (not in use yet).
</para>
<para>
<emphasis>
@ -87,7 +87,31 @@ modparam("phonenum", "smode", 0)
</programlisting>
</example>
</section>
<section id="phonenum.p.resid">
<title><varname>resid</varname> (str)</title>
<para>
Preregister result container id during initialization, enabling the use
of the module in KEMI scripts. In native &kamailio;.cfg file, registration
is done when parsing config and finding variables.
</para>
<para>
<emphasis>
Default value is <quote></quote> (empty).
</emphasis>
</para>
<example>
<title>Set <varname>resid</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("phonenum", "resid", "src")
...
if(phonenum_match("1-484-555-8888", "src")) {
...
}
...
</programlisting>
</example>
</section>
</section>
<section>
@ -98,7 +122,7 @@ modparam("phonenum", "smode", 0)
</title>
<para>
Match num against the libphonenumber and set the attributes inside
the pvc container. The function has to be called before accessing
the pvc result container. The function has to be called before accessing
a key via: $phn(pvc=&gt;key).
</para>
<para>

@ -47,6 +47,8 @@ static int w_phonenum_match_cn(struct sip_msg *msg, char *str1, char *str2,
char *str3);
static int phonenum_match(sip_msg_t *msg, str *tomatch, str *pvclass);
static int phonenum_resid_param(modparam_t type, void* val);
/* clang-format off */
static pv_export_t mod_pvs[] = {
{ {"phn", sizeof("phn")-1}, PVT_OTHER, pv_get_phonenum, 0,
@ -64,6 +66,7 @@ static cmd_export_t cmds[]={
static param_export_t params[]={
{"smode", PARAM_INT, &phonenum_smode},
{"resid", PARAM_STR|PARAM_USE_FUNC, &phonenum_resid_param},
{0, 0, 0}
};
@ -102,6 +105,21 @@ static void mod_destroy(void)
phonenum_destroy_pv();
}
/**
*
*/
static int phonenum_resid_param(modparam_t type, void* val)
{
str rname;
rname = *((str*)val);
if(sr_phonenum_add_resid(&rname) < 0) {
LM_ERR("failed to register result container with id: %.*s\n",
rname.len, rname.s);
return -1;
}
return 0;
}
static int phonenum_match(sip_msg_t *msg, str *tomatch, str *pvclass)
{

@ -111,6 +111,13 @@ sr_phonenum_item_t *sr_phonenum_add_item(str *name)
return it;
}
int sr_phonenum_add_resid(str *rname)
{
if(sr_phonenum_add_item(rname)==NULL) {
return -1;
}
return 0;
}
int pv_parse_phonenum_name(pv_spec_p sp, str *in)
{

@ -34,6 +34,7 @@ int phonenum_init_pv(int smode);
void phonenum_destroy_pv(void);
void phonenum_pv_reset(str *pvclass);
int phonenum_update_pv(str *tomatch, str *cncode, str *pvclass);
int sr_phonenum_add_resid(str *rname);
#endif

@ -150,6 +150,7 @@ int add_event(pres_ev_t* event)
if(ev== NULL)
{
free_event_params(parsed_event.params.list, PKG_MEM_TYPE);
parsed_event.params.list = NULL;
ERR_MEM(SHARE_MEM);
}
memset(ev, 0, sizeof(pres_ev_t));

@ -291,6 +291,35 @@ static int ki_record_route(sip_msg_t *msg)
return ki_record_route_params( msg, 0 );
}
/**
* wrapper for record_route_preset(msg, key1, key2)
*/
static int ki_record_route_preset(sip_msg_t *msg, str *key1, str *key2)
{
if (msg->msg_flags & FL_RR_ADDED) {
LM_ERR("Double attempt to record-route\n");
return -1;
}
if (key2 && !enable_double_rr) {
LM_ERR("Attempt to double record-route while 'enable_double_rr' param is disabled\n");
return -1;
}
if ( record_route_preset( msg, key1)<0 )
return -1;
if (!key2)
goto done;
if ( record_route_preset( msg, key2)<0 )
return -1;
done:
msg->msg_flags |= FL_RR_ADDED;
return 1;
}
/**
* config wrapper for record_route(msg, params)
*/
@ -317,7 +346,7 @@ static int w_record_route_preset(struct sip_msg *msg, char *key, char *key2)
str s;
if (msg->msg_flags & FL_RR_ADDED) {
LM_ERR("Duble attempt to record-route\n");
LM_ERR("Double attempt to record-route\n");
return -1;
}
if (key2 && !enable_double_rr) {
@ -747,6 +776,11 @@ static sr_kemi_t sr_kemi_rr_exports[] = {
{ SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ str_init("rr"), str_init("record_route_preset"),
SR_KEMIP_INT, ki_record_route_preset,
{ SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE,
SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE }
},
{ {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } }
};

@ -2922,6 +2922,15 @@ select_rtpp_node_old(str callid, str viabranch, int do_test, enum rtpe_operation
return node;
}
unsigned int node_in_set(struct rtpp_node *node, struct rtpp_set *set) {
struct rtpp_node *current = set->rn_first;
while (current) {
if (current->idx == node->idx) return 1;
current = current->rn_next;
}
return 0;
}
/*
* Main balancing routine. This DO try to keep the same proxy for
* the call if some proxies were disabled or enabled (e.g. kamctl command)
@ -2950,7 +2959,7 @@ select_rtpp_node(str callid, str viabranch, int do_test, struct rtpp_node **quer
node = select_rtpp_node_old(callid, viabranch, do_test, op);
// check node
if (!node) {
if (!node || (node_in_set(node, active_rtpp_set) == 0)) {
// run the selection algorithm
node = select_rtpp_node_new(callid, viabranch, do_test, queried_nodes_ptr, queried_nodes);

@ -98,6 +98,7 @@ static int rtpp_load_db(void)
if (n_rows == 0)
{
LM_WARN("No rtpproxy instances in database\n");
rtpp_dbf.free_result(rtpp_db_handle, res);
return 0;
}

@ -497,14 +497,14 @@ static int sip_trace_store(siptrace_data_t *sto, dest_info_t *dst,
static int sip_trace_store_db(siptrace_data_t *sto)
{
if(trace_to_database_flag == NULL || *trace_to_database_flag == 0)
goto done;
if(db_con == NULL) {
LM_DBG("database connection not initialized\n");
return -1;
}
if(trace_to_database_flag == NULL || *trace_to_database_flag == 0)
goto done;
db_key_t db_keys[NR_KEYS];
db_val_t db_vals[NR_KEYS];

@ -125,7 +125,7 @@ int put_command( struct modem *mdm, char* cmd, int cmd_len, char* answer,
}
}
}
/* repeat until timout */
/* repeat until timeout */
}while (timeoutcounter<timeout);
if (!answer_e)

@ -31,7 +31,7 @@ typedef int(*cds_report)( struct modem* , char* , int );
/* put_command
Sends a command to the modem and waits max timout*0.1 seconds for an answer.
Sends a command to the modem and waits max timeout*0.1 seconds for an answer.
The function returns the length of the answer.
The answer can be Ok, ERROR or expect.
The command may be empty or NULL */

@ -117,7 +117,6 @@ int sd_lookup_owner(sip_msg_t* _msg, str* stable, str* sowner)
db_vals[nr_keys].nul = 0;
db_vals[nr_keys].val.str_val.s = puri->host.s;
db_vals[nr_keys].val.str_val.len = puri->host.len;
nr_keys++;
if (dstrip_s.s!=NULL && dstrip_s.len>0
&& dstrip_s.len<puri->host.len
@ -126,6 +125,7 @@ int sd_lookup_owner(sip_msg_t* _msg, str* stable, str* sowner)
db_vals[nr_keys].val.str_val.s += dstrip_s.len;
db_vals[nr_keys].val.str_val.len -= dstrip_s.len;
}
nr_keys++;
}
/* take sd from r-uri */
if (parse_sip_msg_uri(_msg) < 0)

@ -92,6 +92,10 @@ Chapter 1. Admin Guide
routing block configurations. It adds new features similar to the
textops module (textops eXtentions).
Note: If you add or remove message parts (header, body etc..) it may be
required to execute msg_apply_changes() from this module if there are
other operations done on the SIP message later on.
2. Functions
2.1. msg_apply_changes()

@ -37,6 +37,11 @@
in routing block configurations.
It adds new features similar to the textops module (textops eXtentions).
</para>
<para>
Note: If you add or remove message parts (header, body etc..) it
may be required to execute msg_apply_changes() from this module
if there are other operations done on the SIP message later on.
</para>
</section>
<xi:include href="functions.xml"/>

@ -28,6 +28,7 @@ else
# E.g.: make TLS_HOOKS=1 TLS_EXTRA_LIBS="-lz -lkrb5"
endif
TLS_EXTRA_LIBS= -L. -lfortuna
LIBS+= $(TLS_EXTRA_LIBS)
# dcm: tls.cfg installed via local 'install-cfg' to update paths
@ -53,3 +54,7 @@ install-cfg:
"$(cfg_prefix)/$(cfg_dir)tls.cfg" ; \
fi
libfortuna.a:
$(MAKE) -C ./fortuna OUT="../libfortuna.a"
tls.so: libfortuna.a

@ -65,9 +65,10 @@ Olle E. Johansson
10.31. config (string)
10.32. xavp_cfg (string)
10.33. event_callback (str)
10.34. engine (string)
10.35. engine_config (string)
10.36. engine_algorithms (string)
10.34. rand_engine (str)
10.35. engine (string)
10.36. engine_config (string)
10.37. engine_algorithms (string)
11. Functions
@ -137,8 +138,9 @@ Olle E. Johansson
1.42. Change and reload the TLS configuration at runtime
1.43. Set xavp_cfg parameter
1.44. Set event_callback parameter
1.45. is_peer_verified usage
1.46. Use of event_route[tls:connection-out]
1.45. Set rand_engine parameter
1.46. is_peer_verified usage
1.47. Use of event_route[tls:connection-out]
Chapter 1. Admin Guide
@ -188,9 +190,10 @@ Chapter 1. Admin Guide
10.31. config (string)
10.32. xavp_cfg (string)
10.33. event_callback (str)
10.34. engine (string)
10.35. engine_config (string)
10.36. engine_algorithms (string)
10.34. rand_engine (str)
10.35. engine (string)
10.36. engine_config (string)
10.37. engine_algorithms (string)
11. Functions
@ -603,9 +606,10 @@ Place holder
10.31. config (string)
10.32. xavp_cfg (string)
10.33. event_callback (str)
10.34. engine (string)
10.35. engine_config (string)
10.36. engine_algorithms (string)
10.34. rand_engine (str)
10.35. engine (string)
10.36. engine_config (string)
10.37. engine_algorithms (string)
10.1. tls_method (string)
@ -1415,7 +1419,35 @@ function ksr_tls_event(evname)
end
...
10.34. engine (string)
10.34. rand_engine (str)
Set the ranondom number generator engine for libssl.
Note: the default random number generator (PRNG) engine of libssl
v1.1.x is not designed for multi-process applications and can result in
a crash. Therefore set the PRNG engine to one of the options listed in
this section. If libssl 1.1.x (or newer) is detected at compile time,
then the PRNG engine is set to "cryptorand".
The following options are avaialble:
* krand - use internal kam_rand() function
* fastrand - use internal fastrand (ISAAC) function
* cryptorand - use internal cryptorand (Fortuna) function
* kxlibssl - default libssl rand engine wrapped by a Kamailio mutex
Note: the krand and fastrand engines are not recommended for use on
systems requiring strong security, as they may not generate numbers
with enough randomness and are not cryptographically secure.
The default value is empty (not set) for libssl v1.0.x or older, and
"cryptorand" for libssl v1.1.x or newer.
Example 1.45. Set rand_engine parameter
...
modparam("tls", "rand_engine", "fastrand")
...
10.35. engine (string)
If OpenSSL is compiled with engine support this will allow algorithms
to be offloaded and private keys from HSM to be used. Currently only a
@ -1441,13 +1473,13 @@ modparam("tls", "engine_algorithms", "ALL")
By default OpenSSL engine support is disabled (NONE). This global param
is not supported in the tls config file.
10.35. engine_config (string)
10.36. engine_config (string)
A OpenSSL configuration file to initialize the engine. Typically used
to send PIN to HSMs to unlock private keys. See the HSM howto for an
example. This global param is not supported in the tls config file.
10.36. engine_algorithms (string)
10.37. engine_algorithms (string)
A list of cryptographic methods to be set as default in the engine.
This is a comma-separated list of values from ALL RSA DSA DH EC RAND
@ -1469,7 +1501,7 @@ modparam("tls", "engine_algorithms", "ALL")
It can be used only in a request route.
Example 1.45. is_peer_verified usage
Example 1.46. is_peer_verified usage
if (proto==TLS && !is_peer_verified()) {
sl_send_reply("400", "No certificate or verification failed");
exit;
@ -1546,7 +1578,7 @@ modparam("tls", "engine_algorithms", "ALL")
If drop() is executed in the event route, then the data is no longer
sent over the connection.
Example 1.46. Use of event_route[tls:connection-out]
Example 1.47. Use of event_route[tls:connection-out]
...
event_route[tls:connection-out] {
if($sndto(ip)=="1.2.3.4") {

@ -1241,6 +1241,46 @@ end
</example>
</section>
<section id="tls.p.rand_engine">
<title><varname>rand_engine</varname> (str)</title>
<para>
Set the ranondom number generator engine for libssl.
</para>
<para>
Note: the default random number generator (PRNG) engine of libssl v1.1.x
is not designed for multi-process applications and can result in a crash.
Therefore set the PRNG engine to one of the options listed in this
section. If libssl 1.1.x (or newer) is detected at compile time, then
the PRNG engine is set to "cryptorand".
</para>
<para>
The following options are avaialble:
</para>
<itemizedlist>
<listitem><para>krand - use internal kam_rand() function</para></listitem>
<listitem><para>fastrand - use internal fastrand (ISAAC) function</para></listitem>
<listitem><para>cryptorand - use internal cryptorand (Fortuna) function</para></listitem>
<listitem><para>kxlibssl - default libssl rand engine wrapped by a &kamailio; mutex</para></listitem>
</itemizedlist>
<para>
Note: the krand and fastrand engines are not recommended for use on
systems requiring strong security, as they may not generate numbers
with enough randomness and are not cryptographically secure.
</para>
<para>
The default value is empty (not set) for libssl v1.0.x or older, and
"cryptorand" for libssl v1.1.x or newer.
</para>
<example>
<title>Set <varname>rand_engine</varname> parameter</title>
<programlisting>
...
modparam("tls", "rand_engine", "fastrand")
...
</programlisting>
</example>
</section>
<section id="tls.p.engine">
<title><varname>engine</varname> (string)</title>
<para>

@ -0,0 +1,15 @@
COREPATH=../../../../src
include $(COREPATH)/Makefile.defs
include $(COREPATH)/Makefile.targets
.PHONY: all
all: libfortuna.a
libfortuna.a:
$(CC) -c -fPIC -I. $(CFLAGS) fortuna.c rijndael.c sha256.c random.c
$(AR) rc $(OUT) fortuna.o rijndael.o sha256.o random.o
.PHONY: clean
clean:
rm -f *.a
rm -r *.o

@ -0,0 +1,461 @@
/*
* fortuna.c
* Fortuna-like PRNG.
*
* Copyright (c) 2005 Marko Kreen
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* contrib/pgcrypto/fortuna.c
*/
#include <sys/time.h>
#include <time.h>
#include <string.h>
#include "rijndael.h"
#include "sha256.h"
#include "fortuna.h"
/*
* Why Fortuna-like: There does not seem to be any definitive reference
* on Fortuna in the net. Instead this implementation is based on
* following references:
*
* http://en.wikipedia.org/wiki/Fortuna_(PRNG)
* - Wikipedia article
* http://jlcooke.ca/random/
* - Jean-Luc Cooke Fortuna-based /dev/random driver for Linux.
*/
/*
* There is some confusion about whether and how to carry forward
* the state of the pools. Seems like original Fortuna does not
* do it, resetting hash after each request. I guess expecting
* feeding to happen more often that requesting. This is absolutely
* unsuitable for pgcrypto, as nothing asynchronous happens here.
*
* J.L. Cooke fixed this by feeding previous hash to new re-initialized
* hash context.
*
* Fortuna predecessor Yarrow requires ability to query intermediate
* 'final result' from hash, without affecting it.
*
* This implementation uses the Yarrow method - asking intermediate
* results, but continuing with old state.
*/
/*
* Algorithm parameters
*/
/*
* How many pools.
*
* Original Fortuna uses 32 pools, that means 32'th pool is
* used not earlier than in 13th year. This is a waste in
* pgcrypto, as we have very low-frequancy seeding. Here
* is preferable to have all entropy usable in reasonable time.
*
* With 23 pools, 23th pool is used after 9 days which seems
* more sane.
*
* In our case the minimal cycle time would be bit longer
* than the system-randomness feeding frequency.
*/
#define NUM_POOLS 23
/* in microseconds */
#define RESEED_INTERVAL 100000 /* 0.1 sec */
/* for one big request, reseed after this many bytes */
#define RESEED_BYTES (1024*1024)
/*
* Skip reseed if pool 0 has less than this many
* bytes added since last reseed.
*/
#define POOL0_FILL (256/8)
/*
* Algorithm constants
*/
/* Both cipher key size and hash result size */
#define BLOCK 32
/* cipher block size */
#define CIPH_BLOCK 16
/* for internal wrappers */
#define MD_CTX SHA256_CTX
#define CIPH_CTX rijndael_ctx
struct fortuna_state
{
u_int8_t counter[CIPH_BLOCK];
u_int8_t result[CIPH_BLOCK];
u_int8_t key[BLOCK];
MD_CTX pool[NUM_POOLS];
CIPH_CTX ciph;
unsigned reseed_count;
struct timeval last_reseed_time;
unsigned pool0_bytes;
unsigned rnd_pos;
int tricks_done;
};
typedef struct fortuna_state FState;
/*
* Use our own wrappers here.
* - Need to get intermediate result from digest, without affecting it.
* - Need re-set key on a cipher context.
* - Algorithms are guaranteed to exist.
* - No memory allocations.
*/
static void
ciph_init(CIPH_CTX * ctx, const u_int8_t *key, int klen)
{
rijndael_set_key(ctx, (const u_int32_t *) key, klen, 1);
}
static void
ciph_encrypt(CIPH_CTX * ctx, const u_int8_t *in, u_int8_t *out)
{
rijndael_encrypt(ctx, (const u_int32_t *) in, (u_int32_t *) out);
}
static void
md_init(MD_CTX * ctx)
{
sr_SHA256_Init(ctx);
}
static void
md_update(MD_CTX * ctx, const u_int8_t *data, int len)
{
sr_SHA256_Update(ctx, data, len);
}
static void
md_result(MD_CTX * ctx, u_int8_t *dst)
{
SHA256_CTX tmp;
memcpy(&tmp, ctx, sizeof(*ctx));
sr_SHA256_Final(dst, &tmp);
memset(&tmp, 0, sizeof(tmp));
}
/*
* initialize state
*/
static void
init_state(FState *st)
{
int i;
memset(st, 0, sizeof(*st));
for (i = 0; i < NUM_POOLS; i++)
md_init(&st->pool[i]);
}
/*
* Endianess does not matter.
* It just needs to change without repeating.
*/
static void
inc_counter(FState *st)
{
u_int32_t *val = (u_int32_t *) st->counter;
if (++val[0])
return;
if (++val[1])
return;
if (++val[2])
return;
++val[3];
}
/*
* This is called 'cipher in counter mode'.
*/
static void
encrypt_counter(FState *st, u_int8_t *dst)
{
ciph_encrypt(&st->ciph, st->counter, dst);
inc_counter(st);
}
/*
* The time between reseed must be at least RESEED_INTERVAL
* microseconds.
*/
static int
enough_time_passed(FState *st)
{
int ok;
struct timeval tv;
struct timeval *last = &st->last_reseed_time;
gettimeofday(&tv, NULL);
/* check how much time has passed */
ok = 0;
if (tv.tv_sec > last->tv_sec + 1)
ok = 1;
else if (tv.tv_sec == last->tv_sec + 1)
{
if (1000000 + tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
ok = 1;
}
else if (tv.tv_usec - last->tv_usec >= RESEED_INTERVAL)
ok = 1;
/* reseed will happen, update last_reseed_time */
if (ok)
memcpy(last, &tv, sizeof(tv));
memset(&tv, 0, sizeof(tv));
return ok;
}
/*
* generate new key from all the pools
*/
static void
reseed(FState *st)
{
unsigned k;
unsigned n;
MD_CTX key_md;
u_int8_t buf[BLOCK];
/* set pool as empty */
st->pool0_bytes = 0;
/*
* Both #0 and #1 reseed would use only pool 0. Just skip #0 then.
*/
n = ++st->reseed_count;
/*
* The goal: use k-th pool only 1/(2^k) of the time.
*/
md_init(&key_md);
for (k = 0; k < NUM_POOLS; k++)
{
md_result(&st->pool[k], buf);
md_update(&key_md, buf, BLOCK);
if (n & 1 || !n)
break;
n >>= 1;
}
/* add old key into mix too */
md_update(&key_md, st->key, BLOCK);
/* now we have new key */
md_result(&key_md, st->key);
/* use new key */
ciph_init(&st->ciph, st->key, BLOCK);
memset(&key_md, 0, sizeof(key_md));
memset(buf, 0, BLOCK);
}
/*
* Pick a random pool. This uses key bytes as random source.
*/
static unsigned
get_rand_pool(FState *st)
{
unsigned rnd;
/*
* This slightly prefers lower pools - thats OK.
*/
rnd = st->key[st->rnd_pos] % NUM_POOLS;
st->rnd_pos++;
if (st->rnd_pos >= BLOCK)
st->rnd_pos = 0;
return rnd;
}
/*
* update pools
*/
static void
add_entropy(FState *st, const u_int8_t *data, unsigned len)
{
unsigned pos;
u_int8_t hash[BLOCK];
MD_CTX md;
/* hash given data */
md_init(&md);
md_update(&md, data, len);
md_result(&md, hash);
/*
* Make sure the pool 0 is initialized, then update randomly.
*/
if (st->reseed_count == 0)
pos = 0;
else
pos = get_rand_pool(st);
md_update(&st->pool[pos], hash, BLOCK);
if (pos == 0)
st->pool0_bytes += len;
memset(hash, 0, BLOCK);
memset(&md, 0, sizeof(md));
}
/*
* Just take 2 next blocks as new key
*/
static void
rekey(FState *st)
{
encrypt_counter(st, st->key);
encrypt_counter(st, st->key + CIPH_BLOCK);
ciph_init(&st->ciph, st->key, BLOCK);
}
/*
* Hide public constants. (counter, pools > 0)
*
* This can also be viewed as spreading the startup
* entropy over all of the components.
*/
static void
startup_tricks(FState *st)
{
int i;
u_int8_t buf[BLOCK];
/* Use next block as counter. */
encrypt_counter(st, st->counter);
/* Now shuffle pools, excluding #0 */
for (i = 1; i < NUM_POOLS; i++)
{
encrypt_counter(st, buf);
encrypt_counter(st, buf + CIPH_BLOCK);
md_update(&st->pool[i], buf, BLOCK);
}
memset(buf, 0, BLOCK);
/* Hide the key. */
rekey(st);
/* This can be done only once. */
st->tricks_done = 1;
}
static void
extract_data(FState *st, unsigned count, u_int8_t *dst)
{
unsigned n;
unsigned block_nr = 0;
/* Should we reseed? */
if (st->pool0_bytes >= POOL0_FILL || st->reseed_count == 0)
if (enough_time_passed(st))
reseed(st);
/* Do some randomization on first call */
if (!st->tricks_done)
startup_tricks(st);
while (count > 0)
{
/* produce bytes */
encrypt_counter(st, st->result);
/* copy result */
if (count > CIPH_BLOCK)
n = CIPH_BLOCK;
else
n = count;
memcpy(dst, st->result, n);
dst += n;
count -= n;
/* must not give out too many bytes with one key */
block_nr++;
if (block_nr > (RESEED_BYTES / CIPH_BLOCK))
{
rekey(st);
block_nr = 0;
}
}
/* Set new key for next request. */
rekey(st);
}
/*
* public interface
*/
FState main_state;
int init_done = 0;
void
fortuna_add_entropy(const u_int8_t *data, unsigned len)
{
if (!init_done)
{
init_state(&main_state);
init_done = 1;
}
if (!data || !len)
return;
add_entropy(&main_state, data, len);
}
void
fortuna_get_bytes(unsigned len, u_int8_t *dst)
{
if (!init_done)
{
init_state(&main_state);
init_done = 1;
}
if (!dst || !len)
return;
extract_data(&main_state, len, dst);
}

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

Loading…
Cancel
Save