Imported Upstream version 4.3.1

changes/33/2333/1 upstream/4.3.1
Victor Seva 10 years ago
parent 7e6131e1b4
commit a88ca52b70

@ -1,3 +1,467 @@
===================== 2015-07-20 Version 4.3.1 Released =====================
===================== Changes Since Version 4.3.0 ===========================
commit 949c09b650246b805c7fbe0b70a41c16a56468e7
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Jul 20 14:45:28 2015 +0200
Makefile.defs: version set to 4.3.1
commit b8852389346fbaeef9e46ddffd35e3aca0b7873c
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Mon Jul 20 14:43:18 2015 +0200
pkg/rpm: updated spec files for v4.3.1
commit 5599ae1efa03d4c182a7a78c63f6b300f2b9ef88
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Mon Jul 20 14:28:04 2015 +0200
pkg/kamailio/deb: update version to 4.3.1
commit 474ed6547aa71a7cc5e48444fd876a74a183548a
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Sat Jul 18 14:37:30 2015 +0200
dnssec: link openssl
Fixes: #253
(cherry picked from commit 577ddf62f46d3e06d9ae235fef9cde177020a9d4)
commit 02ba3dd9fbb41fb3f03fa230672c72acedc39f0d
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Jul 17 08:59:29 2015 +0200
permissions: safety check for trusted hash table
- avoid crash if a db reload is issued in db-only mode
- reported Emmanuel Schmidbauer, GH #228
(cherry picked from commit f2958e5861a96e40f0aca05d5d5bd7fa14c2089e)
commit ff31270f9419d275bcf532f666075903b0b26a08
Author: Fred Posner <fred@palner.com>
Date: Thu Jul 16 15:17:52 2015 -0400
Update pipelimit_admin.xml
- added information about algorithms
- corrected rl typos
- corrected example (wrong algorithm)
- added note about algorithms being case sensitive
- added example using pipelimit for specific method (INVITE)
(cherry picked from commit b0f465bc6e402ba77923216affc2020ad25e97c0)
commit 27c0918a9198e6c7d684541ddfabe598d35dbba8
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jul 16 14:18:51 2015 +0200
etc/kamailio-oob.cfg: remove modules_k from mpath
(cherry picked from commit d796409e653031fdfecee554500b06a43b981296)
commit 3551d707fa497554f3da767e9fba8e046f83b417
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jul 14 17:40:05 2015 +0200
pv: catch early setting $rU with empty string
- avoids backing up and restoring last char, which can create
inappropriate access when using static empty string value
(cherry picked from commit adf1bca4a820e9cb5fcc94a1953b0fcdbd8a20da)
commit b896bb31155240011c32ff6444c0f30c269ae6d0
Author: Paul Arnold <paul@barfoo.net>
Date: Wed Jul 15 12:10:13 2015 +1000
Makefile.groups: rename usrloc_dmq to dmq_usrloc
(cherry picked from commit 8dcc663d050ec314e35ed2c4bcaae592f8e39350)
commit 6279f50a2cdbcba34226f959f40258bb768954bc
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jul 14 16:15:43 2015 +0200
Makefile.defs: detect gcc version 5.0+
- reported by Anthony Messina, GH #230
(cherry picked from commit 35e5da141569b8ace7c0a8fd743d02de6c0df525)
commit 6acc988416ebfd03e4471cb11ae25e5c53690945
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jul 14 15:36:19 2015 +0200
pv: documented pv_xavp_print() function
(cherry picked from commit aa5156037e0884e7aa3981421a15327fffd62f99)
commit a3f01fa8abc6abf885bb77263e3ef5b275a7edc6
Author: Fred Posner <fred@palner.com>
Date: Thu Jul 9 12:53:33 2015 -0400
core: update release notes in NEWS
- Earlier versions for 3.1 and earlier remain. Newer versions are linked to the Kamailio website.
(cherry picked from commit 917bd965e230c9c60906e1c2d3c9ed3df7b00e7f)
commit 05ac2a2b88f476b0fd32b1bf314b2357eedfceb0
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jul 7 11:14:31 2015 +0200
core: fix matching network addresses with bitmask non divisible to 8
- reported by Kyle Kurz <kkurz@digium.com> for permissions module
(cherry picked from commit f429e753dfa750a604bfb0acb5068b47d0fbe142)
commit 5d1fe9db6ef3da2d349a1b77bd441eda19ff7aa0
Author: kelchy <kelchy@bitbucket.org>
Date: Mon Jul 6 19:21:41 2015 +0800
prevent jansson from shuffling key order in json
(cherry picked from commit 140d0c6fc89d3c72bbd45627ca627e19e45b4e53)
commit 563cc6e069079a66839ab1a9a0c7e12139cca6d9
Author: Fred Posner <fred@palner.com>
Date: Mon Jul 6 08:53:16 2015 +0200
INSTALL: updated bug tracker URL
- fixed flavour typo
(cherry picked from commit 115e1eb10566ffafe0f37aed92df8413f660ea6c)
commit 48996cc1e879a2abf96306fc69ace2a86b8ef836
Author: Mikko Lehto <mslehto@iki.fi>
Date: Thu Jun 25 20:00:54 2015 +0300
modules/htable: improves error message when loading from database
(cherry picked from commit f39736b276878f0de1e0471311119f12f1878801)
commit 9c2dbc86a63c6bc403798d8ba48dfea764ca2537
Author: Mikko Lehto <mslehto@iki.fi>
Date: Wed Jun 24 23:59:49 2015 +0300
modules/[rls|presence_xml]: fixes warning [-Wtautological-compare]
warning: comparison of unsigned expression < 0 is always false
(cherry picked from commit d5339cf397b83b79cd1594e37df69990374ec467)
commit 785ab99f18627f1173c9e1714551577c901f04ed
Author: Charles Chance <charles.chance@sipcentric.com>
Date: Wed Jul 15 09:48:57 2015 +0100
dmq_usrloc: use new version of serialized structure returned by usrloc (now includes received address)
(cherry picked from commit bc01d8d6c6abfc7912a27df3ac23bffd818758e9)
commit 5304da51e32ba79dbe6bdd60d848c4d4f5afd9bd
Author: Charles Chance <charles.chance@sipcentric.com>
Date: Tue Jul 14 22:59:10 2015 +0100
dmq_usrloc: don't destroy json doc before we're done with it.
(cherry picked from commit 99f7d67b20c011e78c277a44ea8cd4d6a820806f)
commit 6e6f679c7d7894bd0e268581022ed111c33384c5
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Wed Jul 15 16:00:03 2015 +0200
pua_reginfo: use ruid to fix comparation of contact
(ptr == c) is always false. Using ruid instead.
(cherry picked from commit 7d31d78e3ac861cddfcb70c9940242ec7f3f0dbc)
commit 9a6d8d2bffe13b442ed5e880fb0dd2c6572c29e2
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Thu May 28 18:26:08 2015 +0200
pua_reginfo: use ul.get_urecord_by_ruid instead of ul.get_urecord
(cherry picked from commit 63bd356cc3c7aa64d64361283f630f88b8db88af)
commit 2acfc53ae66f3d96523e746f7722c2f98a09c1d1
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Tue Jul 14 17:18:02 2015 +0200
pkg/kamailio/deb: kamailio.init use $NAME as basename "$0" and chown HOMEDIR when created
(manual cherry picked from commit 7cf6368591b630ddf19b32e1218fdbc10490442c)
(manual cherry picked from commit 62c4a48f6f8568613de54eeddccb0814692e41be)
commit 9c6eef916be7926ae2c7f926da670a3e01226232
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jul 14 15:19:55 2015 +0200
avpops: remove unecessary test for deleting avps by name rules
- causes crash, following the change to use cached pv structures
- reported by Alexandr Dubovikov, GH #239
(cherry picked from commit b120b47c39034d4bc384ff733ce62b845f2b4062)
commit f5d11d18f9d483c5fc731ff36f30fbbe1204f9ff
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jul 14 14:54:31 2015 +0200
core: proper cloning of xavp list with no-data type
- function used for cloning xavps stored in location record
- reported by Luca Mularoni
(cherry picked from commit 4efb386ebf47fc89446f57f2faf6f5cddfb7bff7)
commit 8c597a012e68408475f1abf1b65a1970b8ecd298
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jul 14 14:06:07 2015 +0200
Makefile.defs: test if SCTP is set to enable core USE_SCTP
(cherry picked from commit a9d10bbae1ffbd6be0f5a83ffacfa57a03174a2e)
commit 48a43eb98e3d4c905485a062d614ec0f7f5ca854
Author: Carsten Bock <carsten@ng-voice.com>
Date: Mon Jul 13 16:53:02 2015 +0200
core: Add tsilo to Makefile.groups
Conflicts:
Makefile.groups
commit 41a211e6c13dcecaa6752238d63dfae932433ea7
Author: Juha Heinanen <jh@tutpro.com>
Date: Fri Jul 3 11:27:12 2015 +0300
modules/rls: normalize RLS entry URIs
- RLS entry URI is xs:AnyURI, which may be an absolute or relative URI.
In relative URI, URI scheme is missing.
(cherry picked from commit 68bb6b35098f5555ca35ddb21527660e46b7336a)
commit 5e9862c1b669a8d4d359ed73f47a008b1e8d7865
Author: Juha Heinanen <jh@tutpro.com>
Date: Mon Jun 29 17:29:35 2015 +0300
modules/rtpengine: unset "don't fragment" ip header flag
(cherry picked from commit 5de00fa47bd3e9f0a05324463325dcaf891174a5)
commit 66cbab29ef285ea71116f814108106412f41eae5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Jun 24 13:32:12 2015 +0200
uac: refreshed the readme
commit 119a878abf15ae2af524174a5948f9b8b4d87599
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Jun 24 13:31:56 2015 +0200
rtjson: updated the readme content
commit a5bb99b4499b1ffde155cad9b2bc1377caf19009
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 23 23:21:35 2015 +0200
rtjson: more documentation about json routing document format
(cherry picked from commit 5db8bec2fdfba911f7053e615cf156d76af5fa46)
commit 4b19b9223d73d7138a48e7b358a86f2504efa4f0
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 23 16:45:17 2015 +0200
rtjson: safety check for branch index stored interanlly in xavp
(cherry picked from commit 59389b288fd50369226681b309c0895de03d7b77)
commit 32243fd248a5d49b22ee597fe02ca95f58cab8a5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 23 16:44:11 2015 +0200
evapi: don't print the message after relaying to evapi dispatcher
- the dispatcher process can consume it and frees the pointers
(cherry picked from commit 57b75141542cdaa471dab00cfb4f7d8812d41824)
commit f1a39a6580f6af041f3b002961dcd6f45498ad87
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 23 16:09:40 2015 +0200
rtjson: proper access to items in routes array
- more debug messages to show the internal operations
(cherry picked from commit 8025761dc0c75fd50e3ee24be96d420df79659d5)
commit c6b64b214af224e3416cc1d302bea472d847cebf
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 23 14:07:37 2015 +0200
evapi: more documentation for exported functions
(cherry picked from commit 96225847ddfc2f879d63adbc0117748c9cf76f02)
commit bebf30abb057221be646e95b07cdaca88cab63b5
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 23 13:15:29 2015 +0200
uac: fixed typos in log message
(cherry picked from commit 42f0a1ffe551442058f53c9446495d5e62dc5abc)
commit 85f93d29191ee099704c850a8742cf23404a3e9f
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 23 13:12:08 2015 +0200
rtjson: error log level set to notice for importing uac api
- printed at module init, it is not preventing to start the server
(cherry picked from commit 239c54843897ec143c03693e44c994ee9cdde684)
commit dcd1ba0e3a4e37b0a291bdebb69df0edec29aff2
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 23 11:45:22 2015 +0200
evapi: evapi_close() doesn't use any parameter
(cherry picked from commit cccd1a4b20c750246b491ff41090c5749561948d)
commit 2894aff93058d29e2ad336c43478c3fcb5d082b1
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Jun 19 12:06:30 2015 +0200
Makefile: kamailio user home dir set to /var/run/kamailio for install-initd-centos
- affects the useradd command
- it was pointing to lib dir
(cherry picked from commit dc2d3c3f609c81e21928390110952f4070ea9c62)
commit 388433d265cfcf8637c4e549803ee84cc9ef8519
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Jun 19 11:56:56 2015 +0200
sdpops: don't return 0 if no match for sdp_get_line_startswith()
- that causes exit of config execution
- reported by Sebastian Damm
(cherry picked from commit 0870ab88262bb61124899ad98d06a72a6cdc7129)
commit 75b853cf54c2dd7595c094b302af169fcad25fe0
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Fri Jun 19 10:41:08 2015 +0200
domain: allow 'type' field in domain_attrs to be a DB1_BIGINT
- in addition to allowing DB1_INT
- makes it work with MySQL views on 64bit systems
- based on a patch by divereigh, GH#182
(cherry picked from commit e6f3a512c599678fca08daca561bcad4c05add23)
commit 6da6b53ba373af00f4f29b097c28709b9436583b
Author: Mikko Lehto <mslehto@iki.fi>
Date: Thu Jun 18 15:22:56 2015 +0300
Makefile.defs: fixes indentation
(cherry picked from commit 89633c4c85a6a44df3bbe4a80cf5ca595b59c196)
commit 82b3e56c0ea38682d82ac7b5411555e7c8423eab
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Wed Jun 17 16:12:44 2015 +0200
utils: fixed indentation
(cherry picked from commit 8a9d7df57e0ac83bb8fb6f97c71b01ec96184ba0)
commit f4f400c6078ac45133c546ed0e42e434ae06c983
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 16 15:45:07 2015 +0200
dialog: removed unused variable
(cherry picked from commit 6dba3a2d2785cba6b29bcb3d11b318687a12b632)
commit 69fe3fae08a8ebbe4926fb1e96e52547fe1047bb
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Tue Jun 16 15:06:43 2015 +0200
dialog: re-entrant mutex for dialogs hash table slots
- changed from a lock set usage to per slot lock field
(cherry picked from commit 9c3ea838b31039ac067e17d519df67b64b0dada1)
commit 43b70c5c809f666c74bc0b75ce7549d2a7b0518e
Author: Daniel-Constantin Mierla <miconda@gmail.com>
Date: Thu Jun 11 10:49:10 2015 +0200
uac: updated notes about uac_auth()
(cherry picked from commit db829aabf30c5b4fdfee5ebd842959b63a598b26)
commit 65a4adb30436ae16f241aefb3c44fdd36192a3fd
Author: Victor Seva <linuxmaniac@torreviejawireless.org>
Date: Tue Jun 16 11:25:50 2015 +0200
Revert "modules/lcr: added priority_ordering module parameter"
This reverts commit 27d0e6d99ee512788f16ce4f6b6e4127dea420bd.
commit 27d0e6d99ee512788f16ce4f6b6e4127dea420bd
Author: Juha Heinanen <jh@tutpro.com>
Date: Tue Jun 16 11:37:45 2015 +0300
modules/lcr: added priority_ordering module parameter
- allows ordering of matched gateways only by priority and weight
commit 2b34e4def552444fd72b9dc4f4ae286b19a839b7
Author: Hugh Waite <hugh.waite@acision.com>
Date: Thu Jun 11 10:17:32 2015 +0100
dispatcher: Fix typo in error message
(cherry picked from commit 55a7bf18d0663a9503320143958d0d9e2e845b26)
commit b83c7fef0e4d5c3cab1e2d0ad46bab7e9a852118
Author: Hugh Waite <hugh.waite@acision.com>
Date: Fri May 29 14:40:53 2015 +0100
tm: Ensure all contact attributes are initialised to NULL when serial forking
(cherry picked from commit 192cf785eead68980194e63b06e34bf8f5f861f3)
commit 8ca68616a289a342f2ccedb42c7889294cebc4af
Author: Hugh Waite <hugh.waite@acision.com>
Date: Wed May 27 14:36:56 2015 +0100
tm: Load and restore contact attributes when serial forking
- Add xavp_contact parameter for name of xavp holding attributes from usrloc
- t_load_contacts: Load per branch attributes into contact XAVP
- t_next_contacts/t_next_contact_flow: Restore branch attributes
(cherry picked from commit 4033b77bf99b1521df8add14c6abea3c85d225d1)
commit 1396a656ee9653a94bf1d3470fc2054b54fa40e5
Author: Hugh Waite <hugh.waite@acision.com>
Date: Wed May 27 14:33:06 2015 +0100
usrloc: Update documentation concerning xavp_contact parameter
- Note that tm xavp_contact parameter must match
(cherry picked from commit b4488aa7d743b7f14bc0232beaa69f3591aa1b66)
===================== 2015-06-10 Version 4.3.0 Released =====================
===================== Changes Since Version 4.2.0 ===========================

@ -50,7 +50,7 @@ Starting with version 3.0.0, the two SIP server flavours are built from
same source code tree. In version 4.0.0 the two source code trees were
merged even more, so a combined module directory is now used.
Kamailio flavor is the one built by default. SER is, historically speaking, the
Kamailio flavour is the one built by default. SER is, historically speaking, the
first open source SIP server started in 2001. Kamailio forked from SER in
2005 under the initial name OpenSER.
@ -772,7 +772,7 @@ A: In both cases, the reason is probably an error in request routing script
Q: Where to report issues?
A: Use bug tracker at: http://sip-router.org/tracker
A: Use bug tracker at: https://github.com/kamailio/kamailio/issues
Q: Any F.A.Q. that could be helpful to check before reporting an issue?

@ -999,7 +999,7 @@ install_initd_centos install-initd-centos:
> /etc/default/$(NAME)
/usr/sbin/groupadd -r $(NAME)
/usr/sbin/useradd -r -g $(NAME) -s /bin/false -c "Kamailio Daemon" \
-d ${lib_prefix}/${lib_dir} $(NAME)
-d /var/run/$(NAME) $(NAME)
.PHONY: dbschema
dbschema:

@ -96,7 +96,7 @@ INSTALL_FLAVOUR=$(FLAVOUR)
# version number
VERSION = 4
PATCHLEVEL = 3
SUBLEVEL = 0
SUBLEVEL = 1
# memory manager switcher
# 0 - f_malloc (fast malloc)
@ -236,8 +236,10 @@ ifneq (,$(findstring gcc, $(CC_LONGVER)))
-e 's/4\.[2-4]\..*/4.2+/' \
-e 's/4\.[2-4]$$/4.2+/' \
-e 's/4\.[5-9]\..*/4.5+/' \
-e 's/4\.[5-9]$$/4.5+/')
ifeq (,$(strip $(filter-out 3.0 3.4 4.x 4.2+ 4.5+,$(CC_SHORTVER))))
-e 's/4\.[5-9]$$/4.5+/' \
-e 's/5\.[0-9]\..*/5.0+/' \
-e 's/5\.[0-9]$$/5.0+/')
ifeq (,$(strip $(filter-out 3.0 3.4 4.x 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
# dependencies can be generated on-the-fly while compiling *.c
CC_MKDEP_OPTS=-MMD -MP
endif # 3.0 <= $(CC_SHORTVER) <= 4.x
@ -698,6 +700,10 @@ ifeq ($(WITHAS), 1)
C_DEFS+= -DWITH_AS_SUPPORT
endif
ifeq ($(SCTP), 1)
C_DEFS+= -DUSE_SCTP
endif
ifeq ($(mode),)
mode = release
endif
@ -835,8 +841,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS=-g $(CC_OPT) -funroll-loops -Wcast-align $(PROFILE)
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
$(call set_if_empty,CPU,athlon64)
CFLAGS+=-m32 -minline-all-stringops \
-falign-loops \
@ -885,17 +891,14 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.5+ or 4.2+
endif # CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else # CC_NAME, gcc
ifeq ($(CC_NAME), clang)
$(call set_if_empty,CPU,athlon64)
C_DEFS+=-DCC_GCC_LIKE_ASM
CFLAGS+=-g -m32
$(CC_OPT) \
\
-mtune=$(CPU)
LDFLAGS+=-m32
CFLAGS+=-g -m32 $(CC_OPT) -mtune=$(CPU)
LDFLAGS+=-m32
else # CC_NAME, clang
ifeq ($(CC_NAME), icc)
C_DEFS+=-DCC_GCC_LIKE_ASM
@ -922,7 +925,7 @@ ifeq ($(CC_NAME), gcc)
CFLAGS=-g $(CC_OPT) -funroll-loops -Wcast-align $(PROFILE)
#if gcc 4.5+
# don't add '-mtune=$(CPU)' - gcc failure
ifeq ($(CC_SHORTVER), 4.5+)
ifeq ($(CC_SHORTVER),$(filter $(CC_SHORTVER),4.5+ 5.0+))
$(call set_if_empty,CPU,opteron)
CFLAGS+=-m64 -minline-all-stringops \
-falign-loops \
@ -981,7 +984,7 @@ endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.2+
endif # CC_SHORTVER, 4.5+
endif # CC_SHORTVER, 5.0+, 4.5+
else # CC_NAME, gcc
ifeq ($(CC_NAME), clang)
@ -1016,8 +1019,8 @@ ifeq ($(CC_NAME), gcc)
CFLAGS=-g $(CC_OPT) -funroll-loops $(PROFILE) \
#-Wcast-align \
#-Wmissing-prototypes
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
$(call set_if_empty,CPU,ultrasparc)
#use 32bit for now
CFLAGS+=-m64 -mcpu=ultrasparc \
@ -1083,7 +1086,7 @@ endif #CC_SHORTVER, 2.9x
endif #CC_SHORTVER, 3.0
endif #CC_SHORTVER, 3.4
endif #CC_SHORTVER, 4.x
endif #CC_SHORTVER, 4.5+ or 4.2+
endif #CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else #CC_NAME, gcc
ifeq ($(CC_NAME), suncc)
@ -1107,8 +1110,8 @@ ifeq ($(CC_NAME), gcc)
CFLAGS=-g $(CC_OPT) -funroll-loops $(PROFILE) \
#-Wcast-align \
#-Wmissing-prototypes
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
$(call set_if_empty,CPU,v8)
#use 32bit for now
CFLAGS+= -mtune=$(CPU) \
@ -1149,7 +1152,7 @@ endif #CC_SHORTVER, 2.9x
endif #CC_SHORTVER, 3.0
endif #CC_SHORTVER, 3.4
endif #CC_SHORTVER, 4.x
endif #CC_SHORTVER, 4.5+ or 4.2+
endif #CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else #CC_NAME, gcc
ifeq ($(CC_NAME), suncc)
@ -1171,7 +1174,7 @@ ifeq ($(CC_NAME), gcc)
#common stuff
CFLAGS=-marm -march=armv5t $(CC_OPT) -funroll-loops -fsigned-char $(PROFILE)
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
CFLAGS+= -ftree-vectorize -fno-strict-overflow
# not supported on arm: -minline-all-stringops
else
@ -1203,7 +1206,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.5+ or 4.2+
endif # CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1219,8 +1222,8 @@ ifeq ($(CC_NAME), gcc)
#common stuff
CFLAGS=-march=armv6 $(CC_OPT) -funroll-loops -fsigned-char \
$(PROFILE)
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
CFLAGS+= -ftree-vectorize -fno-strict-overflow
else
#if gcc 4.x+
@ -1250,7 +1253,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.5+ or 4.2+
endif # CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1265,8 +1268,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS=$(CC_OPT) -funroll-loops $(PROFILE)
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
CFLAGS+=-march=r3000 -minline-all-stringops \
-ftree-vectorize -fno-strict-overflow
else
@ -1297,7 +1300,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.5+ or 4.2+
endif # CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1312,8 +1315,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS= -mips2 $(CC_OPT) -funroll-loops $(PROFILE)
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
CFLAGS+=-minline-all-stringops -ftree-vectorize \
-fno-strict-overflow
else
@ -1342,7 +1345,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.5+ or 4.2+
endif # CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1357,8 +1360,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS= -mips64 $(CC_OPT) -funroll-loops $(PROFILE)
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
CFLAGS+=-minline-all-stringops -ftree-vectorize \
-fno-strict-overflow
else
@ -1387,7 +1390,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.5+ or 4.2+
endif # CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1402,8 +1405,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS= $(CC_OPT) -funroll-loops $(PROFILE)
#if gcc 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5 or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
CFLAGS+= -fno-strict-overflow
# not supported: -minline-all-stringops
else
@ -1433,7 +1436,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.5+ or 4.2+
endif # CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1448,8 +1451,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS=
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
$(call set_if_empty,CPU,powerpc)
ifeq ($(NOALTIVEC),)
CFLAGS += $(CC_OPT) -funroll-loops -fsigned-char $(PROFILE)
@ -1490,7 +1493,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.5+ or 4.2+
endif # CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else # CC_NAME, gcc
#other compilers
@ -1505,8 +1508,8 @@ ifeq ($(CC_NAME), gcc)
C_DEFS+=-DCC_GCC_LIKE_ASM
#common stuff
CFLAGS= $(CC_OPT) -funroll-loops -fsigned-char $(PROFILE)
#if gcc 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+,$(CC_SHORTVER))))
#if gcc 5.0+, 4.5+ or 4.2+
ifeq (,$(strip $(filter-out 4.2+ 4.5+ 5.0+,$(CC_SHORTVER))))
$(call set_if_empty,CPU,powerpc64)
CFLAGS+=-ftree-vectorize \
-fno-strict-overflow \
@ -1539,7 +1542,7 @@ endif # CC_SHORTVER, 2.9x
endif # CC_SHORTVER, 3.0
endif # CC_SHORTVER, 3.4
endif # CC_SHORTVER, 4.x
endif # CC_SHORTVER, 4.5+ or 4.2+
endif # CC_SHORTVER, 5.0+, 4.5+ or 4.2+
else # CC_NAME, gcc
#other compilers

@ -15,12 +15,12 @@ mod_list_basic=async auth benchmark blst cfg_rpc cfgutils corex counters \
nat_traversal nathelper path pike pv ratelimit rr rtimer \
rtpproxy sanity sdpops siputils sl statistics textops \
textopsx tm tmx topoh xlog rtpengine stun sipt tcpops \
auth_xkeys
auth_xkeys tsilo
# - extra used modules, with no extra dependency
mod_list_extra=avp auth_diameter call_control dmq domainpolicy msrp pdb \
qos sca seas sms sst timer tmrec uac_redirect xhttp \
xhttp_rpc xprint jsonrpc-s nosip usrloc_dmq statsd rtjson
xhttp_rpc xprint jsonrpc-s nosip dmq_usrloc statsd rtjson
# - common modules depending on database
mod_list_db=acc alias_db auth_db avpops cfg_db db_text db_flatstore \

14
NEWS

@ -1,8 +1,20 @@
Release notes for Kamailio/SIP Router (sr)
***********************************************
For news about release 4.0, please check
Starting with release 3.2, release notes have
been posted to the Kamailio website. Release
notes for previous versions are posted below.
For releases after 3.1, please visit:
http://www.kamailio.org/wiki/features/new-in-4.3.x
http://www.kamailio.org/wiki/features/new-in-4.2.x
http://www.kamailio.org/wiki/features/new-in-4.1.x
http://www.kamailio.org/wiki/features/new-in-4.0.x
http://www.kamailio.org/wiki/features/new-in-3.3.x
http://www.kamailio.org/wiki/features/new-in-3.2.x
Earlier verisons are listed below.
===================================================
sip-router 3.1 changes

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

@ -223,9 +223,9 @@ voicemail.srv_port = "5060" desc "VoiceMail Port"
# set paths to location of modules (to sources or installation folders)
#!ifdef WITH_SRCPATH
mpath="modules_k:modules"
mpath="modules"
#!else
mpath="/usr/local/lib/kamailio/modules_k/:/usr/local/lib/kamailio/modules/"
mpath="/usr/local/lib/kamailio/modules/"
#!endif
#!ifdef WITH_MYSQL

@ -377,7 +377,8 @@ char* get_proto_name(unsigned int proto)
int ip_addr_match_net(ip_addr_t *iaddr, ip_addr_t *naddr,
int mask)
{
unsigned char c;
unsigned char ci;
unsigned char cn;
int i;
int mbytes;
int mbits;
@ -420,8 +421,9 @@ int ip_addr_match_net(ip_addr_t *iaddr, ip_addr_t *naddr,
mbits = mask % 8;
if(mbits==0)
return 0;
c = naddr->u.addr[i] & (~((1 << (8 - mbits)) - 1));
if((iaddr->u.addr[i] & c) == c)
ci = iaddr->u.addr[i] & (~((1 << (8 - mbits)) - 1));
cn = naddr->u.addr[i] & (~((1 << (8 - mbits)) - 1));
if(ci == cn)
return 0;
return -1;
}

@ -791,10 +791,6 @@ int ops_delete_avp(struct sip_msg* msg, struct fis_param *ap)
((ap->opd&AVPOPS_VAL_INT)&&((avp->flags&AVP_NAME_STR))==0) ||
((ap->opd&AVPOPS_VAL_STR)&&(avp->flags&AVP_NAME_STR)) ) )
continue;
if((ap->u.sval->pvp.pvn.u.isname.type&AVP_SCRIPT_MASK)!=0
&& ((ap->u.sval->pvp.pvn.u.isname.type&AVP_SCRIPT_MASK)
&avp->flags)==0)
continue;
/* remove avp */
destroy_avp( avp );
n++;

@ -42,9 +42,6 @@
#include "dlg_req_within.h"
#include "dlg_db_handler.h"
#define MAX_LDG_LOCKS 2048
#define MIN_LDG_LOCKS 2
extern int dlg_ka_interval;
/*! global dialog table */
@ -223,7 +220,7 @@ int dlg_clean_run(ticks_t ti)
tm = (unsigned int)time(NULL);
for(i=0; i<d_table->size; i++)
{
lock_set_get(d_table->locks, d_table->entries[i].lock_idx);
dlg_lock(d_table, &d_table->entries[i]);
dlg = d_table->entries[i].first;
while (dlg) {
tdlg = dlg;
@ -243,7 +240,7 @@ int dlg_clean_run(ticks_t ti)
tdlg->dflags |= DLG_FLAG_CHANGED;
}
}
lock_set_release(d_table->locks, d_table->entries[i].lock_idx);
dlg_unlock(d_table, &d_table->entries[i]);
}
return 0;
}
@ -255,7 +252,6 @@ int dlg_clean_run(ticks_t ti)
*/
int init_dlg_table(unsigned int size)
{
unsigned int n;
unsigned int i;
dlg_ka_list_head = (dlg_ka_t **)shm_malloc(sizeof(dlg_ka_t *));
@ -288,30 +284,13 @@ int init_dlg_table(unsigned int size)
d_table->size = size;
d_table->entries = (struct dlg_entry*)(d_table+1);
n = (size<MAX_LDG_LOCKS)?size:MAX_LDG_LOCKS;
for( ; n>=MIN_LDG_LOCKS ; n-- ) {
d_table->locks = lock_set_alloc(n);
if (d_table->locks==0)
continue;
if (lock_set_init(d_table->locks)==0) {
lock_set_dealloc(d_table->locks);
d_table->locks = 0;
continue;
}
d_table->locks_no = n;
break;
}
if (d_table->locks==0) {
LM_ERR("unable to allocted at least %d locks for the hash table\n",
MIN_LDG_LOCKS);
goto error1;
}
for( i=0 ; i<size; i++ ) {
memset( &(d_table->entries[i]), 0, sizeof(struct dlg_entry) );
if(lock_init(&d_table->entries[i].lock)<0) {
LM_ERR("failed to init lock for slot: %d\n", i);
goto error1;
}
d_table->entries[i].next_id = rand() % (3*size);
d_table->entries[i].lock_idx = i % d_table->locks_no;
}
return 0;
@ -411,11 +390,6 @@ void destroy_dlg_table(void)
if (d_table==0)
return;
if (d_table->locks) {
lock_set_destroy(d_table->locks);
lock_set_dealloc(d_table->locks);
}
for( i=0 ; i<d_table->size; i++ ) {
dlg = d_table->entries[i].first;
while (dlg) {
@ -423,7 +397,7 @@ void destroy_dlg_table(void)
dlg = dlg->next;
destroy_dlg(l_dlg);
}
lock_destroy(&d_table->entries[i].lock);
}
shm_free(d_table);

@ -33,6 +33,7 @@
#include "../../locking.h"
#include "../../lib/kmi/mi.h"
#include "../../timer.h"
#include "../../atomic_ops.h"
#include "dlg_timer.h"
#include "dlg_cb.h"
@ -134,7 +135,9 @@ typedef struct dlg_entry
struct dlg_cell *first; /*!< dialog list */
struct dlg_cell *last; /*!< optimisation, end of the dialog list */
unsigned int next_id; /*!< next id */
unsigned int lock_idx; /*!< lock index */
gen_lock_t lock; /* mutex to access items in the slot */
atomic_t locker_pid; /* pid of the process that holds the lock */
int rec_lock_level; /* recursive lock count */
} dlg_entry_t;
@ -143,8 +146,6 @@ typedef struct dlg_table
{
unsigned int size; /*!< size of the dialog table */
struct dlg_entry *entries; /*!< dialog hash table */
unsigned int locks_no; /*!< number of locks */
gen_lock_set_t *locks; /*!< lock table */
} dlg_table_t;
@ -160,12 +161,22 @@ extern dlg_table_t *d_table;
/*!
* \brief Set a dialog lock
* \brief Set a dialog lock (re-entrant)
* \param _table dialog table
* \param _entry locked entry
*/
#define dlg_lock(_table, _entry) \
lock_set_get( (_table)->locks, (_entry)->lock_idx);
do { \
int mypid; \
mypid = my_pid(); \
if (likely(atomic_get( &(_entry)->locker_pid) != mypid)) { \
lock_get( &(_entry)->lock); \
atomic_set( &(_entry)->locker_pid, mypid); \
} else { \
/* locked within the same process that executed us */ \
(_entry)->rec_lock_level++; \
} \
} while(0)
/*!
@ -174,7 +185,15 @@ extern dlg_table_t *d_table;
* \param _entry locked entry
*/
#define dlg_unlock(_table, _entry) \
lock_set_release( (_table)->locks, (_entry)->lock_idx);
do { \
if (likely((_entry)->rec_lock_level == 0)) { \
atomic_set( &(_entry)->locker_pid, 0); \
lock_release( &(_entry)->lock); \
} else { \
/* recursive locked => decrease lock count */ \
(_entry)->rec_lock_level--; \
} \
} while(0)
/*!
* \brief Unlink a dialog from the list without locking

@ -764,7 +764,7 @@ static int ds_warn_fixup(void** param, int param_no)
{
if(!dst_avp_param.s || !grp_avp_param.s || !cnt_avp_param.s || !sock_avp_param.s)
{
LM_ERR("failover functions used, but AVPs paraamters required"
LM_ERR("failover functions used, but required AVP parameters"
" are NULL -- feature disabled\n");
}
return 0;

@ -96,7 +96,7 @@ void usrloc_get_all_ucontact(dmq_node_t* node)
{
int rval, len=0;
void *buf, *cp;
str c;
str c, recv;
str path;
str ruid;
unsigned int aorhash;
@ -145,6 +145,9 @@ void usrloc_get_all_ucontact(dmq_node_t* node)
break;
c.s = (char*)cp + sizeof(c.len);
cp = (char*)cp + sizeof(c.len) + c.len;
memcpy(&(recv.len), cp, sizeof(recv.len));
recv.s = (char*)cp + sizeof(recv.len);
cp = (char*)cp + sizeof(recv.len) + recv.len;
memcpy( &send_sock, cp, sizeof(send_sock));
cp = (char*)cp + sizeof(send_sock);
memcpy( &flags, cp, sizeof(flags));
@ -328,7 +331,6 @@ int usrloc_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t*
LM_ERR("unrecognized field in json object\n");
}
}
srjson_DestroyDoc(&jdoc);
memset( &ci, 0, sizeof(ucontact_info_t));
ci.ruid = ruid;
ci.c = &c;
@ -367,16 +369,19 @@ int usrloc_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t*
default: goto invalid;
}
srjson_DestroyDoc(&jdoc);
resp->reason = dmq_200_rpl;
resp->resp_code = 200;
return 0;
invalid:
srjson_DestroyDoc(&jdoc);
resp->reason = dmq_400_rpl;
resp->resp_code = 400;
return 0;
error:
srjson_DestroyDoc(&jdoc);
resp->reason = dmq_500_rpl;
resp->resp_code = 500;
return 0;

@ -7,7 +7,7 @@
include ../../Makefile.defs
auto_gen=
NAME=dnssec.so
LIBS= -lval-threads -lcrypto -lsres -lpthread
LIBS= -lval-threads -lcrypto -lsres -lpthread -lssl
DEFS+=-DKAMAILIO_MOD_INTERFACE

@ -362,11 +362,16 @@ int reload_tables ( void )
}
if ((VAL_NULL(ROW_VALUES(row) + 2) == 1) ||
(VAL_TYPE(ROW_VALUES(row) + 2) != DB1_INT)) {
((VAL_TYPE(ROW_VALUES(row) + 2) != DB1_INT) &&
(VAL_TYPE(ROW_VALUES(row) + 2) != DB1_BIGINT))) {
LM_ERR("type at row <%u> is null or not int\n", i);
goto err;
}
type = (int)VAL_INT(ROW_VALUES(row) + 2);
if(VAL_TYPE(ROW_VALUES(row) + 2) == DB1_BIGINT) {
type = (int)VAL_BIGINT(ROW_VALUES(row) + 2);
} else {
type = (int)VAL_INT(ROW_VALUES(row) + 2);
}
if ((type != 0) && (type != 2)) {
LM_ERR("unknown type <%d> at row <%u>\n", type, i);
goto err;

@ -131,8 +131,18 @@ modparam("evapi", "netstring_format", 0)
<function moreinfo="none">evapi_relay(evdata)</function>
</title>
<para>
Relay the event data give as parameter to connected applications.
The format on the network is netstring with evdata payload.
Relay the event data given as parameter to connected applications.
</para>
<para>
The format on the network is netstring with evdata payload if
netstring_format parameter is set to 1 or bare evdata if
netstring_format parameter is set to 0.
</para>
<para>
The function is passing the task to evapi dispatcher process, therefore
the SIP worker process is not blocked. Also, it doesn't wait for any
response, therefore the processing of the configuration continues
very fast when executing evapi_relay().
</para>
<para>
This function can be used from ANY_ROUTE.
@ -166,10 +176,17 @@ evapi_relay("{ \"event\": \"test\",\n \"data\": { \"fU\": \"$fU\" }\n}");
<function moreinfo="none">evapi_async_relay(evdata)</function>
</title>
<para>
Relay the event data give as parameter to connected applications.
The format on the network is netstring with evdata payload. Before
Relay the event data given as parameter to connected applications. Before
evaluating the parameter, the request processing is suspended using
tm module.
tm module (using the t_suspend()/t_continue() framework). The routing
of the SIP request can be continued once event_route[evapi:message-received]
is triggered. After evapi_async_relay() returns true, no relaying should
happen in request_route(), it should be followed by exit;.
</para>
<para>
The format on the network is netstring with evdata payload if
netstring_format parameter is set to 1 or bare evdata if
netstring_format parameter is set to 0.
</para>
<para>
This function can be used from REQUEST_ROUTE.

@ -534,8 +534,8 @@ int evapi_relay(str *evdata)
int sbsize;
str *sbuf;
LM_DBG("relaying event data [%.*s]\n",
evdata->len, evdata->s);
LM_DBG("relaying event data [%.*s] (%d)\n",
evdata->len, evdata->s, evdata->len);
sbsize = evdata->len;
sbuf = (str*)shm_malloc(sizeof(str) + ((sbsize+32) * sizeof(char)));
@ -560,12 +560,12 @@ int evapi_relay(str *evdata)
return -1;
}
LM_DBG("sending [%p] [%.*s] (%d)\n", sbuf, sbuf->len, sbuf->s, sbuf->len);
len = write(_evapi_notify_sockets[1], &sbuf, sizeof(str*));
if(len<=0) {
LM_ERR("failed to pass the pointer to evapi dispatcher\n");
return -1;
}
LM_DBG("sent [%p] [%.*s] (%d)\n", sbuf, sbuf->len, sbuf->s, sbuf->len);
return 0;
}

@ -66,6 +66,8 @@ static cmd_export_t cmds[]={
0, ANY_ROUTE},
{"evapi_async_relay", (cmd_function)w_evapi_async_relay, 1, fixup_evapi_relay,
0, REQUEST_ROUTE},
{"evapi_close", (cmd_function)w_evapi_close, 0, NULL,
0, ANY_ROUTE},
{"evapi_close", (cmd_function)w_evapi_close, 1, NULL,
0, ANY_ROUTE},
{0, 0, 0, 0, 0, 0}

@ -197,11 +197,17 @@ int ht_db_load_table(ht_t *ht, str *dbtable, int mode)
do {
for(i=0; i<RES_ROW_N(db_res); i++)
{
if(RES_ROWS(db_res)[i].values[0].type!=DB1_STRING
|| VAL_NULL(&RES_ROWS(db_res)[i].values[0])) {
LM_ERR("key type must be string and its value not null\n");
if(VAL_NULL(&RES_ROWS(db_res)[i].values[0])) {
LM_ERR("key value must not be null\n");
goto error;
}
if(RES_ROWS(db_res)[i].values[0].type!=DB1_STRING) {
LM_ERR("key type must be string (type=%d)\n",
RES_ROWS(db_res)[i].values[0].type);
goto error;
}
kname.s = (char*)(RES_ROWS(db_res)[i].values[0].val.string_val);
if(kname.s==NULL) {
LM_ERR("null key in row %d\n", i);

@ -33,7 +33,7 @@ int jansson_to_val(pv_value_t* val, char** freeme, json_t* v) {
val->flags = 0;
if(json_is_object(v) || json_is_array(v)) {
const char* value = json_dumps(v, JSON_COMPACT);
const char* value = json_dumps(v, JSON_COMPACT|JSON_PRESERVE_ORDER);
*freeme = (char*)value;
val->rs.s = (char*)value;
val->rs.len = strlen(value);

@ -43,9 +43,9 @@
#define TABLE_VERSION 5
struct trusted_list ***hash_table; /* Pointer to current hash table pointer */
struct trusted_list **hash_table_1; /* Pointer to hash table 1 */
struct trusted_list **hash_table_2; /* Pointer to hash table 2 */
struct trusted_list ***hash_table = 0; /* Pointer to current hash table pointer */
struct trusted_list **hash_table_1 = 0; /* Pointer to hash table 1 */
struct trusted_list **hash_table_2 = 0; /* Pointer to hash table 2 */
static db1_con_t* db_handle = 0;
@ -69,16 +69,21 @@ int reload_trusted_table(void)
char *pattern, *tag;
cols[0] = &source_col;
cols[1] = &proto_col;
cols[2] = &from_col;
cols[3] = &tag_col;
if (hash_table == 0) {
LM_ERR("in-memory hash table not initialized\n");
return -1;
}
if (db_handle == 0) {
LM_ERR("no connection to database\n");
return -1;
}
cols[0] = &source_col;
cols[1] = &proto_col;
cols[2] = &from_col;
cols[3] = &tag_col;
if (perm_dbf.use_table(db_handle, &trusted_table) < 0) {
LM_ERR("failed to use trusted table\n");
return -1;

@ -29,9 +29,66 @@
Pipelimit started from ratelimit module, adding support for definition
of pipes limits in database and dynamic names. Complexity of keeping
everything in a module and make it dual mode functional resulted in a
new module which is focused on just traffic shaping policies. For
description of the algorithms see the README of ratelimit.
new module which is focused on just traffic shaping policies.
</para>
<section>
<title>Algorithms</title>
<para>
Algorithms are based from the ratelimit module, which describes the
algorithms in more detail. The algorithms are used by the pipelimit
module to determine if a message should be blocked.
</para>
<para>
<emphasis>Tail Drop Algorithm (TAILDROP)</emphasis>
</para>
<para>
This is a trivial algorithm that imposes some risks when used in
conjunction with long timer intervals. At the start of each interval an
internal counter is reset and incremented for each incoming message.
Once the counter hits the configured limit pl_check returns an error.
</para>
<para>
<emphasis>Random Early Detection Algorithm (RED)</emphasis>
</para>
<para>
The Random Early Detection Algorithm tries to circumvent the
synchronization problem imposed by the tail drop algorithm by measuring
the average load and adapting the drop rate dynamically. When running
with the RED algorithm (enabled by default) Kamailio will return errors
to the Kamailio routing engine every n'th packet trying to evenly
spread the measured load of the last timer interval onto the current
interval. As a negative side effect Kamailio might drop messages
although the limit might not be reached within the interval. Decrease
the timer interval if you encounter this.
</para>
<para>
<emphasis>Network Algorithm (NETWORK)</emphasis>
</para>
<para>
This algorithm relies on information provided by network interfaces.
The total amount of bytes waiting to be consumed on all the network
interfaces is retrieved once every timer_interval seconds. If the
returned amount exceeds the limit specified in the modparam, pl_check
returns an error.
</para>
<para>
<emphasis>Feedback Algorithm (FEEDBACK)</emphasis>
</para>
<para>
Using the PID Controller model (see Wikipedia page), the drop rate is
adjusted dynamically based on the load factor so that the load factor
always drifts towards the specified limit (or setpoint, in PID terms).
</para>
<para>
As reading the CPU load average is relatively expensive (opening
/proc/stat, parsing it, etc), this only happens once every
timer_interval seconds and consequently the FEEDBACK value is only at
these intervals recomputed. This in turn makes it difficult for the
drop rate to adjust quickly. Worst case scenarios are request rates
going up/down instantly by thousands - it takes up to 20 seconds for
the controller to adapt to the new request rate.
</para>
</section>
</section>
<section>
<title>Dependencies</title>
@ -291,7 +348,7 @@ modparam("pipelimit", "reply_reason", "Limiting")
<para>
If algorithm and limit are provided, the function attempts to create a
new pipe of one with that name doesn't exit. If it exists, no changes
to algorithm and limit are done.
to algorithm and limit are done. Algorithm is case sensitive.
</para>
<para>
The pipe name can be provided via a pseudo variabile.
@ -311,7 +368,7 @@ modparam("pipelimit", "reply_reason", "Limiting")
</para></listitem>
<listitem><para>
<emphasis>algorithm</emphasis> - the string or pseudovariable with the
algorithm. The values can be: taildrop, red, network or feedback - see
algorithm. The values can be: TAILDROP, RED, NETWORK, or FEEDBACK - see
readme of ratelimit module for details on each algorithm.
</para></listitem>
<listitem><para>
@ -322,7 +379,7 @@ modparam("pipelimit", "reply_reason", "Limiting")
This function can be used from REQUEST_ROUTE.
</para>
<example>
<title><function>rl_check</function> usage</title>
<title><function>pl_check</function> usage</title>
<programlisting format="linespecific">
...
# perform pipe match for current method
@ -360,12 +417,20 @@ with unexpected retcode=$var(check_result)\n");
...
# perform pipe match for authenticated user
$var(limit) = 20;
if (!pl_check("$au", "traildrop", "$var(limit)")) {
if (!pl_check("$au", "TAILDROP", "$var(limit)")) {
pl_drop();
exit;
}
...
# perform pipe match for INVITE
if (is_method("INVITE")) {
$var(invlimit) = 10;
if (!pl_check("$si", "TAILDROP", "$var(invlimit)")) {
pl_drop();
exit;
}
}
...
</programlisting>
</example>
</section>

@ -382,7 +382,7 @@ static int pxml_add_xcap_server( modparam_t type, void* val)
LM_ERR("while converting string to int\n");
goto error;
}
if(port< 0 || port> 65535)
if(port< 1 || port> 65535)
{
LM_ERR("wrong port number\n");
goto error;

@ -101,10 +101,14 @@ str* build_reginfo_full(urecord_t * record, str uri, ucontact_t* c, int type) {
snprintf(buf, sizeof(buf), "%p", record);
xmlNewProp(registration_node, BAD_CAST "id", BAD_CAST buf);
LM_DBG("Updated Contact %.*s[%.*s]\n", c->c.len, c->c.s,
c->ruid.len, c->ruid.s);
ptr = record->contacts;
while (ptr) {
if (VALID_CONTACT(ptr, cur_time)) {
LM_DBG("Contact %.*s, %p\n", ptr->c.len, ptr->c.s, ptr);
LM_DBG("Contact %.*s[%.*s]\n", ptr->c.len, ptr->c.s,
ptr->ruid.len, ptr->ruid.s);
/* Contact-Node */
contact_node =xmlNewChild(registration_node, NULL, BAD_CAST "contact", NULL) ;
if( contact_node ==NULL) {
@ -115,7 +119,9 @@ str* build_reginfo_full(urecord_t * record, str uri, ucontact_t* c, int type) {
snprintf(buf, sizeof(buf), "%p", ptr);
xmlNewProp(contact_node, BAD_CAST "id", BAD_CAST buf);
/* Check, if this is the modified contact: */
if (ptr == c) {
if ((c->ruid.len == ptr->ruid.len) &&
!memcmp(c->ruid.s, ptr->ruid.s, c->ruid.len))
{
if ((type & UL_CONTACT_INSERT) || (type & UL_CONTACT_UPDATE)) {
reg_active = 1;
xmlNewProp(contact_node, BAD_CAST "state", BAD_CAST "active");
@ -218,9 +224,9 @@ void reginfo_usrloc_cb(ucontact_t* c, int type, void* param) {
str content_type;
udomain_t * domain;
urecord_t * record;
ucontact_t* _c = NULL;
int res;
str uri = {NULL, 0};
str user = {NULL, 0};
char* at = NULL;
char id_buf[512];
@ -245,9 +251,6 @@ void reginfo_usrloc_cb(ucontact_t* c, int type, void* param) {
LM_ERR("Unknown Type %i\n", type);
return;
}
/* make a local copy of the AOR */
user.len = c->aor->len;
user.s = c->aor->s;
/* Get the UDomain for this account */
res = ul.get_udomain(c->domain->s, &domain);
@ -256,10 +259,11 @@ void reginfo_usrloc_cb(ucontact_t* c, int type, void* param) {
return;
}
/* Get the URecord for this AOR */
res = ul.get_urecord(domain, &user, &record);
if (res > 0) {
LM_ERR("' %.*s (%.*s)' Not found in usrloc\n", c->aor->len, c->aor->s, c->domain->len, c->domain->s);
/* Get the URecord for this ruid */
res = ul.get_urecord_by_ruid(domain, ul.get_aorhash(c->aor), &(c->ruid),
&record, &_c);
if (res < 0) {
LM_ERR("'%.*s (%.*s)' Not found in usrloc\n", c->aor->len, c->aor->s, c->domain->len, c->domain->s);
return;
}

@ -372,6 +372,25 @@ sbranch_append();
<programlisting format="linespecific">
...
sbranch_reset();
...
</programlisting>
</example>
</section>
<section id="pv.f.pv_xavp_print">
<title>
<function moreinfo="none">pv_xavp_print()</function>
</title>
<para>
Print all XAVPs to the syslog using INFO log level.
</para>
<para>
Function can be used from ANY_ROUTE.
</para>
<example>
<title><function>pv_xavp_print()</function> usage</title>
<programlisting format="linespecific">
...
pv_xavp_print();
...
</programlisting>
</example>

@ -2080,7 +2080,8 @@ int pv_set_ruri_user(struct sip_msg* msg, pv_param_t *param,
return -1;
}
if((val==NULL) || (val->flags&PV_VAL_NULL))
if((val==NULL) || (val->flags&PV_VAL_NULL)
|| ((val->flags&PV_VAL_STR) && val->rs.len<=0))
{
memset(&act, 0, sizeof(act));
act.type = SET_USER_T;

@ -333,7 +333,7 @@ static int mod_init(void)
port_str.len, port_str.s);
return -1;
}
if(xcap_port< 0 || xcap_port> 65535)
if(xcap_port< 1 || xcap_port> 65535)
{
LM_ERR("wrong xcap server port\n");
return -1;

@ -982,23 +982,32 @@ int send_resource_subs(char* uri, void* param)
str pres_uri, *tmp_str;
struct sip_uri parsed_pres_uri;
int duplicate = 0;
str *normalized_uri;
subs_info_t *s = (subs_info_t *) ((void**)param)[0];
list_entry_t **rls_contact_list = (list_entry_t **) ((void**)param)[1];
pres_uri.s = uri;
pres_uri.len = strlen(uri);
if (parse_uri(pres_uri.s, pres_uri.len, &parsed_pres_uri) < 0)
{
LM_ERR("bad uri: %.*s\n", pres_uri.len, pres_uri.s);
return -1;
normalized_uri = normalize_sip_uri(&pres_uri);
if (normalized_uri->s == NULL || normalized_uri->len == 0) {
LM_ERR("failed to normalize RLS entry URI %.*s\n",
pres_uri.len, pres_uri.s);
return -1;
}
if (parse_uri(normalized_uri->s, normalized_uri->len, &parsed_pres_uri)
< 0) {
LM_ERR("bad uri: %.*s\n", normalized_uri->len, normalized_uri->s);
return -1;
}
if (check_self(&parsed_pres_uri.host, 0, PROTO_NONE) != 1
&& rls_disable_remote_presence != 0)
{
LM_WARN("Unable to subscribe to remote contact %.*s for watcher %.*s\n",
pres_uri.len, pres_uri.s,
normalized_uri->len, normalized_uri->s,
s->watcher_uri->len,
s->watcher_uri->s);
return 1;
@ -1009,8 +1018,8 @@ int send_resource_subs(char* uri, void* param)
if (rls_max_backend_subs > 0 && ++counter > rls_max_backend_subs)
return 1;
s->pres_uri = &pres_uri;
s->remote_target = &pres_uri;
s->pres_uri = normalized_uri;
s->remote_target = normalized_uri;
/* Build list of contacts... checking each contact exists only once */
if ((tmp_str = (str *)pkg_malloc(sizeof(str))) == NULL)
@ -1024,8 +1033,8 @@ int send_resource_subs(char* uri, void* param)
LM_ERR("out of private memory\n");
return -1;
}
memcpy(tmp_str->s, pres_uri.s, pres_uri.len);
tmp_str->len = pres_uri.len;
memcpy(tmp_str->s, normalized_uri->s, normalized_uri->len);
tmp_str->len = normalized_uri->len;
*rls_contact_list = list_insert(tmp_str, *rls_contact_list, &duplicate);
if (duplicate != 0)
{

@ -155,6 +155,8 @@ rtjson_push_routes();
...
rtjson_init_routes("$var(json)");
rtjson_push_routes();
t_on_failure("REROUTE");
t_relay();
...
failure_route[REROUTE] {
rtjson_next_route();
@ -172,6 +174,8 @@ failure_route[REROUTE] {
...
rtjson_init_routes("$var(json)");
rtjson_push_routes();
t_on_branch("OUTGOING");
t_relay();
...
branch_route[OUTGOING] {
rtjson_update_branch();
@ -182,13 +186,40 @@ branch_route[OUTGOING] {
The format of the JSON document containing routing information.
Description of the fields: TBA.
Description of the fields in the JSON routing document:
* version - intended to enforce versioning checks (not enforced yet),
recommended to be set to "1.0".
* routing - can be "serial" or "parallel", corresponding to desired
routing type: serial or parallel forking.
* routes - an array with structures holding the attributes for
destinations. The attributes can be:
+ uri - request URI
+ dst_uri - outbound proxy URI
+ path - Path URI vector
+ socket - local socket
+ headers - a structure with values for headers From and To
specified as display name and URI, plus extra headers to be
appended to SIP request. It requires uac module in order to
update From and To headers. Set by rtjson_update_branch() only
for serial routing.
+ branch_flags - branch flags. Set by rtjson_update_branch()
only for serial routing.
+ fr_timer - value for fr_timer parameter of tm module. Set by
rtjson_update_branch() only for serial routing.
+ fr_inv_timer - value for fr_inv_timer parameter of tm module.
Set by rtjson_update_branch() only for serial routing.
Other fields can appear in the JSON routing document, being ignored by
rtjson functions. They can be processed directly in the configuration
files using json or jansson modules. For example, the document can
include the transaction identification tuple (index,label) that can be
used to resume the execution of a suspended transaction.
Example 1.6. JSON Routing Structure
...
{
"version": "1.0",
"routing": "parallel",
"routing": "serial",
"routes": [
{
"uri": "sip:127.0.0.1:5080",

@ -148,6 +148,8 @@ rtjson_push_routes();
...
rtjson_init_routes("$var(json)");
rtjson_push_routes();
t_on_failure("REROUTE");
t_relay();
...
failure_route[REROUTE] {
rtjson_next_route();
@ -174,6 +176,8 @@ failure_route[REROUTE] {
...
rtjson_init_routes("$var(json)");
rtjson_push_routes();
t_on_branch("OUTGOING");
t_relay();
...
branch_route[OUTGOING] {
rtjson_update_branch();
@ -191,7 +195,85 @@ branch_route[OUTGOING] {
The format of the JSON document containing routing information.
</para>
<para>
Description of the fields: TBA.
Description of the fields in the JSON routing document:
<itemizedlist>
<listitem>
<para>
<emphasis>version</emphasis> - intended to enforce versioning
checks (not enforced yet), recommended to be set to "1.0".
</para>
</listitem>
<listitem>
<para>
<emphasis>routing</emphasis> - can be "serial" or "parallel",
corresponding to desired routing type: serial or parallel forking.
</para>
</listitem>
<listitem>
<para>
<emphasis>routes</emphasis> - an array with structures holding
the attributes for destinations. The attributes can be:
<itemizedlist>
<listitem>
<para>
<emphasis>uri</emphasis> - request URI
</para>
</listitem>
<listitem>
<para>
<emphasis>dst_uri</emphasis> - outbound proxy URI
</para>
</listitem>
<listitem>
<para>
<emphasis>path</emphasis> - Path URI vector
</para>
</listitem>
<listitem>
<para>
<emphasis>socket</emphasis> - local socket
</para>
</listitem>
<listitem>
<para>
<emphasis>headers</emphasis> - a structure with values for headers
From and To specified as display name and URI, plus extra
headers to be appended to SIP request. It requires uac module in
order to update From and To headers.
Set by rtjson_update_branch() only for serial routing.
</para>
</listitem>
<listitem>
<para>
<emphasis>branch_flags</emphasis> - branch flags.
Set by rtjson_update_branch() only for serial routing.
</para>
</listitem>
<listitem>
<para>
<emphasis>fr_timer</emphasis> - value for fr_timer parameter of
tm module.
Set by rtjson_update_branch() only for serial routing.
</para>
</listitem>
<listitem>
<para>
<emphasis>fr_inv_timer</emphasis> - value for fr_inv_timer parameter
of tm module.
Set by rtjson_update_branch() only for serial routing.
</para>
</listitem>
</itemizedlist>
</para>
</listitem>
</itemizedlist>
</para>
<para>
Other fields can appear in the JSON routing document, being ignored
by rtjson functions. They can be processed directly in the configuration
files using json or jansson modules. For example, the document can include
the transaction identification tuple (index,label) that can be used
to resume the execution of a suspended transaction.
</para>
<example>
<title>JSON Routing Structure</title>
@ -199,7 +281,7 @@ branch_route[OUTGOING] {
...
{
"version": "1.0",
"routing": "parallel",
"routing": "serial",
"routes": [
{
"uri": "sip:127.0.0.1:5080",

@ -58,7 +58,7 @@ int rtjson_init(void)
memset(&tmb, 0, sizeof(struct tm_binds));
}
if (load_uac_api(&uacb) < 0) {
LM_ERR("cannot bind to UAC API - some features are diabled\n");
LM_NOTICE("cannot bind to UAC API - some features are diabled\n");
memset(&uacb, 0, sizeof(uac_api_t));
}
return 0;
@ -312,17 +312,19 @@ error:
*/
int rtjson_init_serial(sip_msg_t *msg, srjson_doc_t *jdoc, sr_xavp_t *iavp)
{
srjson_t *tj = NULL;
srjson_t *nj = NULL;
srjson_t *rj = NULL;
str val;
unsigned int bflags = 0;
unsigned int old_bflags = 0;
nj = srjson_GetObjectItem(jdoc, jdoc->root, "routes");
if(nj==NULL || nj->type!=srjson_Array || nj->child==NULL) {
tj = srjson_GetObjectItem(jdoc, jdoc->root, "routes");
if(tj==NULL || tj->type!=srjson_Array || tj->child==NULL) {
LM_ERR("missing or invalid routes field\n");
goto error;
}
nj = tj->child;
clear_branches();
@ -330,6 +332,7 @@ int rtjson_init_serial(sip_msg_t *msg, srjson_doc_t *jdoc, sr_xavp_t *iavp)
if(rj!=NULL && rj->type==srjson_String && rj->valuestring!=NULL) {
val.s = rj->valuestring;
val.len = strlen(val.s);
LM_DBG("rewrite r-uri to: [%.*s]\n", val.len, val.s);
if (rewrite_uri(msg, &val) < 0) {
LM_ERR("unable to rewrite Request-URI\n");
goto error;
@ -349,6 +352,7 @@ int rtjson_init_serial(sip_msg_t *msg, srjson_doc_t *jdoc, sr_xavp_t *iavp)
if(rj!=NULL && rj->type==srjson_String && rj->valuestring!=NULL) {
val.s = rj->valuestring;
val.len = strlen(val.s);
LM_DBG("rewrite dst-uri to: [%.*s]\n", val.len, val.s);
if (set_dst_uri(msg, &val) < 0) {
LM_ERR("unable to set destination uri\n");
goto error;
@ -359,6 +363,7 @@ int rtjson_init_serial(sip_msg_t *msg, srjson_doc_t *jdoc, sr_xavp_t *iavp)
if(rj!=NULL && rj->type==srjson_String && rj->valuestring!=NULL) {
val.s = rj->valuestring;
val.len = strlen(val.s);
LM_DBG("rewrite path to: [%.*s]\n", val.len, val.s);
if (set_path_vector(msg, &val) < 0) {
LM_ERR("unable to set path\n");
goto error;
@ -423,6 +428,7 @@ int rtjson_prepare_branch(sip_msg_t *msg, srjson_doc_t *jdoc, srjson_t *nj)
}
if(xhdr.len>4) {
LM_DBG("appending extra headers: [%.*s]\n", xhdr.len, xhdr.s);
anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0);
if(anchor == 0) {
LM_ERR("can't get anchor\n");
@ -532,14 +538,16 @@ error:
*/
int rtjson_init_parallel(sip_msg_t *msg, srjson_doc_t *jdoc, sr_xavp_t *iavp)
{
srjson_t *tj = NULL;
srjson_t *nj = NULL;
int ret;
nj = srjson_GetObjectItem(jdoc, jdoc->root, "routes");
if(nj==NULL || nj->type!=srjson_Array || nj->child==NULL) {
tj = srjson_GetObjectItem(jdoc, jdoc->root, "routes");
if(tj==NULL || tj->type!=srjson_Array || tj->child==NULL) {
LM_ERR("missing or invalid routes field\n");
goto error;
}
nj = tj->child;
ret = rtjson_init_serial(msg, jdoc, iavp);
if(ret<0)
@ -569,6 +577,7 @@ int rtjson_next_route(sip_msg_t *msg)
sr_xavp_t *javp = NULL;
sr_xavp_t *iavp = NULL;
srjson_doc_t tdoc;
srjson_t *tj = NULL;
srjson_t *nj = NULL;
str val;
str xname;
@ -612,11 +621,12 @@ int rtjson_next_route(sip_msg_t *msg)
goto error;
}
nj = srjson_GetObjectItem(&tdoc, tdoc.root, "routes");
if(nj==NULL || nj->type!=srjson_Array || nj->child==NULL) {
tj = srjson_GetObjectItem(&tdoc, tdoc.root, "routes");
if(tj==NULL || tj->type!=srjson_Array || tj->child==NULL) {
LM_ERR("missing or invalid routes field\n");
goto error;
}
nj = tj->child;
i = 0;
while(nj && i<iavp->val.v.i) {
@ -646,6 +656,7 @@ int rtjson_update_branch(sip_msg_t *msg)
sr_xavp_t *javp = NULL;
sr_xavp_t *iavp = NULL;
srjson_doc_t tdoc;
srjson_t *tj = NULL;
srjson_t *nj = NULL;
str val;
str xname;
@ -666,6 +677,10 @@ int rtjson_update_branch(sip_msg_t *msg)
LM_WARN("no idx for routing\n");
return -1;
}
if(iavp->val.v.i<=0) {
LM_WARN("invalid branch idx for routing\n");
return -1;
}
srjson_InitDoc(&tdoc, NULL);
@ -689,14 +704,16 @@ int rtjson_update_branch(sip_msg_t *msg)
goto error;
}
nj = srjson_GetObjectItem(&tdoc, tdoc.root, "routes");
if(nj==NULL || nj->type!=srjson_Array || nj->child==NULL) {
tj = srjson_GetObjectItem(&tdoc, tdoc.root, "routes");
if(tj==NULL || tj->type!=srjson_Array || tj->child==NULL) {
LM_ERR("missing or invalid routes field\n");
goto error;
}
nj = tj->child;
i = 0;
while(nj && i<iavp->val.v.i) {
/* stop at number of branches - 1 */
while(nj && i<iavp->val.v.i-1) {
nj = nj->next;
i++;
}

@ -1059,6 +1059,9 @@ child_init(int rank)
struct addrinfo hints, *res;
struct rtpp_set *rtpp_list;
struct rtpp_node *pnode;
#ifdef IP_MTU_DISCOVER
int ip_mtu_discover = IP_PMTUDISC_DONT;
#endif
if(rtpp_set_list==NULL )
return 0;
@ -1121,6 +1124,12 @@ child_init(int rank)
return -1;
}
#ifdef IP_MTU_DISCOVER
setsockopt(rtpp_socks[pnode->idx], IPPROTO_IP,
IP_MTU_DISCOVER, &ip_mtu_discover,
sizeof(ip_mtu_discover));
#endif
if (bind_force_send_ip(pnode->idx) == -1) {
LM_ERR("can't bind socket\n");
close(rtpp_socks[pnode->idx]);

@ -1657,7 +1657,7 @@ static int w_sdp_get_line_startswith(sip_msg_t *msg, char *avp, char *s_line)
p = find_sdp_line(line.s + line.len, body.s + body.len, sline.s[0]);
}
return 0;
return -1;
}
/**

@ -67,6 +67,7 @@ Juha Heinanen
4.43. remap_503_500 (boolean)
4.44. failure_exec_mode (boolean)
4.45. dns_reuse_rcv_socket (boolean)
4.46. xavp_contact (string)
5. Functions
@ -189,51 +190,52 @@ Juha Heinanen
1.43. Set remap_503_500 parameter
1.44. Set failure_exec_mode parameter
1.45. Set dns_reuse_rcv_socket parameter
1.46. t_relay usage
1.47. t_relay_to_udp usage
1.48. t_on_failure usage
1.49. t_on_branch_failure usage
1.50. t_on_reply usage
1.51. t_on_branch usage
1.52. t_newtran usage
1.53. t_reply usage
1.54. t_lookup_request usage
1.55. t_retransmit_reply usage
1.56. t_release usage
1.57. t_forward_nonack usage
1.58. t_set_fr usage
1.59. t_reset_fr usage
1.60. t_set_max_lifetime usage
1.61. t_reset_max_lifetime usage
1.62. t_set_retr usage
1.63. t_reset_retr usage
1.64. t_set_auto_inv_100 usage
1.65. t_branch_timeout usage
1.66. t_branch_replied usage
1.67. t_any_timeout usage
1.68. t_any_replied usage
1.69. t_grep_status usage
1.70. t_is_canceled usage
1.71. t_is_expired usage
1.72. t_relay_cancel usage
1.73. t_lookup_cancel usage
1.74. t_drop_replies() usage
1.75. t_save_lumps() usage
1.76. t_load_contacts usage
1.77. t_next_contacts usage
1.78. t_next_contact_flow usage
1.79. t_check_status usage
1.80. t_check_trans usage
1.81. t_set_disable_6xx usage
1.82. t_set_disable_failover usage
1.83. t_set_disable_internal_reply usage
1.84. t_replicate usage
1.85. t_relay_to usage
1.86. t_set_no_e2e_cancel_reason usage
1.87. t_replicate usage
1.88. t_use_uac_headers usage
1.89. t_is_retr_async_reply usage
1.90. event_route[tm:branch-failure] usage
1.46. Set xavp_contact parameter
1.47. t_relay usage
1.48. t_relay_to_udp usage
1.49. t_on_failure usage
1.50. t_on_branch_failure usage
1.51. t_on_reply usage
1.52. t_on_branch usage
1.53. t_newtran usage
1.54. t_reply usage
1.55. t_lookup_request usage
1.56. t_retransmit_reply usage
1.57. t_release usage
1.58. t_forward_nonack usage
1.59. t_set_fr usage
1.60. t_reset_fr usage
1.61. t_set_max_lifetime usage
1.62. t_reset_max_lifetime usage
1.63. t_set_retr usage
1.64. t_reset_retr usage
1.65. t_set_auto_inv_100 usage
1.66. t_branch_timeout usage
1.67. t_branch_replied usage
1.68. t_any_timeout usage
1.69. t_any_replied usage
1.70. t_grep_status usage
1.71. t_is_canceled usage
1.72. t_is_expired usage
1.73. t_relay_cancel usage
1.74. t_lookup_cancel usage
1.75. t_drop_replies() usage
1.76. t_save_lumps() usage
1.77. t_load_contacts usage
1.78. t_next_contacts usage
1.79. t_next_contact_flow usage
1.80. t_check_status usage
1.81. t_check_trans usage
1.82. t_set_disable_6xx usage
1.83. t_set_disable_failover usage
1.84. t_set_disable_internal_reply usage
1.85. t_replicate usage
1.86. t_relay_to usage
1.87. t_set_no_e2e_cancel_reason usage
1.88. t_replicate usage
1.89. t_use_uac_headers usage
1.90. t_is_retr_async_reply usage
1.91. event_route[tm:branch-failure] usage
Chapter 1. Admin Guide
@ -289,6 +291,7 @@ Chapter 1. Admin Guide
4.43. remap_503_500 (boolean)
4.44. failure_exec_mode (boolean)
4.45. dns_reuse_rcv_socket (boolean)
4.46. xavp_contact (string)
5. Functions
@ -655,6 +658,7 @@ failure_route["serial"]
4.43. remap_503_500 (boolean)
4.44. failure_exec_mode (boolean)
4.45. dns_reuse_rcv_socket (boolean)
4.46. xavp_contact (string)
4.1. fr_timer (integer)
@ -1564,6 +1568,18 @@ modparam("tm", "failure_exec_mode", 1)
modparam("tm", "dns_reuse_rcv_socket", 1)
...
4.46. xavp_contact (string)
The name of XAVP storing the attributes per contact. This must be the
same as the usrloc parameter xavp_contacts.
Default value is "NULL".
Example 1.46. Set xavp_contact parameter
...
modparam("tm|usrloc", "xavp_contact", "ulattrs")
...
5. Functions
5.1. t_relay([host, port])
@ -1618,7 +1634,7 @@ modparam("tm", "dns_reuse_rcv_socket", 1)
5.50. t_use_uac_headers()
5.51. t_is_retr_async_reply()
5.1. t_relay([host, port])
5.1. t_relay([host, port])
Relay a message statefully either to the destination indicated in the
current URI (if called without any parameters) or to the specified host
@ -1637,7 +1653,7 @@ modparam("tm", "dns_reuse_rcv_socket", 1)
Returns a negative value on failure -- you may still want to send a
negative reply upstream statelessly not to leave upstream UAC in lurch.
Example 1.46. t_relay usage
Example 1.47. t_relay usage
...
if (!t_relay())
{
@ -1646,7 +1662,7 @@ if (!t_relay())
};
...
5.2. t_relay_to_udp([ip, port])
5.2. t_relay_to_udp([ip, port])
Relay a message statefully using a fixed protocol either to the
specified fixed destination or to a destination derived from the
@ -1664,7 +1680,7 @@ if (!t_relay())
derived from the message uri (using sip sepcific DNS lookups), but with
the protocol corresponding to the function name.
Example 1.47. t_relay_to_udp usage
Example 1.48. t_relay_to_udp usage
...
if (src_ip==10.0.0.0/8)
t_relay_to_udp("1.2.3.4", "5060"); # sent to 1.2.3.4:5060 over udp
@ -1672,19 +1688,19 @@ else
t_relay_to_tcp(); # relay to msg. uri, but over tcp
...
5.3. t_relay_to_tcp([ip, port])
5.3. t_relay_to_tcp([ip, port])
See function t_relay_to_udp([ip, port]).
5.4. t_relay_to_tls([ip, port])
5.4. t_relay_to_tls([ip, port])
See function t_relay_to_udp([ip, port]).
5.5. t_relay_to_sctp([ip, port])
5.5. t_relay_to_sctp([ip, port])
See function t_relay_to_udp([ip, port]).
5.6. t_on_failure(failure_route)
5.6. t_on_failure(failure_route)
Sets failure routing block, to which control is passed after a
transaction completed with a negative result but before sending a final
@ -1704,7 +1720,7 @@ else
Meaning of the parameters is as follows:
* failure_route - Failure route block to be called.
Example 1.48. t_on_failure usage
Example 1.49. t_on_failure usage
...
route {
t_on_failure("1");
@ -1721,7 +1737,7 @@ failure_route[1] {
See test/onr.cfg for a more complex example of combination of serial
with parallel forking.
5.7. t_on_branch_failure(branch_failure_route)
5.7. t_on_branch_failure(branch_failure_route)
Sets the branch_failure routing block, to which control is passed on
each negative response to a transaction. This route is run before
@ -1740,7 +1756,7 @@ failure_route[1] {
* branch_failure_route - Name of the branch_failure route block to be
called (it is prefixed internally with 'tm:branch-failure:').
Example 1.49. t_on_branch_failure usage
Example 1.50. t_on_branch_failure usage
...
route {
t_on_branch_failure("myroute");
@ -1754,7 +1770,7 @@ event_route[tm:branch-failure:myroute] {
}
...
5.8. t_on_reply(onreply_route)
5.8. t_on_reply(onreply_route)
Sets the reply routing block, to which control is passed when a reply
for the current transaction is received. Note that the set of commands
@ -1763,7 +1779,7 @@ event_route[tm:branch-failure:myroute] {
Meaning of the parameters is as follows:
* onreply_route - Onreply route block to be called.
Example 1.50. t_on_reply usage
Example 1.51. t_on_reply usage
...
loadmodule "/usr/local/lib/ser/modules/nathelper.so"
...
@ -1784,7 +1800,7 @@ es');
}
}
5.9. t_on_branch(branch_route)
5.9. t_on_branch(branch_route)
Sets the branch routing block, to which control is passed after forking
(when a new branch is created). For now branch routes are intended only
@ -1795,7 +1811,7 @@ es');
Meaning of the parameters is as follows:
* branch_route - branch route block to be called.
Example 1.51. t_on_branch usage
Example 1.52. t_on_branch usage
...
route {
t_on_branch("1");
@ -1808,13 +1824,13 @@ branch_route[1] {
}
}
5.10. t_newtran()
5.10. t_newtran()
Creates a new transaction, returns a negative value on error. This is
the only way a script can add a new transaction in an atomic way.
Typically, it is used to deploy a UAS.
Example 1.52. t_newtran usage
Example 1.53. t_newtran usage
...
if (t_newtran()) {
log("UAS logic");
@ -1824,7 +1840,7 @@ if (t_newtran()) {
See test/uas.cfg for more examples.
5.11. t_reply(code, reason_phrase)
5.11. t_reply(code, reason_phrase)
Sends a stateful reply after a transaction has been established. See
t_newtran for usage.
@ -1844,12 +1860,12 @@ if (t_newtran()) {
* code - Reply code number.
* reason_phrase - Reason string.
Example 1.53. t_reply usage
Example 1.54. t_reply usage
...
t_reply("404", "Not found");
...
5.12. t_lookup_request()
5.12. t_lookup_request()
Checks if a transaction exists. Returns a positive value if so,
negative otherwise. Most likely you will not want to use it, as a
@ -1857,33 +1873,33 @@ t_reply("404", "Not found");
none was found. However this is safely (atomically) done using
t_newtran.
Example 1.54. t_lookup_request usage
Example 1.55. t_lookup_request usage
...
if (t_lookup_request()) {
...
};
...
5.13. t_retransmit_reply()
5.13. t_retransmit_reply()
Retransmits a reply sent previously by UAS transaction.
Example 1.55. t_retransmit_reply usage
Example 1.56. t_retransmit_reply usage
...
t_retransmit_reply();
...
5.14. t_release()
5.14. t_release()
Remove transaction from memory (it will be first put on a wait timer to
absorb delayed messages).
Example 1.56. t_release usage
Example 1.57. t_release usage
...
t_release();
...
5.15. t_forward_nonack([ip, port])
5.15. t_forward_nonack([ip, port])
Mainly for internal usage -- forward a non-ACK request statefully.
Variants of this functions can enforce a specific transport protocol.
@ -1892,28 +1908,28 @@ t_release();
* ip - IP address where the message should be sent.
* port - Port number.
Example 1.57. t_forward_nonack usage
Example 1.58. t_forward_nonack usage
...
t_forward_nonack("1.2.3.4", "5060");
...
5.16. t_forward_nonack_udp(ip, port)
5.16. t_forward_nonack_udp(ip, port)
See function t_forward_nonack([ip, port]).
5.17. t_forward_nonack_tcp(ip, port)
5.17. t_forward_nonack_tcp(ip, port)
See function t_forward_nonack([ip, port]).
5.18. t_forward_nonack_tls(ip, port)
5.18. t_forward_nonack_tls(ip, port)
See function t_forward_nonack([ip, port]).
5.19. t_forward_nonack_sctp(ip, port)
5.19. t_forward_nonack_sctp(ip, port)
See function t_forward_nonack([ip, port]).
5.20. t_set_fr(fr_inv_timeout [, fr_timeout])
5.20. t_set_fr(fr_inv_timeout [, fr_timeout])
Sets the fr_inv_timeout and optionally fr_timeout for the current
transaction or for transactions created during the same script
@ -1931,7 +1947,7 @@ t_forward_nonack("1.2.3.4", "5060");
See also: fr_timer, fr_inv_timer, t_reset_fr().
Example 1.58. t_set_fr usage
Example 1.59. t_set_fr usage
...
route {
t_set_fr(10000); # set only fr invite timeout to 10s
@ -1947,7 +1963,7 @@ branch_route[1] {
}
}
5.21. t_reset_fr()
5.21. t_reset_fr()
Resets the fr_inv_timer and fr_timer for the current transaction to the
default values (set using the tm module parameters fr_inv_timer and
@ -1958,7 +1974,7 @@ branch_route[1] {
See also: fr_timer, fr_inv_timer, t_set_fr.
Example 1.59. t_reset_fr usage
Example 1.60. t_reset_fr usage
...
route {
...
@ -1966,7 +1982,7 @@ route {
...
}
5.22. t_set_max_lifetime(inv_lifetime, noninv_lifetime)
5.22. t_set_max_lifetime(inv_lifetime, noninv_lifetime)
Sets the maximum lifetime for the current INVITE or non-INVITE
transaction, or for transactions created during the same script
@ -1984,7 +2000,7 @@ route {
See also: max_inv_lifetime, max_noninv_lifetime, t_reset_max_lifetime.
Example 1.60. t_set_max_lifetime usage
Example 1.61. t_set_max_lifetime usage
...
route {
if (src_ip=1.2.3.4)
@ -1995,7 +2011,7 @@ route {
# INVITE and to 15s if not
}
5.23. t_reset_max_lifetime()
5.23. t_reset_max_lifetime()
Resets the the maximum lifetime for the current INVITE or non-INVITE
transaction to the default value (set using the tm module parameter
@ -2006,7 +2022,7 @@ route {
See also: max_inv_lifetime, max_noninv_lifetime, t_set_max_lifetime.
Example 1.61. t_reset_max_lifetime usage
Example 1.62. t_reset_max_lifetime usage
...
route {
...
@ -2014,7 +2030,7 @@ route {
...
}
5.24. t_set_retr(retr_t1_interval, retr_t2_interval)
5.24. t_set_retr(retr_t1_interval, retr_t2_interval)
Sets the retr_t1_interval and retr_t2_interval for the current
transaction or for transactions created during the same script
@ -2044,7 +2060,7 @@ route {
See also: retr_timer1, retr_timer2, t_reset_retr().
Example 1.62. t_set_retr usage
Example 1.63. t_set_retr usage
...
route {
t_set_retr(250, 0); # set only T1 to 250 ms
@ -2060,7 +2076,7 @@ branch_route[1] {
}
}
5.25. t_reset_retr()
5.25. t_reset_retr()
Resets the retr_timer1 and retr_timer2 for the current transaction to
the default values (set using the tm module parameters retr_timer1 and
@ -2071,7 +2087,7 @@ branch_route[1] {
See also: retr_timer1, retr_timer2, t_set_retr.
Example 1.63. t_reset_retr usage
Example 1.64. t_reset_retr usage
...
route {
...
@ -2079,7 +2095,7 @@ route {
...
}
5.26. t_set_auto_inv_100(0|1)
5.26. t_set_auto_inv_100(0|1)
Switch automatically sending 100 replies to INVITEs on/off on a per
transaction basis. It overrides the auto_inv_100 value for the current
@ -2087,7 +2103,7 @@ route {
See also: auto_inv_100.
Example 1.64. t_set_auto_inv_100 usage
Example 1.65. t_set_auto_inv_100 usage
...
route {
...
@ -2096,13 +2112,13 @@ route {
...
}
5.27. t_branch_timeout()
5.27. t_branch_timeout()
Returns true if the failure route is executed for a branch that did
timeout. It can be used from failure_route and branch-failure event
route.
Example 1.65. t_branch_timeout usage
Example 1.66. t_branch_timeout usage
...
failure_route[0]{
if (t_branch_timeout()){
@ -2111,14 +2127,14 @@ failure_route[0]{
}
}
5.28. t_branch_replied()
5.28. t_branch_replied()
Returns true if the failure route is executed for a branch that did
receive at least one reply in the past (the "current" reply is not
taken into account). It can be used from failure_route and
branch-failure event route.
Example 1.66. t_branch_replied usage
Example 1.67. t_branch_replied usage
...
failure_route[0]{
if (t_branch_timeout()){
@ -2130,12 +2146,12 @@ failure_route[0]{
}
}
5.29. t_any_timeout()
5.29. t_any_timeout()
Returns true if at least one of the current transactions branches did
timeout.
Example 1.67. t_any_timeout usage
Example 1.68. t_any_timeout usage
...
failure_route[0]{
if (!t_branch_timeout()){
@ -2146,13 +2162,13 @@ failure_route[0]{
}
}
5.30. t_any_replied()
5.30. t_any_replied()
Returns true if at least one of the current transactions branches did
receive some reply in the past. If called from a failure or onreply
route, the "current" reply is not taken into account.
Example 1.68. t_any_replied usage
Example 1.69. t_any_replied usage
...
onreply_route[0]{
if (!t_any_replied()){
@ -2161,12 +2177,12 @@ onreply_route[0]{
}
}
5.31. t_grep_status("code")
5.31. t_grep_status("code")
Returns true if "code" is the final reply received (or locally
generated) in at least one of the current transactions branches.
Example 1.69. t_grep_status usage
Example 1.70. t_grep_status usage
...
onreply_route[0]{
if (t_grep_status("486")){
@ -2175,11 +2191,11 @@ onreply_route[0]{
}
}
5.32. t_is_canceled()
5.32. t_is_canceled()
Returns true if the current transaction was canceled.
Example 1.70. t_is_canceled usage
Example 1.71. t_is_canceled usage
...
failure_route[0]{
if (t_is_canceled()){
@ -2188,12 +2204,12 @@ failure_route[0]{
}
}
5.33. t_is_expired()
5.33. t_is_expired()
Returns true if the current transaction has already been expired, i.e.
the max_inv_lifetime/max_noninv_lifetime interval has already elapsed.
Example 1.71. t_is_expired usage
Example 1.72. t_is_expired usage
...
failure_route[0]{
if (t_is_expired()){
@ -2202,7 +2218,7 @@ failure_route[0]{
}
}
5.34. t_relay_cancel()
5.34. t_relay_cancel()
Forwards the CANCEL if the corresponding INVITE transaction exists. The
function is supposed to be used at the very beginning of the script,
@ -2214,7 +2230,7 @@ failure_route[0]{
CANCELs were successfully sent to the pending branches, true if the
INVITE was not found, and false in case of any error.
Example 1.72. t_relay_cancel usage
Example 1.73. t_relay_cancel usage
if (method == CANCEL) {
if (!t_relay_cancel()) { # implicit drop if relaying was successful,
# nothing to do
@ -2227,7 +2243,7 @@ if (method == CANCEL) {
# do the same as for INVITEs
}
5.35. t_lookup_cancel([1])
5.35. t_lookup_cancel([1])
Returns true if the corresponding INVITE transaction exists for a
CANCEL request. The function can be called at the beginning of the
@ -2241,7 +2257,7 @@ if (method == CANCEL) {
overwritten with the flags of the INVITE. isflagset() can be used to
check the flags of the previously forwarded INVITE in this case.
Example 1.73. t_lookup_cancel usage
Example 1.74. t_lookup_cancel usage
if (method == CANCEL) {
if (t_lookup_cancel()) {
log("INVITE transaction exists");
@ -2259,7 +2275,7 @@ if (method == CANCEL) {
# do the same as for INVITEs
}
5.36. t_drop_replies([mode])
5.36. t_drop_replies([mode])
Drops all the previously received replies in failure_route block to
make sure that none of them is picked up again.
@ -2271,7 +2287,7 @@ if (method == CANCEL) {
Dropping replies works only if a new branch is added to the
transaction, or it is explicitly replied in the script!
Example 1.74. t_drop_replies() usage
Example 1.75. t_drop_replies() usage
...
failure_route[0]{
if (t_check_status("5[0-9][0-9]")){
@ -2287,7 +2303,7 @@ failure_route[0]{
}
}
5.37. t_save_lumps()
5.37. t_save_lumps()
Forces the modifications of the processed SIP message to be saved in
shared memory before t_relay() is called. The new branches which are
@ -2302,7 +2318,7 @@ failure_route[0]{
The transaction must be created by t_newtran() before calling
t_save_lumps().
Example 1.75. t_save_lumps() usage
Example 1.76. t_save_lumps() usage
route {
...
t_newtran();
@ -2327,7 +2343,7 @@ failure_route[1] {
t_relay();
}
5.38. t_load_contacts()
5.38. t_load_contacts()
This is the first of the three functions that can be used to implement
serial/parallel forking based on q and +sip.instance values of
@ -2361,7 +2377,7 @@ failure_route[1] {
This function can be used from REQUEST_ROUTE and FAILURE_ROUTE.
Example 1.76. t_load_contacts usage
Example 1.77. t_load_contacts usage
...
if (!t_load_contacts()) {
sl_send_reply("500", "Server Internal Error - Cannot load contacts");
@ -2369,7 +2385,7 @@ if (!t_load_contacts()) {
};
...
5.39. t_next_contacts()
5.39. t_next_contacts()
Function t_next_contacts() is the second of the three functions that
can be used to implement serial/parallel forking based on the q value
@ -2402,7 +2418,7 @@ if (!t_load_contacts()) {
contact_flows_avp are not anymore set. Based on that test, you can then
use t_set_fr() function to set timers according to your needs.
Example 1.77. t_next_contacts usage
Example 1.78. t_next_contacts usage
...
# First call after t_load_contacts() when transaction does not exist yet
# and contacts should be available
@ -2421,7 +2437,7 @@ if (!t_next_contacts()) {
};
...
5.40. t_next_contact_flow()
5.40. t_next_contact_flow()
Function t_next_contact_flow() is the last of the three functions that
can be used to implement serial/parallel forking based on the q value
@ -2439,7 +2455,7 @@ if (!t_next_contacts()) {
thus there was nothing to do, and returns -1 in case of an error (see
syslog). This function can be used from a BRANCH_FAILURE event route.
Example 1.78. t_next_contact_flow usage
Example 1.79. t_next_contact_flow usage
...
event_route[tm:branch-failure:outbound]
{
@ -2451,7 +2467,7 @@ event_route[tm:branch-failure:outbound]
}
...
5.41. t_check_status(re)
5.41. t_check_status(re)
Returns true if the regular expresion "re" match the reply code of the
response message as follows:
@ -2462,14 +2478,14 @@ event_route[tm:branch-failure:outbound]
This function can be used from ANY_ROUTE .
Example 1.79. t_check_status usage
Example 1.80. t_check_status usage
...
if (t_check_status("(487)|(408)")) {
log("487 or 408 negative reply\n");
}
...
5.42. t_check_trans()
5.42. t_check_trans()
t_check_trans() can be used to quickly check if a message belongs or is
related to a transaction. It behaves differently for different types of
@ -2516,12 +2532,12 @@ Note
See also: t_lookup_request(), t_lookup_cancel().
Example 1.80. t_check_trans usage
Example 1.81. t_check_trans usage
if ( method == "CANCEL" && !t_check_trans())
sl_reply("403", "cancel out of the blue forbidden");
# note: in this example t_check_trans() can be replaced by t_lookup_cancel()
5.43. t_set_disable_6xx(0|1)
5.43. t_set_disable_6xx(0|1)
Turn off/on 6xx replies special rfc conformant handling on a per
transaction basis. If turned off (t_set_disable_6xx("1")) 6XXs will be
@ -2531,7 +2547,7 @@ if ( method == "CANCEL" && !t_check_trans())
See also: disable_6xx_block.
Example 1.81. t_set_disable_6xx usage
Example 1.82. t_set_disable_6xx usage
...
route {
...
@ -2540,13 +2556,13 @@ route {
...
}
5.44. t_set_disable_failover(0|1)
5.44. t_set_disable_failover(0|1)
Turn off/on dns failover on a per transaction basis.
See also: use_dns_failover.
Example 1.82. t_set_disable_failover usage
Example 1.83. t_set_disable_failover usage
...
route {
...
@ -2555,11 +2571,11 @@ route {
...
}
5.45. t_set_disable_internal_reply(0|1)
5.45. t_set_disable_internal_reply(0|1)
Turn off/on sending internally a SIP reply in case of relay errors.
Example 1.83. t_set_disable_internal_reply usage
Example 1.84. t_set_disable_internal_reply usage
...
t_set_disable_internal_reply(1); # turn off sending internal reply on error
if(!t_relay()) {
@ -2567,7 +2583,7 @@ if(!t_relay()) {
}
...
5.46. t_replicate([params])
5.46. t_replicate([params])
Replicate the SIP request to a specific address.
@ -2590,7 +2606,7 @@ if(!t_relay()) {
* hostport - address in "host:port" format. It can be given via an
AVP.
Example 1.84. t_replicate usage
Example 1.85. t_replicate usage
...
# sent to 1.2.3.4:5060 over tcp
t_replicate("sip:1.2.3.4:5060;transport=tcp");
@ -2603,7 +2619,7 @@ t_replicate("sip:$var(h);transport=tls");
t_replicate_to_udp("1.2.3.4", "5060");
...
5.47. t_relay_to(proxy, flags)
5.47. t_relay_to(proxy, flags)
Forward the SIP request to a specific address, controlling internal
behavior via flags.
@ -2624,7 +2640,7 @@ t_replicate_to_udp("1.2.3.4", "5060");
+ 0x02 - do not generate reply on internal error.
+ 0x04 - disable dns failover.
Example 1.85. t_relay_to usage
Example 1.86. t_relay_to usage
...
# sent to 1.2.3.4:5060 over tcp
t_relay_to("tcp:1.2.3.4:5060");
@ -2636,7 +2652,7 @@ t_relay_to("tls:1.2.3.4");
t_relay_to("0x01");
...
5.48. t_set_no_e2e_cancel_reason(0|1)
5.48. t_set_no_e2e_cancel_reason(0|1)
Enables/disables reason header (RFC 3326) copying from the triggering
received CANCEL to the generated hop-by-hop CANCEL. 0 enables and 1
@ -2647,7 +2663,7 @@ t_relay_to("0x01");
See also: e2e_cancel_reason.
Example 1.86. t_set_no_e2e_cancel_reason usage
Example 1.87. t_set_no_e2e_cancel_reason usage
...
route {
...
@ -2657,7 +2673,7 @@ opying
...
}
5.49. t_is_set(target)
5.49. t_is_set(target)
Return true if the attribute specified by 'target' is set for
transaction.
@ -2670,13 +2686,13 @@ opying
* onreply_route - the function returns true if an onreply route is
set to be executed.
Example 1.87. t_replicate usage
Example 1.88. t_replicate usage
...
if(!t_is_set("failure_route"))
LM_DBG("no failure route will be executed for current transaction\n");
...
5.50. t_use_uac_headers()
5.50. t_use_uac_headers()
Set internal flags to tell tm to use UAC side for building headers for
local generated requests (ACK, CANCEL) - useful when changing From/To
@ -2684,12 +2700,12 @@ if(!t_is_set("failure_route"))
It returns true.
Example 1.88. t_use_uac_headers usage
Example 1.89. t_use_uac_headers usage
...
t_use_uac_headers();
...
5.51. t_is_retr_async_reply()
5.51. t_is_retr_async_reply()
Check to see if the reply is a retransmitted reply on a transaction
that is currently suspended asynchronously (suspended during reply
@ -2703,7 +2719,7 @@ t_use_uac_headers();
returns true if the transaction is currently reply suspended or false
if not.
Example 1.89. t_is_retr_async_reply usage
Example 1.90. t_is_retr_async_reply usage
...
if (t_is_retr_async_reply()) {
xlog("L_DBG", "Dropping retransmitted reply which is still currently sus
@ -2792,7 +2808,7 @@ end of body
6.2. Functions
6.2.1. register_tmcb(cb_type, cb_func)
6.2.1. register_tmcb(cb_type, cb_func)
For programmatic use only--register a function to be called back on an
event. See t_hooks.h for more details.
@ -2801,7 +2817,7 @@ end of body
* cb_type - Callback type.
* cb_func - Callback function.
6.2.2. load_tm(*import_structure)
6.2.2. load_tm(*import_structure)
For programmatic use only--import exported TM functions. See the acc
module for an example of use.
@ -2809,7 +2825,7 @@ end of body
Meaning of the parameters is as follows:
* import_structure - Pointer to the import structure.
6.2.3. int t_suspend(struct sip_msg *msg, unsigned int *hash_index, unsigned
6.2.3. int t_suspend(struct sip_msg *msg, unsigned int *hash_index, unsigned
int *label)
For programmatic use only. This function together with t_continue() can
@ -2847,7 +2863,7 @@ int *label)
t_suspend() should return 0 to make sure that the script processing
does not continue.
6.2.4. int t_continue(unsigned int hash_index, unsigned int label, struct
6.2.4. int t_continue(unsigned int hash_index, unsigned int label, struct
action *route)
For programmatic use only. This function is the pair of t_suspend(),
@ -2863,7 +2879,7 @@ action *route)
Return value: 0 - success, <0 - error.
6.2.5. int t_cancel_suspend(unsigned int hash_index, unsigned int label)
6.2.5. int t_cancel_suspend(unsigned int hash_index, unsigned int label)
For programmatic use only. This function is for revoking t_suspend()
from the same process as it was executed before. t_cancel_suspend() can
@ -2883,7 +2899,7 @@ action *route)
7.1. event_route[tm:branch-failure]
7.1. event_route[tm:branch-failure]
7.1. event_route[tm:branch-failure]
Named branch failure routes can be defined to run when when a failure
response is received. This allows handling failures on individual
@ -2893,7 +2909,7 @@ action *route)
enabled with the t_on_branch_failure function. This event_route uses
the BRANCH_FAILURE_ROUTE route type.
Example 1.90. event_route[tm:branch-failure] usage
Example 1.91. event_route[tm:branch-failure] usage
...
route {
t_on_branch_failure("myroute");

@ -1407,4 +1407,25 @@ modparam("tm", "dns_reuse_rcv_socket", 1)
</example>
</section>
<section id="tm.p.xavp_contact">
<title><varname>xavp_contact</varname> (string)</title>
<para>
The name of XAVP storing the attributes per contact. This must be the same as
the usrloc parameter <varname>xavp_contacts</varname>.
</para>
<para>
<emphasis>
Default value is <quote>NULL</quote>.
</emphasis>
</para>
<example>
<title>Set <varname>xavp_contact</varname> parameter</title>
<programlisting format="linespecific">
...
modparam("tm|usrloc", "xavp_contact", "ulattrs")
...
</programlisting>
</example>
</section>
</section>

@ -32,6 +32,7 @@
#include "../../dset.h"
#include "../../parser/msg_parser.h"
#include "../../ut.h"
#include "../../xavp.h"
#include "config.h"
#include "t_funcs.h"
#include "t_reply.h"
@ -40,6 +41,8 @@
/* usr_avp flag for sequential forking */
#define Q_FLAG (1<<2)
extern str ulattrs_xavp_name;
/* Struture where information regarding contacts is stored */
struct contact {
str uri;
@ -53,6 +56,7 @@ struct contact {
unsigned int flags;
unsigned short q_flag;
struct contact *next;
sr_xavp_t *ulattrs;
};
struct instance_list {
@ -97,7 +101,7 @@ static str ua_name = {"ua", 2};
void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
unsigned int flags, unsigned int q_flag, str *instance,
str *ruid, str *location_ua)
str *ruid, str *location_ua, sr_xavp_t *ulattrs_xavp)
{
sr_xavp_t *record;
sr_xval_t val;
@ -151,6 +155,8 @@ void add_contacts_avp(str *uri, str *dst_uri, str *path, str *sock_str,
xavp_add_value(&ua_name, &val, &record);
}
xavp_add(xavp_clone_level_nodata(ulattrs_xavp), &record);
val.type = SR_XTYPE_XAVP;
val.v.xavp = record;
if(xavp_add_value(&contacts_avp, &val, NULL)==NULL) {
@ -215,6 +221,10 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
contacts->instance = msg->instance;
contacts->ruid = msg->ruid;
contacts->location_ua = msg->location_ua;
if (ulattrs_xavp_name.s != NULL)
{
contacts->ulattrs = xavp_get_by_index(&ulattrs_xavp_name, 0, NULL);
}
first_idx = 0;
} else {
/* Insert first branch to first contact */
@ -234,6 +244,10 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
contacts->ruid.len = branch->ruid_len;
contacts->location_ua.s = branch->location_ua;
contacts->location_ua.len = branch->location_ua_len;
if (ulattrs_xavp_name.s != NULL)
{
contacts->ulattrs = xavp_get_by_index(&ulattrs_xavp_name, 1, NULL);
}
first_idx = 1;
}
@ -249,6 +263,7 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
return -1;
}
memset(next, 0, sizeof(struct contact));
next->uri.s = branch->uri;
next->uri.len = branch->len;
next->dst_uri.s = branch->dst_uri;
@ -264,6 +279,10 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
next->ruid.len = branch->ruid_len;
next->location_ua.s = branch->location_ua;
next->location_ua.len = branch->location_ua_len;
if (ulattrs_xavp_name.s != NULL)
{
next->ulattrs = xavp_get_by_index(&ulattrs_xavp_name, idx + 1, NULL);
}
next->next = (struct contact *)0;
prev = (struct contact *)0;
@ -320,13 +339,17 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
add_contacts_avp(&(curr->uri), &(curr->dst_uri), &(curr->path),
&sock_str, curr->flags, curr->q_flag,
&(curr->instance), &(curr->ruid), &(curr->location_ua));
&(curr->instance), &(curr->ruid), &(curr->location_ua),
curr->ulattrs);
curr = curr->next;
}
/* Clear all branches */
clear_branches();
if (ulattrs_xavp_name.s != NULL){
xavp_rm_by_name(&ulattrs_xavp_name, 1, NULL);
}
/* Free contact list */
free_contact_list(contacts);
@ -336,7 +359,7 @@ int t_load_contacts(struct sip_msg* msg, char* key, char* value)
void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
unsigned int flags, str *instance, str *ruid,
str *location_ua)
str *location_ua, sr_xavp_t *ulattrs_xavp)
{
sr_xavp_t *record;
sr_xval_t val;
@ -382,6 +405,8 @@ void add_contact_flows_avp(str *uri, str *dst_uri, str *path, str *sock_str,
xavp_add_value(&ua_name, &val, &record);
}
xavp_add(ulattrs_xavp, &record);
val.type = SR_XTYPE_INT;
val.v.i = flags;
xavp_add_value(&flags_name, &val, &record);
@ -516,6 +541,12 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
location_ua.len = 0;
}
if (ulattrs_xavp_name.s != NULL)
{
vavp = xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp);
xavp_insert(vavp, 0, NULL);
}
/* Rewrite Request-URI */
rewrite_uri(msg, &uri);
@ -627,8 +658,9 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
ilp = ilp->next;
}
if (ilp) {
vavp = (ulattrs_xavp_name.s != NULL)?xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp):NULL;
add_contact_flows_avp(&uri, &dst_uri, &path, &sock_str,
flags, &instance, &ruid, &location_ua);
flags, &instance, &ruid, &location_ua, vavp);
goto check_q_flag;
}
if (!q_flag) {
@ -672,6 +704,12 @@ int t_next_contacts(struct sip_msg* msg, char* key, char* value)
return -1;
}
if (ulattrs_xavp_name.s != NULL)
{
vavp = xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp);
xavp_insert(vavp, nr_branches, NULL);
}
check_q_flag:
if (q_flag) {
free_instance_list(il);
@ -808,6 +846,12 @@ int t_next_contact_flow(struct sip_msg* msg, char* key, char* value)
return -1;
}
if (ulattrs_xavp_name.s != NULL)
{
vavp = xavp_extract(&ulattrs_xavp_name, &xavp->val.v.xavp);
xavp_insert(vavp, nr_branches, NULL);
}
xavp_rm(xavp, NULL);
return 1;
next_xavp:

@ -268,6 +268,7 @@ static char *fr_inv_timer_param = 0 /*FR_INV_TIMER_AVP*/;
str contacts_avp = {0, 0};
str contact_flows_avp = {0, 0};
str ulattrs_xavp_name = {NULL, 0};
int tm_remap_503_500 = 1;
@ -512,6 +513,7 @@ static param_export_t params[]={
{"local_cancel_reason", PARAM_INT, &default_tm_cfg.local_cancel_reason },
{"e2e_cancel_reason", PARAM_INT, &default_tm_cfg.e2e_cancel_reason },
#endif /* CANCEL_REASON_SUPPORT */
{"xavp_contact", PARAM_STR, &ulattrs_xavp_name },
{0,0,0}
};

@ -14,9 +14,9 @@ Ramona-Elena Modroiu
<ramona@rosdev.ro>
Copyright © 2009-2010 asipto.com
Copyright © 2009-2010 asipto.com
Copyright © 2005 Voice Sistem
Copyright © 2005 Voice Sistem
__________________________________________________________________
Table of Contents
@ -191,9 +191,12 @@ Chapter 1. Admin Guide
Known limitations in this version:
* Authentication does not support qop auth-int, just qop auth;
* CSeq is not increased during authentication - the response may be
rejected.
* The “uac_replace_*” functions can only be run once on the same SIP
* CSeq is not increased automatically by uac_auth() during
authentication - the follow up request may be rejected. CSeq can be
increased when authenticating INVITE requests - dialog module has
to be used, with CSeq tracking feature enabled (see the readme of
dialog module).
* The "uac_replace_*" functions can only be run once on the same SIP
request. Try to save needed changes in a pseudovariable and apply
them once.
@ -207,9 +210,9 @@ Chapter 1. Admin Guide
The following modules must be loaded before this module:
* TM - Transaction Module
* RR - Record-Route Module, but only if restore mode for From: URI is
set to “auto”.
set to "auto".
* Dialog Module, but only if restore mode for From: URI is set to
“auto” and you want uac_replace_from or uac_replace_to to store the
"auto" and you want uac_replace_from or uac_replace_to to store the
values of the URIs as dialog variables.
2.2. External Libraries or Applications
@ -242,7 +245,7 @@ Chapter 1. Admin Guide
Name of Record-Route header parameter that will be used to store an
encoded version of the original FROM URI.
This parameter is optional, it's default value being “vsf”.
This parameter is optional, it's default value being "vsf".
Example 1.1. Set rr_from_store_param parameter
...
@ -254,7 +257,7 @@ modparam("uac","rr_from_store_param","my_param")
Name of Record-Route header parameter that will be used to store
(encoded) the original TO URI.
This parameter is optional, it's default value being “vst”.
This parameter is optional, it's default value being "vst".
Example 1.2. Set rr_to_store_param parameter
...
@ -265,16 +268,16 @@ modparam("uac","rr_to_store_param","my_param")
There are 3 modes of restoring the original FROM URI and the original
TO URI:
* “none” - no information about original URI is stored; restoration
* "none" - no information about original URI is stored; restoration
is not possible.
* “manual” - all following replies will be restored, but not also the
* "manual" - all following replies will be restored, but not also the
sequential requests - this must be manually updated based on
original URI.
* “auto” - all sequential requests and replies will be automatically
* "auto" - all sequential requests and replies will be automatically
updated based on stored original URI. For this option you have to
set “modparam("rr", "append_fromtag", 1)”.
set "modparam("rr", "append_fromtag", 1)".
This parameter is optional, it's default value being “auto”.
This parameter is optional, it's default value being "auto".
Example 1.3. Set restore_mode parameter
...
@ -366,9 +369,9 @@ modparam("uac","credential","username:domain:password")
This can be used if the realm upstream will be using is not known in
advance.
If you define it, you also need to define “auth_username_avp”
(Section 3.10, “auth_username_avp (string)”) and “auth_username_avp”
(Section 3.11, “auth_password_avp (string)”).
If you define it, you also need to define "auth_username_avp"
(Section 3.10, "auth_username_avp (string)") and "auth_username_avp"
(Section 3.11, "auth_password_avp (string)").
Example 1.9. Set auth_realm_avp parameter
...
@ -380,9 +383,9 @@ modparam("uac","auth_realm_avp","$avp(i:10)")
The definition of an AVP that might contain the username to be used to
perform authentication.
If you define it, you also need to define “auth_realm_avp”
(Section 3.9, “auth_realm_avp (string)”) and “auth_username_avp”
(Section 3.11, “auth_password_avp (string)”).
If you define it, you also need to define "auth_realm_avp"
(Section 3.9, "auth_realm_avp (string)") and "auth_username_avp"
(Section 3.11, "auth_password_avp (string)").
Example 1.10. Set auth_username_avp parameter
...
@ -394,9 +397,9 @@ modparam("uac","auth_username_avp","$avp(i:11)")
The definition of an AVP that might contain the password to be used to
perform authentication.
If you define it, you also need to define “auth_password_avp”
(Section 3.11, “auth_password_avp (string)”) and “auth_username_avp”
(Section 3.11, “auth_password_avp (string)”).
If you define it, you also need to define "auth_password_avp"
(Section 3.11, "auth_password_avp (string)") and "auth_username_avp"
(Section 3.11, "auth_password_avp (string)").
Example 1.11. Set auth_password_avp parameter
...
@ -443,7 +446,7 @@ modparam("uac", "reg_retry_interval", 300)
DB table name to fetch user profiles for registration.
This parameter is optional, it's default value being “uacreg”.
This parameter is optional, it's default value being "uacreg".
Example 1.15. Set reg_db_table parameter
...
@ -475,7 +478,7 @@ modparam("uac", "reg_contact_addr", "192.168.1.2:5080")
4.9. uac_reg_lookup(uuid, dst)
4.10. uac_reg_request_to(user, mode)
4.1. uac_replace_from(display,uri)
4.1. uac_replace_from(display,uri)
Replace in FROM header the display name and the URI part.
@ -518,7 +521,7 @@ uac_replace_from("","sip:robin@gotham.org");
uac_replace_from("","");
...
4.2. uac_replace_from(uri)
4.2. uac_replace_from(uri)
Replace in FROM header the URI part without altering the display name.
@ -531,7 +534,7 @@ uac_replace_from("","");
uac_replace_from("sip:batman@gotham.org");
...
4.3. uac_restore_from()
4.3. uac_restore_from()
This function will check if the FROM URI was modified and will use the
information stored in header parameter to restore the original FROM URI
@ -544,7 +547,7 @@ uac_replace_from("sip:batman@gotham.org");
uac_restore_from();
...
4.4. uac_replace_to(display,uri)
4.4. uac_replace_to(display,uri)
Replace in TO header the display name and the URI part.
@ -569,7 +572,7 @@ uac_replace_to("","sip:robin@gotham.org");
uac_replace_to("","");
...
4.5. uac_replace_to(uri)
4.5. uac_replace_to(uri)
Replace in TO header the URI part without altering the display name.
@ -600,7 +603,7 @@ uac_replace_to("","");
uac_replace_to("sip:batman@gotham.org");
...
4.6. uac_restore_to()
4.6. uac_restore_to()
This function will check if the TO URI was modified and will use the
information stored in header parameter to restore the original TO URI
@ -613,7 +616,7 @@ uac_replace_to("sip:batman@gotham.org");
uac_restore_to();
...
4.7. uac_auth()
4.7. uac_auth()
This function can be called only from failure route and will build the
authentication response header and insert it into the request without
@ -623,10 +626,34 @@ uac_restore_to();
Example 1.23. uac_auth usage
...
uac_auth();
modparam("uac","auth_username_avp","$avp(auser)")
modparam("uac","auth_password_avp","$avp(apass)")
modparam("uac","auth_realm_avp","$avp(arealm)")
request_route {
...
if(is_method("INVITE")) {
t_on_failure("TRUNKAUTH");
}
...
}
failure_route[TRUNKAUTH] {
if (t_is_canceled()) {
exit;
}
if(t_check_status("401|407")) {
$avp(auser) = "test";
$avp(apass) = "test";
uac_auth();
t_relay();
exit;
}
}
...
4.8. uac_req_send()
4.8. uac_req_send()
This function sends a SIP message from the configuration file. The
message is built out of $uac_req(...) pseudo-variable.
@ -644,7 +671,7 @@ $uac_req(callid)=$(mb{s.md5});
uac_req_send();
...
4.9. uac_reg_lookup(uuid, dst)
4.9. uac_reg_lookup(uuid, dst)
This function sets the PV dst to SIP URI that correspond to uuid in uac
registations table. uuid and dst must be pseudo-variables.
@ -660,7 +687,7 @@ if(uac_reg_lookup("$rU", "$ru"))
}
...
4.10. uac_reg_request_to(user, mode)
4.10. uac_reg_request_to(user, mode)
This function can be used to send an authenticated request to a remote
user in the uac registrations table. It sets the request-uri, dst-uri
@ -704,7 +731,7 @@ failure_route[REMOTE_AUTH] {
6.1. event_route[uac:reply]
6.1. event_route[uac:reply]
6.1. event_route[uac:reply]
Event route executed for the final reply to the request set with
uac_req_send(). The associated $uac_req(evroute) has to be set to 1.
@ -741,7 +768,7 @@ event_route[uac:reply] {
8.5. uac.reg_reload
8.6. uac.reg_refresh
8.1. uac.reg_dump
8.1. uac.reg_dump
Dump the content of remote registration table from memory.
@ -750,7 +777,7 @@ event_route[uac:reply] {
kamcmd uac.reg_dump
...
8.2. uac.reg_info
8.2. uac.reg_info
Return the details of a remote registration record based on a filter.
The command has two parameter: attribute and value. The attribute can
@ -763,7 +790,7 @@ event_route[uac:reply] {
kamcmd uac.reg_info l_uuid account123
...
8.3. uac.reg_enable
8.3. uac.reg_enable
Enable a remote registration record based on a filter. The command has
two parameter: attribute and value. The attribute can be: l_uuid,
@ -776,7 +803,7 @@ event_route[uac:reply] {
kamcmd uac.reg_enable l_uuid account123
...
8.4. uac.reg_disable
8.4. uac.reg_disable
Disable a remote registration record based on a filter. The command has
two parameter: attribute and value. The attribute can be: l_uuid,
@ -789,7 +816,7 @@ event_route[uac:reply] {
kamcmd uac.reg_disable l_uuid account123
...
8.5. uac.reg_reload
8.5. uac.reg_reload
Reload the records from database for remote registrations.
@ -798,7 +825,7 @@ event_route[uac:reply] {
kamcmd uac.reg_reload
...
8.6. uac.reg_refresh
8.6. uac.reg_refresh
Load one record by l_uuid from database for remote registrations. If
the record exists in memory, its authentication password is updated,

@ -20,7 +20,7 @@ int bind_uac(uac_api_t*);
inline static int load_uac_api(uac_api_t *uacb){
bind_uac_f bind_uac_exports;
if(!(bind_uac_exports=(bind_uac_f)find_export("bind_uac",1,0))){
LM_ERR("Failed to import bind_iuax\n");
LM_ERR("Failed to import bind_uac\n");
return -1;
}
return bind_uac_exports(uacb);

@ -42,8 +42,10 @@
</listitem>
<listitem>
<para>
CSeq is not increased during authentication - the response
may be rejected.
CSeq is not increased automatically by uac_auth() during authentication
- the follow up request may be rejected. CSeq can be increased when
authenticating INVITE requests - dialog module has to be used, with
CSeq tracking feature enabled (see the readme of dialog module).
</para>
</listitem>
<listitem>
@ -688,7 +690,31 @@ uac_restore_to();
<title><function>uac_auth</function> usage</title>
<programlisting format="linespecific">
...
uac_auth();
modparam("uac","auth_username_avp","$avp(auser)")
modparam("uac","auth_password_avp","$avp(apass)")
modparam("uac","auth_realm_avp","$avp(arealm)")
request_route {
...
if(is_method("INVITE")) {
t_on_failure("TRUNKAUTH");
}
...
}
failure_route[TRUNKAUTH] {
if (t_is_canceled()) {
exit;
}
if(t_check_status("401|407")) {
$avp(auser) = "test";
$avp(apass) = "test";
uac_auth();
t_relay();
exit;
}
}
...
</programlisting>
</example>

@ -807,8 +807,10 @@ modparam("usrloc", "timer_procs", 4)
3.34. xavp_contact (string)
The name of XAVP storring the attributes per contact. They are saved in
location record and restored at lookup.
The name of XAVP storing the attributes per contact. They are saved in
location record and restored at lookup. The tm module parameter
xavp_contact must also be set to the same value to use the
t_load_contacts and t_next_contacts functions.
Default value is "NULL".

@ -895,8 +895,10 @@ modparam("usrloc", "timer_procs", 4)
<section id="usrloc.p.xavp_contact">
<title><varname>xavp_contact</varname> (string)</title>
<para>
The name of XAVP storring the attributes per contact. They are saved
in location record and restored at lookup.
The name of XAVP storing the attributes per contact. They are saved
in location record and restored at lookup. The tm module parameter
<varname>xavp_contact</varname> must also be set to the same value to use the
<varname>t_load_contacts</varname> and <varname>t_next_contacts</varname> functions.
</para>
<para>
<emphasis>

@ -52,25 +52,25 @@
*/
size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream_ptr)
{
http_res_stream_t *stream = (http_res_stream_t *) stream_ptr;
http_res_stream_t *stream = (http_res_stream_t *) stream_ptr;
stream->buf = (char *) pkg_realloc(stream->buf, stream->curr_size +
(size * nmemb) + 1);
stream->buf = (char *) pkg_realloc(stream->buf, stream->curr_size +
(size * nmemb) + 1);
if (stream->buf == NULL) {
LM_ERR("cannot allocate memory for stream\n");
return CURLE_WRITE_ERROR;
}
if (stream->buf == NULL) {
LM_ERR("cannot allocate memory for stream\n");
return CURLE_WRITE_ERROR;
}
memcpy(&stream->buf[stream->pos], (char *) ptr, (size * nmemb));
memcpy(&stream->buf[stream->pos], (char *) ptr, (size * nmemb));
stream->curr_size += ((size * nmemb) + 1);
stream->pos += (size * nmemb);
stream->curr_size += ((size * nmemb) + 1);
stream->pos += (size * nmemb);
stream->buf[stream->pos + 1] = '\0';
stream->buf[stream->pos + 1] = '\0';
return size * nmemb;
}
return size * nmemb;
}
/*
@ -79,73 +79,73 @@ size_t write_function( void *ptr, size_t size, size_t nmemb, void *stream_ptr)
*/
int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post)
{
CURL *curl;
CURLcode res;
str value, post_value;
char *url, *at, *post;
http_res_stream_t stream;
long stat;
pv_spec_t *dst;
pv_value_t val;
double download_size;
memset(&stream, 0, sizeof(http_res_stream_t));
if (fixup_get_svalue(_m, (gparam_p)_url, &value) != 0) {
LM_ERR("cannot get page value\n");
return -1;
}
curl = curl_easy_init();
if (curl == NULL) {
LM_ERR("failed to initialize curl\n");
return -1;
}
url = pkg_malloc(value.len + 1);
if (url == NULL) {
curl_easy_cleanup(curl);
LM_ERR("cannot allocate pkg memory for url\n");
return -1;
}
memcpy(url, value.s, value.len);
*(url + value.len) = (char)0;
curl_easy_setopt(curl, CURLOPT_URL, url);
if (_post) {
/* Now specify we want to POST data */
curl_easy_setopt(curl, CURLOPT_POST, 1L);
if (fixup_get_svalue(_m, (gparam_p)_post, &post_value) != 0) {
LM_ERR("cannot get post value\n");
curl_easy_cleanup(curl);
pkg_free(url);
CURL *curl;
CURLcode res;
str value, post_value;
char *url, *at, *post;
http_res_stream_t stream;
long stat;
pv_spec_t *dst;
pv_value_t val;
double download_size;
memset(&stream, 0, sizeof(http_res_stream_t));
if (fixup_get_svalue(_m, (gparam_p)_url, &value) != 0) {
LM_ERR("cannot get page value\n");
return -1;
}
post = pkg_malloc(post_value.len + 1);
if (post == NULL) {
}
curl = curl_easy_init();
if (curl == NULL) {
LM_ERR("failed to initialize curl\n");
return -1;
}
url = pkg_malloc(value.len + 1);
if (url == NULL) {
curl_easy_cleanup(curl);
pkg_free(url);
LM_ERR("cannot allocate pkg memory for post\n");
return -1;
LM_ERR("cannot allocate pkg memory for url\n");
return -1;
}
memcpy(url, value.s, value.len);
*(url + value.len) = (char)0;
curl_easy_setopt(curl, CURLOPT_URL, url);
if (_post) {
/* Now specify we want to POST data */
curl_easy_setopt(curl, CURLOPT_POST, 1L);
if (fixup_get_svalue(_m, (gparam_p)_post, &post_value) != 0) {
LM_ERR("cannot get post value\n");
curl_easy_cleanup(curl);
pkg_free(url);
return -1;
}
post = pkg_malloc(post_value.len + 1);
if (post == NULL) {
curl_easy_cleanup(curl);
pkg_free(url);
LM_ERR("cannot allocate pkg memory for post\n");
return -1;
}
memcpy(post, post_value.s, post_value.len);
*(post + post_value.len) = (char)0;
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);
}
memcpy(post, post_value.s, post_value.len);
*(post + post_value.len) = (char)0;
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post);
}
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)http_query_timeout);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream);
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, (long)1);
curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)http_query_timeout);
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, write_function);
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream);
res = curl_easy_perform(curl);
pkg_free(url);
if (_post) {
pkg_free(post);
}
res = curl_easy_perform(curl);
pkg_free(url);
if (_post) {
pkg_free(post);
}
if (res != CURLE_OK) {
/* http://curl.haxx.se/libcurl/c/libcurl-errors.html */
@ -156,33 +156,33 @@ int http_query(struct sip_msg* _m, char* _url, char* _dst, char* _post)
} else {
LM_ERR("failed to perform curl (%d)\n", res);
}
curl_easy_cleanup(curl);
if(stream.buf)
pkg_free(stream.buf);
return -1;
}
curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &stat);
if ((stat >= 200) && (stat < 500)) {
curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &download_size);
LM_DBG("http_query download size: %u\n", (unsigned int)download_size);
/* search for line feed */
at = memchr(stream.buf, (char)10, download_size);
if (at == NULL) {
/* not found: use whole stream */
at = stream.buf + (unsigned int)download_size;
}
val.rs.s = stream.buf;
val.rs.len = at - stream.buf;
LM_DBG("http_query result: %.*s\n", val.rs.len, val.rs.s);
val.flags = PV_VAL_STR;
dst = (pv_spec_t *)_dst;
dst->setf(_m, &dst->pvp, (int)EQ_T, &val);
}
curl_easy_cleanup(curl);
pkg_free(stream.buf);
return stat;
curl_easy_getinfo(curl, CURLINFO_HTTP_CODE, &stat);
if ((stat >= 200) && (stat < 500)) {
curl_easy_getinfo(curl, CURLINFO_SIZE_DOWNLOAD, &download_size);
LM_DBG("http_query download size: %u\n", (unsigned int)download_size);
/* search for line feed */
at = memchr(stream.buf, (char)10, download_size);
if (at == NULL) {
/* not found: use whole stream */
at = stream.buf + (unsigned int)download_size;
}
val.rs.s = stream.buf;
val.rs.len = at - stream.buf;
LM_DBG("http_query result: %.*s\n", val.rs.len, val.rs.s);
val.flags = PV_VAL_STR;
dst = (pv_spec_t *)_dst;
dst->setf(_m, &dst->pvp, (int)EQ_T, &val);
}
curl_easy_cleanup(curl);
pkg_free(stream.buf);
return stat;
}

@ -1,6 +1,6 @@
%define name kamailio
%define ver 4.3.0
%define rel dev0.0%{dist}
%define ver 4.3.1
%define rel 0.0%{dist}

@ -1,3 +1,9 @@
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
-- Victor Seva <linuxmaniac@torreviejawireless.org> Mon, 20 Jul 2015 14:26:43 +0200
kamailio (4.3.0) unstable; urgency=medium
* update version to 4.3.0

@ -16,12 +16,12 @@
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/kamailio
NAME=kamailio
NAME=`basename "$0"`
DESC="Kamailio SIP Server"
HOMEDIR=/var/run/kamailio
HOMEDIR=/var/run/$NAME
PIDFILE=$HOMEDIR/$NAME.pid
DEFAULTS=/etc/default/kamailio
CFGFILE=/etc/kamailio/kamailio.cfg
DEFAULTS=/etc/default/$NAME
CFGFILE=/etc/$NAME/kamailio.cfg
RUN_KAMAILIO=no
USER=kamailio
GROUP=kamailio
@ -67,9 +67,9 @@ create_radius_seqfile ()
# write to the file. If the file exists before kamailio starts, it
# won't change it's ownership and will be writable for both root
# and kamailio, no matter what options are chosen at install time
RADIUS_SEQ_FILE=/var/run/kamailio/kamailio_radius.seq
if [ -d /var/run/kamailio ]; then
chown ${USER}:${GROUP} /var/run/kamailio
RADIUS_SEQ_FILE="$HOMEDIR/kamailio_radius.seq"
if [ -d $HOMEDIR ]; then
chown ${USER}:${GROUP} $HOMEDIR
if [ ! -f $RADIUS_SEQ_FILE ]; then
touch $RADIUS_SEQ_FILE
@ -88,7 +88,7 @@ if [ -f $DEFAULTS ]; then
fi
if [ "$RUN_KAMAILIO" != "yes" ]; then
log_failure_msg "Kamailio not yet configured. Edit /etc/default/kamailio first."
log_failure_msg "Kamailio not yet configured. Edit /etc/default/$NAME first."
exit 0
fi
@ -115,6 +115,7 @@ fi
# /var/run can be a tmpfs
if [ ! -d $HOMEDIR ]; then
mkdir -p $HOMEDIR
chown ${USER}:${GROUP} $HOMEDIR
fi
OPTIONS="-f $CFGFILE -P $PIDFILE -m $SHM_MEMORY -M $PKG_MEMORY -u $USER -g $GROUP"

@ -1,3 +1,9 @@
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
-- Victor Seva <linuxmaniac@torreviejawireless.org> Mon, 20 Jul 2015 14:26:43 +0200
kamailio (4.3.0) unstable; urgency=medium
* update version to 4.3.0

@ -16,12 +16,12 @@
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/kamailio
NAME=kamailio
NAME=`basename "$0"`
DESC="Kamailio SIP Server"
HOMEDIR=/var/run/kamailio
HOMEDIR=/var/run/$NAME
PIDFILE=$HOMEDIR/$NAME.pid
DEFAULTS=/etc/default/kamailio
CFGFILE=/etc/kamailio/kamailio.cfg
DEFAULTS=/etc/default/$NAME
CFGFILE=/etc/$NAME/kamailio.cfg
RUN_KAMAILIO=no
USER=kamailio
GROUP=kamailio
@ -67,9 +67,9 @@ create_radius_seqfile ()
# write to the file. If the file exists before kamailio starts, it
# won't change it's ownership and will be writable for both root
# and kamailio, no matter what options are chosen at install time
RADIUS_SEQ_FILE=/var/run/kamailio/kamailio_radius.seq
if [ -d /var/run/kamailio ]; then
chown ${USER}:${GROUP} /var/run/kamailio
RADIUS_SEQ_FILE="$HOMEDIR/kamailio_radius.seq"
if [ -d $HOMEDIR ]; then
chown ${USER}:${GROUP} $HOMEDIR
if [ ! -f $RADIUS_SEQ_FILE ]; then
touch $RADIUS_SEQ_FILE
@ -88,7 +88,7 @@ if [ -f $DEFAULTS ]; then
fi
if [ "$RUN_KAMAILIO" != "yes" ]; then
log_failure_msg "Kamailio not yet configured. Edit /etc/default/kamailio first."
log_failure_msg "Kamailio not yet configured. Edit /etc/default/$NAME first."
exit 0
fi
@ -115,6 +115,7 @@ fi
# /var/run can be a tmpfs
if [ ! -d $HOMEDIR ]; then
mkdir -p $HOMEDIR
chown ${USER}:${GROUP} $HOMEDIR
fi
OPTIONS="-f $CFGFILE -P $PIDFILE -m $SHM_MEMORY -M $PKG_MEMORY -u $USER -g $GROUP"

@ -1,3 +1,9 @@
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
-- Victor Seva <linuxmaniac@torreviejawireless.org> Mon, 20 Jul 2015 14:26:43 +0200
kamailio (4.3.0) unstable; urgency=medium
* update version to 4.3.0

@ -16,12 +16,12 @@
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/kamailio
NAME=kamailio
NAME=`basename "$0"`
DESC="Kamailio SIP Server"
HOMEDIR=/var/run/kamailio
HOMEDIR=/var/run/$NAME
PIDFILE=$HOMEDIR/$NAME.pid
DEFAULTS=/etc/default/kamailio
CFGFILE=/etc/kamailio/kamailio.cfg
DEFAULTS=/etc/default/$NAME
CFGFILE=/etc/$NAME/kamailio.cfg
RUN_KAMAILIO=no
USER=kamailio
GROUP=kamailio
@ -67,9 +67,9 @@ create_radius_seqfile ()
# write to the file. If the file exists before kamailio starts, it
# won't change it's ownership and will be writable for both root
# and kamailio, no matter what options are chosen at install time
RADIUS_SEQ_FILE=/var/run/kamailio/kamailio_radius.seq
if [ -d /var/run/kamailio ]; then
chown ${USER}:${GROUP} /var/run/kamailio
RADIUS_SEQ_FILE="$HOMEDIR/kamailio_radius.seq"
if [ -d $HOMEDIR ]; then
chown ${USER}:${GROUP} $HOMEDIR
if [ ! -f $RADIUS_SEQ_FILE ]; then
touch $RADIUS_SEQ_FILE
@ -88,7 +88,7 @@ if [ -f $DEFAULTS ]; then
fi
if [ "$RUN_KAMAILIO" != "yes" ]; then
log_failure_msg "Kamailio not yet configured. Edit /etc/default/kamailio first."
log_failure_msg "Kamailio not yet configured. Edit /etc/default/$NAME first."
exit 0
fi
@ -115,6 +115,7 @@ fi
# /var/run can be a tmpfs
if [ ! -d $HOMEDIR ]; then
mkdir -p $HOMEDIR
chown ${USER}:${GROUP} $HOMEDIR
fi
OPTIONS="-f $CFGFILE -P $PIDFILE -m $SHM_MEMORY -M $PKG_MEMORY -u $USER -g $GROUP"

@ -1,3 +1,9 @@
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
-- Victor Seva <linuxmaniac@torreviejawireless.org> Mon, 20 Jul 2015 14:26:43 +0200
kamailio (4.3.0) unstable; urgency=medium
* update version to 4.3.0

@ -16,12 +16,12 @@
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/kamailio
NAME=kamailio
NAME=`basename "$0"`
DESC="Kamailio SIP Server"
HOMEDIR=/var/run/kamailio
HOMEDIR=/var/run/$NAME
PIDFILE=$HOMEDIR/$NAME.pid
DEFAULTS=/etc/default/kamailio
CFGFILE=/etc/kamailio/kamailio.cfg
DEFAULTS=/etc/default/$NAME
CFGFILE=/etc/$NAME/kamailio.cfg
RUN_KAMAILIO=no
USER=kamailio
GROUP=kamailio
@ -67,9 +67,9 @@ create_radius_seqfile ()
# write to the file. If the file exists before kamailio starts, it
# won't change it's ownership and will be writable for both root
# and kamailio, no matter what options are chosen at install time
RADIUS_SEQ_FILE=/var/run/kamailio/kamailio_radius.seq
if [ -d /var/run/kamailio ]; then
chown ${USER}:${GROUP} /var/run/kamailio
RADIUS_SEQ_FILE="$HOMEDIR/kamailio_radius.seq"
if [ -d $HOMEDIR ]; then
chown ${USER}:${GROUP} $HOMEDIR
if [ ! -f $RADIUS_SEQ_FILE ]; then
touch $RADIUS_SEQ_FILE
@ -88,7 +88,7 @@ if [ -f $DEFAULTS ]; then
fi
if [ "$RUN_KAMAILIO" != "yes" ]; then
log_failure_msg "Kamailio not yet configured. Edit /etc/default/kamailio first."
log_failure_msg "Kamailio not yet configured. Edit /etc/default/$NAME first."
exit 0
fi
@ -115,6 +115,7 @@ fi
# /var/run can be a tmpfs
if [ ! -d $HOMEDIR ]; then
mkdir -p $HOMEDIR
chown ${USER}:${GROUP} $HOMEDIR
fi
OPTIONS="-f $CFGFILE -P $PIDFILE -m $SHM_MEMORY -M $PKG_MEMORY -u $USER -g $GROUP"

@ -1,3 +1,9 @@
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
-- Victor Seva <linuxmaniac@torreviejawireless.org> Mon, 20 Jul 2015 14:26:43 +0200
kamailio (4.3.0) unstable; urgency=medium
* update version to 4.3.0

@ -16,12 +16,12 @@
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/kamailio
NAME=kamailio
NAME=`basename "$0"`
DESC="Kamailio SIP Server"
HOMEDIR=/var/run/kamailio
HOMEDIR=/var/run/$NAME
PIDFILE=$HOMEDIR/$NAME.pid
DEFAULTS=/etc/default/kamailio
CFGFILE=/etc/kamailio/kamailio.cfg
DEFAULTS=/etc/default/$NAME
CFGFILE=/etc/$NAME/kamailio.cfg
RUN_KAMAILIO=no
USER=kamailio
GROUP=kamailio
@ -67,9 +67,9 @@ create_radius_seqfile ()
# write to the file. If the file exists before kamailio starts, it
# won't change it's ownership and will be writable for both root
# and kamailio, no matter what options are chosen at install time
RADIUS_SEQ_FILE=/var/run/kamailio/kamailio_radius.seq
if [ -d /var/run/kamailio ]; then
chown ${USER}:${GROUP} /var/run/kamailio
RADIUS_SEQ_FILE="$HOMEDIR/kamailio_radius.seq"
if [ -d $HOMEDIR ]; then
chown ${USER}:${GROUP} $HOMEDIR
if [ ! -f $RADIUS_SEQ_FILE ]; then
touch $RADIUS_SEQ_FILE
@ -88,7 +88,7 @@ if [ -f $DEFAULTS ]; then
fi
if [ "$RUN_KAMAILIO" != "yes" ]; then
log_failure_msg "Kamailio not yet configured. Edit /etc/default/kamailio first."
log_failure_msg "Kamailio not yet configured. Edit /etc/default/$NAME first."
exit 0
fi
@ -115,6 +115,7 @@ fi
# /var/run can be a tmpfs
if [ ! -d $HOMEDIR ]; then
mkdir -p $HOMEDIR
chown ${USER}:${GROUP} $HOMEDIR
fi
OPTIONS="-f $CFGFILE -P $PIDFILE -m $SHM_MEMORY -M $PKG_MEMORY -u $USER -g $GROUP"

@ -1,3 +1,9 @@
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
-- Victor Seva <linuxmaniac@torreviejawireless.org> Mon, 20 Jul 2015 14:26:43 +0200
kamailio (4.3.0) unstable; urgency=medium
* update version to 4.3.0

@ -16,12 +16,12 @@
PATH=/sbin:/bin:/usr/sbin:/usr/bin
DAEMON=/usr/sbin/kamailio
NAME=kamailio
NAME=`basename "$0"`
DESC="Kamailio SIP Server"
HOMEDIR=/var/run/kamailio
HOMEDIR=/var/run/$NAME
PIDFILE=$HOMEDIR/$NAME.pid
DEFAULTS=/etc/default/kamailio
CFGFILE=/etc/kamailio/kamailio.cfg
DEFAULTS=/etc/default/$NAME
CFGFILE=/etc/$NAME/kamailio.cfg
RUN_KAMAILIO=no
USER=kamailio
GROUP=kamailio
@ -67,9 +67,9 @@ create_radius_seqfile ()
# write to the file. If the file exists before kamailio starts, it
# won't change it's ownership and will be writable for both root
# and kamailio, no matter what options are chosen at install time
RADIUS_SEQ_FILE=/var/run/kamailio/kamailio_radius.seq
if [ -d /var/run/kamailio ]; then
chown ${USER}:${GROUP} /var/run/kamailio
RADIUS_SEQ_FILE="$HOMEDIR/kamailio_radius.seq"
if [ -d $HOMEDIR ]; then
chown ${USER}:${GROUP} $HOMEDIR
if [ ! -f $RADIUS_SEQ_FILE ]; then
touch $RADIUS_SEQ_FILE
@ -88,7 +88,7 @@ if [ -f $DEFAULTS ]; then
fi
if [ "$RUN_KAMAILIO" != "yes" ]; then
log_failure_msg "Kamailio not yet configured. Edit /etc/default/kamailio first."
log_failure_msg "Kamailio not yet configured. Edit /etc/default/$NAME first."
exit 0
fi
@ -115,6 +115,7 @@ fi
# /var/run can be a tmpfs
if [ ! -d $HOMEDIR ]; then
mkdir -p $HOMEDIR
chown ${USER}:${GROUP} $HOMEDIR
fi
OPTIONS="-f $CFGFILE -P $PIDFILE -m $SHM_MEMORY -M $PKG_MEMORY -u $USER -g $GROUP"

@ -1,5 +1,5 @@
%define name kamailio
%define ver 4.3.0
%define ver 4.3.1
%define rel 0%{dist}

@ -1,5 +1,5 @@
%define name kamailio
%define ver 4.3.0
%define ver 4.3.1
%define rel 0
%define EXCLUDED_MODULES mysql jabber cpl-c avp_radius auth_radius group_radius uri_radius pa postgres osp tlsops unixodbc

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

@ -1,5 +1,5 @@
%define name kamailio
%define ver 4.3.0
%define ver 4.3.1
%define rel 0
%define EXCLUDED_MODULES mysql jabber cpl-c auth_radius misc_radius peering postgress pa unixodbc osp tlsops

@ -641,6 +641,7 @@ sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold)
LM_ERR("cannot create cloned root xavp\n");
return NULL;
}
LM_DBG("cloned root xavp [%.*s]\n", xold->name.len, xold->name.s);
if(xold->val.type!=SR_XTYPE_XAVP)
{
@ -667,15 +668,16 @@ sr_xavp_t *xavp_clone_level_nodata(sr_xavp_t *xold)
return NULL;
}
}
LM_DBG("cloned inner xavp [%.*s]\n", oavp->name.len, oavp->name.s);
if(xnew->val.v.xavp == NULL)
{
/* link to val in head xavp */
xnew->val.v.xavp = navp;
pavp = navp;
} else {
/* link to prev xavp in the list */
pavp->next = navp;
}
pavp = navp;
}
oavp = oavp->next;
}

Loading…
Cancel
Save