[Pkg-voip-commits] [kamailio] 01/01: Imported Upstream version 4.3.3
Victor Seva Lopez
maniac-guest at moszumanska.debian.org
Tue Oct 13 10:47:29 UTC 2015
This is an automated email from the git hooks/post-receive script.
maniac-guest pushed a commit to annotated tag upstream/4.3.3
in repository kamailio.
commit 5dad250b1dc48feaef8eb7b7709e08a277e3c8da
Author: Victor Seva <linuxmaniac at torreviejawireless.org>
Date: Tue Oct 13 11:15:52 2015 +0200
Imported Upstream version 4.3.3
---
ChangeLog | 1514 +++++++++++++++++++++++
Makefile | 2 +
Makefile.defs | 22 +-
autover.h | 4 +-
core_cmd.c | 4 +-
dset.c | 19 +
dset.h | 4 +
etc/kamailio.cfg | 10 +-
lib/binrpc/binrpc_api.c | 10 +-
lib/srdb1/db.c | 4 +
lib/srdb1/db_val.c | 3 +
lib/trie/dtrie.c | 1 +
main.c | 14 +
mem/f_malloc.c | 149 ++-
mem/f_malloc.h | 12 +-
modules/acc/README | 3 +-
modules/acc/acc_logic.c | 2 +-
modules/acc/doc/acc_admin.xml | 3 +-
modules/acc_radius/acc_radius_mod.c | 81 +-
modules/app_perl/app_perl_mod.c | 4 +-
modules/async/async_mod.c | 8 +-
modules/async/async_sleep.c | 8 +-
modules/auth/README | 209 ++--
modules/auth/doc/auth_functions.xml | 15 +-
modules/auth/nonce.c | 8 +-
modules/auth_db/authorize.c | 20 +-
modules/cnxcc/cnxcc_mod.c | 27 +-
modules/cnxcc/cnxcc_redis.h | 2 +-
modules/corex/corex_rpc.c | 2 +
modules/ctl/binrpc.h | 114 +-
modules/ctl/binrpc_run.c | 10 +-
modules/db_postgres/km_pg_con.c | 4 +
modules/dialog/dlg_db_handler.c | 46 +-
modules/dialog/dlg_handlers.c | 32 +-
modules/dialog/dlg_hash.c | 26 +-
modules/dialog/dlg_hash.h | 13 +-
modules/dialog/dlg_profile.c | 1 +
modules/dialog/dlg_var.c | 24 +-
modules/dispatcher/dispatch.c | 1 +
modules/dmq_usrloc/usrloc_sync.c | 44 +-
modules/domain/domain_mod.c | 4 +-
modules/drouting/README | 160 +--
modules/drouting/doc/drouting_admin.xml | 8 +-
modules/drouting/drouting.c | 2 +-
modules/evapi/README | 27 +-
modules/evapi/evapi_dispatch.c | 120 +-
modules/geoip/geoip_pv.c | 2 +-
modules/htable/ht_api.c | 13 +-
modules/htable/ht_var.c | 7 +-
modules/htable/htable.c | 2 +-
modules/ims_registrar_scscf/README | 818 ++++++++++++
modules/ipops/README | 8 +-
modules/ipops/doc/ipops_admin.xml | 8 +-
modules/janssonrpc-c/README | 18 +-
modules/janssonrpc-c/doc/janssonrpc-c_admin.xml | 18 +-
modules/janssonrpc-c/janssonrpc_connect.c | 9 +-
modules/janssonrpc-c/janssonrpc_io.c | 9 +-
modules/janssonrpc-c/janssonrpc_request.c | 4 +-
modules/janssonrpc-c/janssonrpc_server.c | 4 +-
modules/jsonrpc-c/jsonrpc_io.c | 28 +-
modules/jsonrpc-s/jsonrpc-s_mod.c | 2 +-
modules/kex/mi_core.c | 8 +
modules/mi_datagram/datagram_fnc.c | 2 +
modules/mi_rpc/README | 6 +-
modules/mi_rpc/doc/mi_rpc_admin.xml | 6 +-
modules/permissions/address.c | 83 +-
modules/permissions/mi.c | 14 +-
modules/pipelimit/README | 77 +-
modules/pua/hash.h | 2 +-
modules/pua_reginfo/usrloc_cb.c | 14 +-
modules/pv/README | 23 +-
modules/pv/pv_core.c | 2 +-
modules/registrar/README | 15 +-
modules/registrar/doc/registrar_admin.xml | 10 +-
modules/registrar/lookup.c | 13 +-
modules/registrar/reg_mod.c | 11 +-
modules/registrar/save.c | 14 +
modules/rls/subscribe.c | 4 +-
modules/rr/loose.c | 14 +-
modules/rtpengine/README | 8 +-
modules/rtpengine/doc/rtpengine_admin.xml | 6 +-
modules/sanity/sanity.c | 26 +-
modules/sctp/README | 2 +-
modules/sctp/doc/sctp_admin.xml | 2 +-
modules/siptrace/siptrace.c | 10 +
modules/sqlops/sql_var.c | 6 +-
modules/textops/textops.c | 3 +-
modules/textops/txt_var.c | 2 +-
modules/textopsx/textopsx.c | 2 +-
modules/tm/README | 121 +-
modules/tm/doc/functions.xml | 4 +
modules/tm/doc/params.xml | 2 +-
modules/tm/t_append_branches.c | 13 +-
modules/tm/t_reply.c | 69 +-
modules/tm/t_suspend.c | 26 +-
modules/tmrec/README | 16 +-
modules/tmrec/doc/tmrec_admin.xml | 13 +-
modules/tmx/t_var.c | 57 +-
modules/tmx/tmx_mod.c | 2 +-
modules/tmx/tmx_pretran.c | 9 +-
modules/tsilo/ts_append.c | 18 +-
modules/tsilo/ts_handlers.c | 7 +-
modules/tsilo/ts_hash.c | 4 +-
modules/tsilo/ts_store.c | 17 +-
modules/uac/uac_reg.c | 9 +-
modules/usrloc/ul_mi.c | 4 +-
modules/usrloc/ul_rpc.c | 4 +-
modules/utils/functions.c | 14 +-
parser/case_reas.h | 2 +-
parser/parse_hname2.c | 53 +-
parser/parse_hname2.h | 1 +
parser/parse_retry_after.c | 2 -
pkg/kamailio/centos/6/kamailio.spec | 2 +-
pkg/kamailio/deb/debian/changelog | 12 +
pkg/kamailio/deb/jessie/changelog | 12 +
pkg/kamailio/deb/precise/changelog | 12 +
pkg/kamailio/deb/squeeze/changelog | 12 +
pkg/kamailio/deb/trusty/changelog | 12 +
pkg/kamailio/deb/wheezy/changelog | 12 +
pkg/kamailio/fedora/17/kamailio.spec | 2 +-
pkg/kamailio/rpm/kamailio.spec-4.1 | 2 +-
pkg/kamailio/rpm/kamailio.spec.CenOS | 2 +-
pkg/kamailio/rpm/kamailio.spec.SuSE | 2 +-
pvapi.c | 15 +
pvar.h | 1 +
rvalue.c | 14 +-
select_core.c | 2 +-
sr_module.c | 23 +-
tcp_main.c | 1 +
utils/kamcmd/kamcmd.c | 32 +-
130 files changed, 3945 insertions(+), 827 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index e9f597b..6a662d2 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,1517 @@
+===================== 2015-10-02 Version 4.3.3 Released =====================
+
+===================== Changes Since Version 4.3.2 ===========================
+
+commit 51e15819d31a1387837e1872d4cb80f94956cad1
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Oct 2 14:29:11 2015 +0200
+
+ Makefile.defs: version set to 4.3.3
+
+commit ecf289cfcdb7ee5678d86f03ccf4a5138c102a34
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Oct 2 14:27:36 2015 +0200
+
+ pkg/rpm: updated spec files for v4.3.3
+
+commit 3181001ebae49847ed210428946fde96e89e9c4f
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Oct 2 14:01:34 2015 +0200
+
+ dialog: fix race due to deep copy of dlg hash table slot when saving to db
+
+ (cherry picked from commit 2d9c7f9658fe78979df69c81f56b36366b80a262)
+
+commit 76b5d394ddec84c6a80dcfd67df2e2ec036f37da
+Author: Victor Seva <linuxmaniac at torreviejawireless.org>
+Date: Fri Oct 2 13:26:39 2015 +0200
+
+ pkg/kamailio/deb: update version to 4.3.3
+
+commit bf0efda9cbd3ab02e1cdefb187ae2ac3089e1b18
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Oct 2 10:57:50 2015 +0200
+
+ dialog: avoid useless re-entrant locking when linking the new dialog
+
+ (cherry picked from commit 02fa3bf1b62cb10a33a8b216cfe7baa9e1b84054)
+
+commit 385d9be8ed45f378c52c7d4f1220f517f5605831
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Oct 1 16:51:59 2015 +0200
+
+ dialog: don't update dlg vars in db if in deleted state
+
+ - dlg record and vars are scheduled for deletion
+
+ (cherry picked from commit 6620fe7b0963ffe0e2c0d4ab7a38e85d1dfd121d)
+
+commit 714d3e329e9c0352da814832e6f86cd0e5fdea39
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Oct 1 16:34:59 2015 +0200
+
+ dialog: updated old comment to reflect current behaviour
+
+ (cherry picked from commit 098849c72a8b651a5757eac3eb3dee6772766d76)
+
+commit 9083ac32755565a97421d2b6100bc477c19175f5
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Oct 1 16:31:07 2015 +0200
+
+ dialog: release remote profile lock on remove operation
+
+ (cherry picked from commit 04bd28fffdfed05dda9a8fff41b220a3bb008a17)
+
+commit 1ec00b13bb7069a0a4dba44bac0eb95fd271f9f1
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Oct 1 16:08:13 2015 +0200
+
+ dialog: completed previous commit for spiral handling
+
+ (cherry picked from commit b198b390106924df2279d94f28305c25c86b435e)
+
+commit 39d1b8f8eeddef1d796855e8d7ef63569987fb65
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Oct 1 15:49:26 2015 +0200
+
+ dialog: keep slot locked when searching for duplicate dialog
+
+ - when attempting to create a new dialog, the function searching to see
+ if it is already one with same attributes keeps the slot locked so is
+ no race in between the return of function and building the new dlg
+ structure
+ - if the dlg is found, release the lock after figuring out it is a
+ spiral or not
+
+ (cherry picked from commit 9d807d1d8af24c0163d3bb2ae876a87a8b637494)
+
+commit 915f1410d9c0b4a5afe89727ad2d64437951f8a1
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Sat Sep 26 22:19:17 2015 +0200
+
+ jsonrpc-s: input buffer for fifo transport increased to 8k
+
+ (cherry picked from commit 0a7e24398a564d1703f4484834b823e988cf64db)
+
+commit e0406d460b29e3a4872dfb2f31b710c0773ff88e
+Author: Chris Double <chris.double at double.co.nz>
+Date: Thu Sep 24 11:02:56 2015 +1200
+
+ janssonrpc-c: Fix use after free
+
+ - Fix use after free due to pointer aliasing of 'arg' and 'a'
+ in server_backoff_cb.
+ - Fix use after free in force_disconnect
+ - Fix use after free in free_server_list
+
+ (cherry picked from commit a53b2fb68d555b07be479e41895937ae1c6318f6)
+
+commit 8ffab1caa7753f5cdcf00584340a68f7d3308b18
+Author: Chris Double <chris.double at double.co.nz>
+Date: Thu Sep 24 10:35:34 2015 +1200
+
+ janssonrpc-c: Fix double free if retry timer add fails
+
+ - Fix double free if schedule_retry fails when adding
+ request retry timer. timeout_cb called fail_request
+ which frees req after schedule_retry had already
+ done so.
+
+ (cherry picked from commit bce9cf97646153af6abcf9f43cbb72f2c734e490)
+
+commit 3b2946b41a69e19f4a995c26baa03f6f9fc61cba
+Author: Chris Double <chris.double at double.co.nz>
+Date: Wed Sep 23 22:21:41 2015 +1200
+
+ sqlops: Fix memory leak in error condition
+
+ - Fix pv_parse_dbr_name to free spv if the key is
+ unknown.
+ - Fix typo in error log in pv_parse_dbr_name.
+
+ (cherry picked from commit 48de750550dd12016e957d60e0ae57e59944558d)
+
+commit cfc9fee62d9a7023743b694eeab4276a124f448f
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 23 13:03:15 2015 +0200
+
+ tm: t_suspend() skip suspending if a final response was sent out for transaction already
+
+ (cherry picked from commit 92c376dbeb6ee515a80537c91014972ada4a5f34)
+
+commit 8cdf9a26e90b1006a6992ad73d1e60fbc1c5178c
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 23 12:59:52 2015 +0200
+
+ tsilo: ts_append_to() check if transation is active before adding new branches
+
+ (cherry picked from commit 9451625ff8cc7e02abc2c6cf95572bff9c086d20)
+
+commit 1e0e1a8cd24aac95ffe1970643a2a8cb37f044fe
+Author: Chris Double <chris.double at double.co.nz>
+Date: Wed Sep 23 22:17:21 2015 +1200
+
+ sqlops: Don't pkg_free memory that wasn't pkg_malloc'd
+
+ - Don't pkg_free the gparam_t parameter of sql_parse_index.
+ When called within pv_parse_dbr_name that parameter is
+ an internal field in the sql_pv_t structure and wasn't
+ allocated with pkg_malloc.
+
+ (cherry picked from commit 460e0a6077d69cf74ceb4b095195b683fb49269c)
+
+commit b7c3276fd6a8c309465a6bb22db09044a420c68b
+Author: Chris Double <chris.double at double.co.nz>
+Date: Wed Sep 23 22:03:47 2015 +1200
+
+ htable: Fix buffer overrun in htable_rpc_list
+
+ - Fix for using wrong len variable in htable_rpc_list if
+ ht->dbtable.len is greater than 127, causing an out of
+ bounds write.
+
+ (cherry picked from commit 1c164473c6fd78318236254827a4cadbe8271463)
+
+commit 209162e56facff75549560361cfd1d5474bb615e
+Author: zxcpoiu <zxcpoiu at gmail.com>
+Date: Wed Sep 23 17:23:40 2015 +0800
+
+ tmx: safety check for bad callid header in t_precheck_tran()
+ - reported by GH#331
+
+ (cherry picked from commit 7cc1d1113e8e461656d55595f1a268d345d2676b)
+
+commit 5d7d1fd3ccc96e032ef73a799dfbd97b86839b5e
+Author: Chris Double <chris.double at double.co.nz>
+Date: Wed Sep 23 20:48:56 2015 +1200
+
+ textops: prevent null dereference on tr_txt_eval_re error
+
+ - Check for NULL pointer before calling subst_expr_free
+ to prevent NULL pointer dereference when there is an
+ unknown subtype error.
+
+ (cherry picked from commit 5aa2ed265f80664f57073213b17c83b1dac42ab4)
+
+commit 8559ab818ffae6e24941758ecb97d37894d1adee
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 21 13:04:56 2015 +0200
+
+ evapi: debug messages for invalid len and execution of event route
+
+ (cherry picked from commit 093337bc7f3d8d3ce31ad3770252503628bc3599)
+
+commit 0ceab4ea76348fd91b86ee9d372783a3fef5af76
+Author: Federico Cabiddu <federico.cabiddu at gmail.com>
+Date: Mon Sep 21 12:43:39 2015 +0200
+
+ app_perl: renamed the exported structure "_app_perl_exports" to avoid naming conflicts
+
+ - reported by GH#333
+
+ (cherry picked from commit 2c736877dc215592f3f8889ffd47e90ab68066af)
+
+commit 8a943bd7ab88942aabdd28f1959b0b7e1dd2eb00
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 21 00:16:27 2015 +0200
+
+ core: name of structure exported by a module can be prefixed with module name
+
+ - some modules use the flag for global exporting, which can lead to
+ naming conflicts
+ - related to GH#333
+
+ (cherry picked from commit 6c7d38ee0fcbd482ff0527178481345fc93a7fc8)
+
+commit 660edda79e65925b414f0d0cb47764603a08dd1f
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Sun Sep 20 23:16:35 2015 +0200
+
+ cnxcc: build fake msg for event route before terminating the dialog
+
+ - dialog structure can be deleted in between
+ - reported by GH#324
+
+ (cherry picked from commit 6177e766035f6bad2d5ee512ccde9a805d026760)
+
+commit 0d2fe9ae840d3e34f3c69577a5d6875f2d2c3831
+Author: Olle E. Johansson <oej at edvina.net>
+Date: Sat Sep 19 12:48:42 2015 +0100
+
+ sctp Documentation - change "sercmd" to "kamcmd"
+
+ (cherry picked from commit 58b4ea9ca31305a4450807add2c21e7ecb01614b)
+
+commit 91788e01dec1fba92a2484b5c547a5c493527b60
+Author: Olle E. Johansson <oej at edvina.net>
+Date: Sat Sep 19 12:47:36 2015 +0100
+
+ tm Change "sercmd" to "kamcmd"
+
+ (cherry picked from commit 0c9ea3ccb7fac1180f26741422857807d24fcea1)
+
+commit 6c387ca9c854a426c206266deef6bfcbb77ffb8b
+Author: Olle E. Johansson <oej at edvina.net>
+Date: Sat Sep 19 12:46:06 2015 +0100
+
+ mi_rpc Change "sercmd" to "kamcmd" in docs
+
+ (cherry picked from commit 52d88ef0f0b0b361419edede208acd459af9fb1a)
+
+commit 7e788aac3bd94c2c979441d6ab8b4528faf3c820
+Author: Olle E. Johansson <oej at edvina.net>
+Date: Sat Sep 19 12:43:02 2015 +0100
+
+ srdb1 Check if the module is loaded, so the error message makes sense in case of missing module
+
+ If a module use a default database and it's not loaded, currently
+ Kamailio complains that the module doesn't implement an API function
+ instead of actually telling the Kamailian that the module is not loaded.
+ This patch modifies that behaviour.
+
+ (cherry picked from commit c1a1a1bb054ee79af6ca44d262c8f73c725a2d90)
+
+commit 14297b78418cbe963b491de928f8e44510819c4d
+Author: Olle E. Johansson <oej at edvina.net>
+Date: Mon Apr 20 21:11:42 2015 +0200
+
+ async: Fix some error messages
+
+ (cherry picked from commit 103b915cffd63b4abab1a3e57b51644eef20e81d)
+
+commit f31270d714f6017ec6d4ad3c1ebced6f7fdc8c65
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Sat Sep 19 00:16:22 2015 +0200
+
+ evapi: more debug messages when processing received data
+
+ (cherry picked from commit a8adf3bdb74dd3819bb23e2876eee704663f3cef)
+
+commit fdecde3715688aa9145f21e0cbdb414ace61198c
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Sep 18 10:08:14 2015 +0200
+
+ evapi: implemented receive buffering per connected client
+
+ - incomplete data may be received on tcp, needing to wait to get more
+ (only for netstring format)
+
+ (cherry picked from commit 4eb7656726d1b1b408a12d55b3d7d297b78ee68d)
+
+commit 59976f8235f091e911137e1e1a74154aacd23b9b
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Sep 18 09:31:58 2015 +0200
+
+ htable: more checks of updateexpire when item is updated
+
+ (cherry picked from commit dd0fd7011b750e34c595936b6c95759ccb77f786)
+
+commit 1452eddee9ec5933325faf4d6b26a07ac74394f4
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 16 23:54:02 2015 +0200
+
+ core: cast operator (int) converts hex strings as well
+
+ - in addition to dec string
+
+ (cherry picked from commit 33f159121193b3ed09e2ec7aa7b55aa543aeb852)
+
+commit 98228c451bb6f8d08070b56232736e79fd045073
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Oct 1 09:48:26 2015 +0200
+
+ acc_radius: fixed identation, removed history
+
+ (cherry picked from commit f9a6b7893ad421cb142e03c9c2797773061c8933)
+
+commit c8d17ba355b3979fc28390f9c93460572ecfeb17
+Author: Yasin <yasin.caner at netgsm.com.tr>
+Date: Thu Oct 1 10:28:54 2015 +0300
+
+ acc_radius : fixes extra attribues memory leak
+
+ if we dont free getting memory from extrarstr , can give out of memory. this commit fixes this problem.
+ (cherry picked from commit f84689aa9f56693abe95f537f8a0217a068b1f01)
+
+commit 4479272e96f73d03607af82b4dd3b171ba8a40c3
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Oct 1 09:26:14 2015 +0200
+
+ tmx: tm reply code pv to use status code directly in onreply routes
+
+ - no need to lookup transaction
+
+ (cherry picked from commit 738b113b4be346b7caef600249202d361b556a41)
+
+commit 170d6717abb3b824bf0e7046ab47abcc37369782
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Oct 1 09:12:16 2015 +0200
+
+ tmx: proper response of branch ruid pv for tm onreply route
+
+ (cherry picked from commit 11791d2b749df9673e9c8fe09ae9e923fb6e735b)
+
+commit a79449a149a84957a2786200ba2207027069c410
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Oct 1 09:11:11 2015 +0200
+
+ core: pv - helper function to return empty string
+
+ (cherry picked from commit 36a704e8b54b65e8414fd2a02d973e74a9256e1d)
+
+commit ce1cdba720e34cff1b5c2d150996d666e8ce2127
+Author: Sven Neuhaus <neuhaus at tyntec.com>
+Date: Tue Sep 29 15:26:45 2015 +0200
+
+ core: Fix label for RPC command ("proto" -> "port")
+
+ (cherry picked from commit 03b955ef8cc2ffcc08d0b361c0f1d6ce057c68b8)
+
+commit e10fc9b41e45abd73e3006b3fe8a4c76f96451f7
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Sep 25 23:38:56 2015 +0200
+
+ core: mem - reworked f_malloc free chunks management
+
+ - credits to Juha Heinanen for heling with testing
+
+ (cherry picked from commit 8cced16d7055939a885b6dc6bdb8a346748a0fcd)
+
+commit efb2a06b5f6d4278bda6dec63af8e685a559fd73
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 28 23:02:27 2015 +0200
+
+ core: create runtime dir if doesn't exist
+
+ - test and create runtime dir (default /var/run/kamailio)
+ - do chown of runtime dir if user/group parameters are set for kamailio
+
+ (cherry picked from commit b151e9d6071b1affe814f4edf2e87b132f0accb8)
+
+commit 7ba20025b12bc6754778de72bbca58b01f9c4f7b
+Author: Chris Double <chris.double at double.co.nz>
+Date: Wed Sep 23 21:20:27 2015 +1200
+
+ tsilo: Fix pointer comparison in ts_set_tm_callbacks
+
+ - Fix cloned ts_transaction pointer comparison to check for
+ NULL rather than less than zero. The latter doesn't make
+ sense for an allocated pointer.
+
+ (cherry picked from commit e304f9d8d4cc16a3b6cca1cdd10dff6d0a18d955)
+
+commit 0be54999fe5025cf42fa9d5506e588542c7ec2ed
+Author: Chris Double <chris.double at double.co.nz>
+Date: Wed Sep 23 21:26:39 2015 +1200
+
+ tsilo: Call LM_DBG with correct transaction information
+
+ - Use cb_ptr in ts_onreply LM_DBG call as the ptr variable
+ is NULL at that call point and cb_ptr contains the
+ transaction information being looked for.
+
+ (cherry picked from commit 03f6a49146980338d7e31aec60da551f8b6e7595)
+
+commit 33939d102b836e440915ce958e90cef36aafec2d
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 22 23:05:27 2015 +0200
+
+ domain: proper memset of the hash tables used by domain at init time
+
+ - discovered on a report by Juha Heinanen
+
+ (cherry picked from commit 82f74a57229e46e9b9302a6b4caebed6860c47ed)
+
+commit 71e7e92aeed8acb058e4064a1369f52bd612479f
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 22 15:22:32 2015 +0200
+
+ core: tcp - reset connection write flag if io_watch_chg() for pollout fails
+
+ - it can loop otherwise in trying to see if write can be done
+
+ (cherry picked from commit d36734d658cd0bcfc8357c7e85ca32da0612aaee)
+
+commit 9b1b8a70aaac447624c4633c169dde3b84542b66
+Author: Federico Cabiddu <federico.cabiddu at gmail.com>
+Date: Tue Sep 22 15:53:28 2015 +0200
+
+ tsilo: don't force destination protocol on branches added by t_append_branches
+
+ (cherry picked from commit 6bdddb99d7bca42897b2c0f96a87c49b97efd8ac)
+
+commit 938759112e00bdac837c09e407480872ae1aff35
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 21 18:20:24 2015 +0200
+
+ tsilo: print return error code by lookup_to_dset() in ts_append()
+
+ - helps figuring out why it failed
+
+ (cherry picked from commit 692c24ac7d6524cb2388534ee004d636c8b0c277)
+
+commit 8bdb3f95d3db79bea5f3d49e2c8b0fc090bb65dd
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 22 14:07:47 2015 +0200
+
+ Makefile.defs: memory manager set to q_malloc
+
+commit 2b8dc34378812f9aea187c2cfe27021dd4f7113b
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 21 21:10:47 2015 +0200
+
+ mem: f_malloc - safety init of nxt_free fields in first and last fragments
+
+ (cherry picked from commit 66b9c4dc56e14cac8ffcb0f87d29be4858dafbd3)
+
+commit 2070b215872ce8d15375e9ccda8bb45b496ad44a
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 21 17:01:18 2015 +0200
+
+ mem: f_malloc - proper inserting of last free large fragment
+
+ - reported by Juha Heinanen
+
+ (cherry picked from commit b58a55da1a43f1b2d3b1f0b831fcb639c57a66b9)
+
+commit b09ccd2d16982c16babe5ba71c3e7d94bec71706
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Sun Sep 20 22:33:57 2015 +0200
+
+ mem: f_malloc - properly set empty slot in free hash
+
+ - reported by Juha Heninanen
+
+ (cherry picked from commit f6400aa19736e3f6acf00f3c79f5ddaaf2acbcee)
+
+commit 578200cd2f32dfcc45b1b1fe682a907cf21083e8
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Sun Sep 20 18:48:18 2015 +0200
+
+ tmx: safety check for bad cseq header in t_precheck_tran()
+
+ - reported by GH#331
+
+ (cherry picked from commit 3e84157b4bbce9c6bcb8c4563910811a7eb8f019)
+
+commit 7881ec8d3cd5aa347424108f1fb9860c383e01d5
+Author: Carsten Bock <carsten at ng-voice.com>
+Date: Fri Sep 18 17:25:03 2015 +0200
+
+ utils: Don't leak memory of pkg_realloc returns NULL
+
+commit 020693698e0ec43da1d652524e497f12d1263fe4
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Sep 18 13:36:03 2015 +0200
+
+ tsilo: use current r-uri for ts_store()
+
+ - msg->first_line.u.request.uri is always the incoming r-uri (never
+ updated inside the msg structure)
+ - if $ru was updated, msg->new_uri is set with the new value
+ - if incoming r-uri is wanted back after $ru was updated, revert_uri()
+ can be used
+ - if only incoming r-uri is allowed, then the function doesn't work when
+ dialing an alias or a short number
+
+ (cherry picked from commit 1e5bad019c450a003e812ee051d84134aad6c5f0)
+
+commit bc89d93ce935881754b21af98e1e5ccc41ac9f3a
+Author: Hugh Waite <hugh.waite at acision.com>
+Date: Thu Sep 17 15:50:48 2015 +0100
+
+ parser: Fix parser error when Retry-After is last header
+
+ - Prevent off-by-one error when CRLF is followed by CRLF
+ (cherry picked from commit deab9d061cbe180aaf32b7416c2477b4eb901ec8)
+
+commit 192294cc025f7b39efcd60c2053423ff10861d75
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 17 12:50:55 2015 +0200
+
+ tm: warn in case of transaction is not suspended by a continue is attempted
+
+ (cherry picked from commit 33c5449563becd2357b648ec469ef247a6ae2f5d)
+
+commit c58d4c4471f794944c60164a19ae3aa884fe2ade
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 14 12:45:28 2015 +0200
+
+ tm: test if transaction was suspended before resuming inside t_continue()
+
+ (cherry picked from commit 52c4965bbb4cde5d7bddcf697aa504e7c2202ac1)
+
+commit 0c6bed8779024c0c35a9c1bb82dc24255d8f08e2
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 14 12:53:54 2015 +0200
+
+ tm: reset async suspended flag when continuing via failure_route
+
+ - suspended transaction can be resumed automatically on timeout, without
+ t_continue(), ending up in failure_route
+
+ (cherry picked from commit 171553ebcac2f00a015191f36f2f228c0d3e483b)
+
+commit ce43a14d701ec38276883b863cd81bbb3de3b35a
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 17 12:48:36 2015 +0200
+
+ tmx: err to work if resuming suspended transaction fails
+
+ - it can be a non-suspended transaction id or after expiration
+
+ (cherry picked from commit 2682d85657d1caf96961a6153cd82c506fde7d0d)
+
+commit 978e3b65c7d1d21a69a55492dc156493cc8c28bf
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 16 11:21:08 2015 +0200
+
+ auth_db: more log messages when username checks failed
+
+ (cherry picked from commit d46d008e0936a01229872df71ac26afb43122f4b)
+
+commit c5b7b0baab51c5d2ca584c1ff1366f8e03e97290
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 15 19:05:12 2015 +0200
+
+ ipops: fixed wrong location of double quites in example in docs
+
+ - reported by GH#327
+
+ (cherry picked from commit 5d50171a4443eeafa5734afec58bbf41c07fece7)
+
+commit c8bf8199fbbc8ddfbca76a63df94bb246bb0017a
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 14 22:28:57 2015 +0200
+
+ Makefile: install-initd-centos target creates run dir
+
+ (cherry picked from commit 19b3d02c0fc4188b175d0d86e27f3c092900b10c)
+
+commit d6d2474bbbd6a6fd08cbede42ad1cd64cc47dc64
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Sep 11 16:39:36 2015 +0200
+
+ mem: removed unused variables
+
+ - two old vars not needed anymore after previous commit
+
+ (cherry picked from commit 16bcb9d257622a68eed44d6eea5e342f35dbde83)
+
+commit 7ac3eea0c49872a75d384e94ee0b4380caf440e0
+Author: jaybeepee <jason.penton at gmail.com>
+Date: Fri Sep 11 13:38:37 2015 +0200
+
+ modules/tm: precent possible seg fault if branch reply is null
+
+ (cherry picked from commit aec9850491a8e8fa919396ae0e0f1d99d30c607c)
+
+commit 3ddf71b943530e98ba94ad9d9ec37be3a90e1182
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Sep 11 16:32:32 2015 +0200
+
+ mem/f_malloc: simplified free frags management
+
+ - avoid address referencing to previous free fragments, it can get
+ invalidated on joins
+ - straight doubly linked list also speeds join/defrag
+
+ (cherry picked from commit 2d0455d9f2266ad67867e03aa652863e37d5a8d2)
+
+commit 637e727484affa52489ff6d7bf2fe06fd6bb1085
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 15 13:09:36 2015 +0200
+
+ textopsx: include : in the value to be parsed as header name inside fixup_hname_param()
+
+ - reported by Björn Bylander
+
+ (cherry picked from commit 5f301c9e9b3d4b67a11aeaab45c21fd8d8929695)
+
+commit 0b20349c487f9a486db7407b3f712ca06531b9d1
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 15 13:08:53 2015 +0200
+
+ parse: more log messages in case of errors in parse_hname2_short()
+
+ (cherry picked from commit 3913cc881030cccc9518733e18363402f2dfb18e)
+
+commit 3763f689436b717b323d6d0337317ffc24d180a1
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 14 12:05:27 2015 +0200
+
+ dialog: mark slot as lock if dialog found in state deleted for spiral detection
+
+ (cherry picked from commit 6a9c892fd0a7a526ec6ced4b40479875477d96db)
+
+
+===================== 2015-09-10 Version 4.3.2 Released =====================
+
+===================== Changes Since Version 4.3.1 ===========================
+
+commit d1ca777a23c09965be7cbe3b9f686a4329c077ab
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 10 15:31:26 2015 +0200
+
+ Makefile.defs: version set to 4.3.2
+
+commit 9e7106f55019011defe438fa6fb1f9d0aa6567c0
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 10 14:01:11 2015 +0200
+
+ pkg/rpm: updated spec files for v4.3.2
+
+commit 648834a64d63aed64076dacf85ec5af1a5702333
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 10 12:22:48 2015 +0200
+
+ rls: proper detection of initial subscribe to send notify with full state
+
+ - use to-tag conditions, previously was sending only based on db mode
+ - reported by GH#276
+
+ (cherry picked from commit b99e9e96592a5d708ff565343f3c810b2d264577)
+
+commit 8487422d35ab8af7511e2abf3a38afb1328f4851
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 10 11:48:54 2015 +0200
+
+ evapi: increased the static buffer size used for reading evapi responses
+
+ - 32k instead of 4k
+
+ (cherry picked from commit c4fd9188263414d825815cfbd745ce5b1351e62e)
+
+commit 9bb179f72f7e4321a8f3a6e89685ee586d6cfa74
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 10 11:47:45 2015 +0200
+
+ cnxcc: fixed include guard
+
+ - reported by GH#323
+
+ (cherry picked from commit 3137d2ab8ec539c2059e59e0849ef7bdd7aa509b)
+
+commit a58c136c3abad48b2d01a4b54b1e56e0901b8246
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 10 09:24:01 2015 +0200
+
+ dialog: safety check not to store dialog vars and data when state initial
+
+ - acc callbacks for cdrs can trigger setting dialog vars in initial
+ state, which then try to save in db, however, initial state might not
+ have all required fields for a proper db reload, storing being
+ desinged to be done when all mandatory fields are set
+
+ (cherry picked from commit cecdd0817052046e634152d6e512165451b5f6d4)
+
+commit 061195f6d553bad5edfc30db5c8da28d74421519
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 10 00:21:14 2015 +0200
+
+ dialog: lock the slot if old dialog found in state deleted
+
+ - no longer a spiral condition and new dialog will be created
+
+ (cherry picked from commit 7f9194c416e171c2b723430eb98a55a52b7b5e38)
+
+commit 3fc2d2ceafa33153e9c046f192dc41baae14f3ec
+Author: Charles Chance <charles.chance at sipcentric.com>
+Date: Thu Sep 10 12:50:04 2015 +0100
+
+ dmq_usrloc: check existence of usrloc domain before continuing.
+
+commit 24b347a5fca61d13a0765dbf1b3c8207caf3b45d
+Author: Charles Chance <charles.chance at sipcentric.com>
+Date: Sat Aug 8 18:00:21 2015 +0100
+
+ dmq_usrloc: implement deleted contact replication
+
+ (cherry picked from commit edc25d7373f9560d09a35640ab19741f19b97040)
+
+commit bca48b913e6cc6900af7ec0683506ba8680470b6
+Author: Victor Seva <linuxmaniac at torreviejawireless.org>
+Date: Thu Sep 10 12:16:13 2015 +0200
+
+ pkg/kamailio/deb: update version to 4.3.2
+
+commit b0cab1484979a7d975b56bf8dcf0dbc2e3510732
+Author: Federico Cabiddu <federico.cabiddu at gmail.com>
+Date: Wed Sep 9 12:35:42 2015 +0200
+
+ tm: reset 'found' variable at the beginning of each cycle over the branches
+
+ (cherry picked from commit 5a442b219075c18a7e3a5b0942f34d05d8baba60)
+
+commit 262d3574790ea3a10c82cb8bc0e4a65429f25540
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 8 17:28:40 2015 +0200
+
+ parser: fix start of search for long header names
+
+ - in parse_hname2_short(), used only for mod fixups, in the case header
+ name given as function param was greater than 250 chars
+
+ (cherry picked from commit de8ba3900d6fef42e99ca9568044c7aefa44a5ea)
+
+commit e8bec39d2650c7867ec325e80e7f2d1b46d5684c
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 8 15:09:13 2015 +0200
+
+ modules: refreshed several readme files
+
+commit c46d065a9ef9f63207811e629120ef5cf8a44dbf
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 7 16:35:10 2015 +0200
+
+ tm: enable drop in onsend_route for tm replies
+
+ - skip sending out the reply by resetting the send_socket
+
+ (cherry picked from commit 4b2d6dd7ce1a61c964f7d996c2db4428010dd478)
+
+commit ed292c774f93a14123521094fcab4cf2da0620cd
+Author: Lucian Balaceanu <lucian.balaceanu at 1and1.ro>
+Date: Mon Sep 7 16:31:11 2015 +0200
+
+ tm: execute the onsend_route for responses forwarded by tm module
+
+ - not executed for local generated sip responses
+
+ (cherry picked from commit 2690a8c314d23406649dceaadce7032690500a6e)
+
+commit dca8ff16753639b1f84cd60286142fbad88335c7
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Sep 7 15:56:45 2015 +0200
+
+ tm: store last received response code before running onreply_route
+
+ - otherwise an innapropriate cancel can happen if the current branch got
+ before an 1xx response, and the script writer enforces another reply
+ code with t_reply()
+ - reported by Thomas Sevestre, GH#315
+
+ (cherry picked from commit b7c588dff06030a82f305b210573be5bbc961cec)
+
+commit 970ef5b844c195ad07cda15027ba99516eae645a
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Sep 4 11:38:02 2015 +0200
+
+ dialog: more debug when storing vars in database
+
+ (cherry picked from commit 2962852bf706692bdbc9b51419dbdc2012f34e1b)
+
+commit 08bd04db6a71a1111e04adbbb85671544b1cd5f2
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Sep 4 10:47:15 2015 +0200
+
+ corex: log messages for memory status/summary rpc commands
+
+ (cherry picked from commit 014a62f7546675ffc198d1c169f6bd12b3bdd87d)
+
+commit 44948a6c7618639f1864de140e5afd4d41c541b7
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Sep 3 17:34:10 2015 +0200
+
+ usrloc: mi commands with aor caseness
+
+ - reported in GH#264
+
+ (cherry picked from commit a10d8b133edef697ec3bd40e5babd76dc881b2cb)
+
+commit 20231f4936b5f79bcb2e3f64985953888391e570
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 8 15:02:45 2015 +0200
+
+ auth: fixed improper whitespacing
+
+commit f02215971667f54c553e10593e370db8feb1aae9
+Author: vance-od <vance at ukr.net>
+Date: Thu Sep 3 11:43:37 2015 +0300
+
+ Update nonce.c
+
+ auth: fixed issue when during registration nonce expired, after backwards time shift
+ (cherry picked from commit 063e32a8fe81b2cfbaac0386e6b51446586e619a)
+
+commit 5f02824b9dd195a1a94ae0038d4c73aa1ea6da24
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 2 13:31:08 2015 +0200
+
+ textopsx: use safer function to parse header name in short buffer
+
+ (cherry picked from commit 2aa013d5fb992be98fc1ec90abdf0d67625ab724)
+
+commit 036c1d134e6c20e9e5e394b790abb6fd0fe47695
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 2 13:30:58 2015 +0200
+
+ textops: use safer function to parse header name in short buffer
+
+ (cherry picked from commit b62492e2e25984528e4cda7f96d7afee1425ceb3)
+
+commit 5d97276a2586c8c312b6c56542e9b440ef006c28
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 2 13:30:46 2015 +0200
+
+ pv: use safer function to parse header name in short buffer
+
+ (cherry picked from commit a9dc0f738f448676b8a92818d442ca7142147f9b)
+
+commit 5cc4184e64f300319a65ce7f951510222830fbd8
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 2 13:29:43 2015 +0200
+
+ core: select framework - use safer function to parse header name in short buffer
+
+ (cherry picked from commit baf90dba5c12158386e501e73daa266321d9de38)
+
+commit db279576832664b5dee2c432c35030047e9e7b6f
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 2 13:29:09 2015 +0200
+
+ parser: fixed the name for the new parse_hname2_short() function
+
+ (cherry picked from commit ac27d053ce0d9d9295f3ca8052a320e0c0b01699)
+
+commit 5425c257ff0726a310aced28282821a4e4b7911c
+Author: Chris Double <chris.double at double.co.nz>
+Date: Wed Sep 2 13:15:37 2015 +0200
+
+ parser: fix overflow access when parsing Reason header stored in short buffer
+
+ - it can happen for fixup functions from textops module having header
+ name as a parameter, with critical impact when using system malloc,
+ the internal pkg malloc does a roundup of the allocated space
+ - the issue is caused by the word (4 bytes) read step performed by
+ parse_hname2() - second 4-byte read in buffer "Reason:" exceeds the
+ size by 1
+ - added a safe read macro that reads 1, 2 or 3 bytes if the size of the
+ buffer is not big enough for a 4 bytes read
+
+ (cherry picked from commit 964ed0a5083413eb0a70bd8a952d5a91ee9e9883)
+
+commit 742f6fbba5b0d5d308ea0434311d811b5cb56e55
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 2 13:07:45 2015 +0200
+
+ parser: safer function to parse header name stored in short buffer
+
+ (cherry picked from commit cbc5034b26189371c2ffb80424414aa8b1b8dea5)
+
+commit b7aab8f4a019e21f03b3e3323af592bc4af5857c
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Sep 2 09:17:24 2015 +0200
+
+ tmx: err level replaced with info when getting t reply code pv
+
+ (cherry picked from commit aad248fc39279f84879929772e9306fc01473860)
+
+commit 46af0cfb7cc1fffb22e43ebd41f07fc95947f8e5
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 1 14:18:02 2015 +0200
+
+ drouting: notes about the format of duration attribute
+
+ (cherry picked from commit 711144a1fa3e1dfa540cc7ccd0ce1c14faeba42f)
+
+commit c979b991450052f6a77238aef391dd8bb3f13f32
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Sep 1 09:17:39 2015 +0200
+
+ tmrec: more details about duration format for time recurrences
+
+ (cherry picked from commit 81006ee1246b8f700ce9ce20814d4522780d7ceb)
+
+commit b5e95cb1e528cf619c467c58cefd851fc489e950
+Author: Matthias Wimmer <m at tthias.eu>
+Date: Sat Aug 29 01:03:34 2015 +0200
+
+ Small typo fix in config.
+
+ (cherry picked from commit aef62d8277be4699b9e79ef49542865a44857999)
+
+commit 3beb4e9f524956883e2260450ea3593dc553ec6c
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Aug 27 15:58:48 2015 +0200
+
+ jsonrpc-c: proper error handling for pipe cmd callback
+
+ - credits to Hugh Waite for spotting missing return
+ - free vars if already set when error handling is done
+
+ (cherry picked from commit ec0ba37b9f2b6c60303227ea0527d69896f2930e)
+
+commit de7eb56737ca57429dd6ffcb01907b11609318f1
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Aug 27 15:38:03 2015 +0200
+
+ mem: safety prev free checks for f_malloc extract operation
+
+ - following a report by Alex Balashov
+
+ (cherry picked from commit a620bfec37cdcdc5c5debcdfb5219b09464065fe)
+
+commit 9d6e5aae27954065f0e61e1995993c37bd4bec80
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Aug 26 19:07:11 2015 +0200
+
+ kamcmd: do binrpc read in non-strict mode
+
+ - reported by Dmitri Savolainen, GH#145
+
+ (cherry picked from commit 6b73ca89832e034239d6f17d41b825cfdc52424d)
+
+commit 23745567b8d640dfb9778f71e5a064c95423de5c
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Aug 26 19:06:43 2015 +0200
+
+ lib/binrpc: updated code for the new prototype of binrpc read function
+
+ (cherry picked from commit 9c105b13436c9eb3e61568e6f08050423da3e569)
+
+commit 4e8935a2c3bbf2acdf6c4ffef84d5937f017c4b1
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Aug 26 19:03:55 2015 +0200
+
+ ctl: internal mode to allow non-strict reading binrpc packets
+
+ - allow handling structs with simple values inside, some rpc responses
+ are not strictly build as per xmlrpc/jsonrpc specs
+
+ (cherry picked from commit 39ab16e4f0d24d70b7d1414df48af023b2018cf6)
+
+commit 05242f6db6edcf32705722dcd0d9d3e3cf7a8340
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Aug 26 15:16:13 2015 +0200
+
+ kamcmd: lower max size for socket name
+
+ - was set to 108 which is common for linux, but mac os x has it 104
+ - set to 100 now
+
+ (cherry picked from commit 3f4c63802194cb83ffb8124e5ae38f85ee315c28)
+
+commit ee3048e8685f54c35daff699ad64ce9ef5c71f8a
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Aug 26 15:09:17 2015 +0200
+
+ kamcmd: updated default server name references
+
+ (cherry picked from commit 8db5eb2b53320d84ded36c531a00f6dfbec27a75)
+
+commit ab950f753de8c0baecc51f66e2be0012b4afed37
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Aug 26 13:55:54 2015 +0200
+
+ usrloc: take in consideration aor case sensitive value for rpc commands
+
+ - reported by GH#264
+
+ (cherry picked from commit e319a22f80d425f39611857fddc1e948e76ebe87)
+
+commit eebcd2be7332331894ef5b9d32a4a9e126763f9a
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Aug 26 13:55:33 2015 +0200
+
+ registrar: propagate value of case_sensitive for aor to core
+
+ (cherry picked from commit acf0432cafdaa4b464f1069996e46d54ab0c22e4)
+
+commit 9e97b80abbfa78c78f7c5359cc9af3774f1647e5
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Aug 26 13:47:13 2015 +0200
+
+ core: keep info about aor being considered case sensitive or not
+
+ (cherry picked from commit 06e36989b2c5332b3ca377ec8098d8f2d953a5b6)
+
+commit bb0194aa9f0963cb77bb1275b8e0a4cae8f60909
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Aug 25 15:53:02 2015 +0200
+
+ jsonrpc-c: free pipe cmd for notifications
+
+ - fixes leak reported by GH#296
+
+ (cherry picked from commit 79459d3f87731309641794a2b881ee1cacc5e1f2)
+
+commit 3ce973b0c20be7230baaf2cb8d8713e7fce64a06
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Aug 25 14:28:17 2015 +0200
+
+ dialog: dlg var value stored as zero terminated string
+
+ - easier to use in std lib operations
+
+ (cherry picked from commit 0d9e4adb328dabaf2a34d926bc80e022bee65079)
+
+commit 063a9b2a7f6ba6fe60797faa1ebf9f9dd37d2062
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Aug 25 13:35:30 2015 +0200
+
+ dialog: set dlg var table as static and rename to avoid name conflicts
+
+ (cherry picked from commit cbc0c720e1c239296ff3842d701f75663bead6d9)
+
+commit a8c2c53b1175af7bd3c6020cc01e95174b2597e0
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Aug 24 09:28:29 2015 +0200
+
+ sanity: adjusted log messages for check_proxy_require()
+
+ (cherry picked from commit 0f479b5366fae4c5ad0c78e4c91661b7a421d5e8)
+
+commit fea0d0801a09aa7faac8efa6ae19de49db864aa2
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Sat Aug 22 13:47:47 2015 +0200
+
+ evapi: do cfg framework update on i/o events
+
+ (cherry picked from commit 4404f75cf194e8fd727c2ffaeeea41d2193decf6)
+
+commit 65d4dae702ccd16654fa22c66522516f99751e3e
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Sat Aug 22 09:44:12 2015 +0200
+
+ db_postgres: memset vars to 0 to avoid using invalid values inside db_postgres_new_connection()
+
+ - reported by mading087, GH#292
+
+ (cherry picked from commit a16c6108e1f6d1a3f6b6c962bbaaedf37e57a8d2)
+
+commit 60b2e3e3e66320446541ba92de239fc3f58bc79f
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Sat Aug 22 09:28:29 2015 +0200
+
+ sanity: commented priting require header on error level
+
+ (cherry picked from commit 9902ca145178498ff47092f0ecdd3bca6650c97c)
+
+commit 4d8a2b62928d1d974cdcded29458817527fc1273
+Author: Victor Seva <linuxmaniac at torreviejawireless.org>
+Date: Wed Aug 12 08:16:52 2015 +0200
+
+ kamcmd: support VERSION_NODATE and VERSION_DATE for reproducible builds
+
+ support added e03d1279f49709e0d320478fa1ff7c27161c30ed
+
+ Related: #60
+ (cherry picked from commit 19359772acf1cbd9dedb244c1fe327ec47b7dc9c)
+
+commit 50567658b491d70a95da50c428bbb73678e3c775
+Author: Jason Newman <jason at getweave.com>
+Date: Tue Aug 11 14:30:31 2015 -0600
+
+ janssonrpc-c: allow null json error property in rpc response
+
+ If the JSON RPC response contains an error property, check to see if it is a json_null or not before flagging the response as an error.
+
+ (cherry picked from commit 92ba30d66e9e6bb686410f362f2b6e8d669ed295)
+
+commit 23bca854d7e703efcc6f18ab1bd46c679ad04e12
+Author: Jason Newman <jason at getweave.com>
+Date: Mon Aug 10 17:20:26 2015 -0600
+
+ janssonrpc-c: correct jansson_get parameter order in examples
+
+ parameter order should be jansson_get(key/path, src, dst) and not jansson_get(src, key/path, dst)
+
+ (cherry picked from commit 3cefc76ade4046962962f112beafe939d5ff2ed0)
+
+commit fb9a01616b407065c318ba204889507d5e4d026b
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Aug 7 10:36:50 2015 +0200
+
+ drouting: fixed typo in reload cmd response
+
+ - reported by GH#275
+
+ (cherry picked from commit 6b15a51b016c232fab6665fc03ed01dad09ac8b5)
+
+commit 1090e83918c78c5c81b3d6c5d080e3b86c9ae402
+Author: qxork <fred at qxork.com>
+Date: Thu Aug 6 13:29:23 2015 -0400
+
+ etc: simple typo fixes in kamailio.cfg
+
+ - fixed small typos within comments of default kamailio config
+
+ (cherry picked from commit 49420bac12faf27ce4b7ae6a869741f41e6a6553)
+
+commit c2595a2e5b8818fa7cddc916ef91b6b433fcd920
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Jul 31 18:39:41 2015 +0200
+
+ registrar: updated the docs for registered(...) function
+
+ (cherry picked from commit b0a776b31220fc5e8599288b14ddb9ffccb24c0f)
+
+commit 0b04d1526dfdf9490f407b8a00ab42a5e35cbb74
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Jul 31 18:35:55 2015 +0200
+
+ registrar: allow registered() in any route
+
+ - if used for a sip reply and URI is not provided, then To URI is used
+
+ (cherry picked from commit c3755580f8e2763e33be03b0370630d04af3a019)
+
+commit d88f52cadb2bf6764518c89be852b0534731d82e
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Thu Jul 30 20:54:56 2015 +0200
+
+ pua: fix typo in matching presence.winfo
+
+ - patch by foucse, GH #270
+
+ (cherry picked from commit 48f89ed0390a80cc760da5a7ed41dd9c5c5ffc4d)
+
+commit da64e01eb401e3dd57fc4c7bc8161d9fa5319857
+Author: lazedo <luis.azedo at factorlusitano.com>
+Date: Fri Jul 31 14:06:29 2015 +0100
+
+ htable : fix $shtrecord(value) returned value
+
+ $shtrecord(value) does not return correct value when it is an integer
+ (cherry picked from commit c446840e0004f8cb9208c2a6f68774c4c788e5a8)
+
+commit 3742fe74e34eaed12c88107aad5d32355a7bc549
+Author: Victor Seva <linuxmaniac at torreviejawireless.org>
+Date: Thu Jul 30 16:01:25 2015 +0200
+
+ jsonrpc-c: fix crash at reconnect_cb if server was never connected
+
+ (cherry picked from commit 0588a7bc5f57c012b6c8d188860251f402af9be7)
+
+commit d13e418a34cae70e68c3bb50ee0cef6245569284
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Sat Jul 18 09:52:28 2015 +0200
+
+ lib/srdb1: dummy string for null values pointed to static buffer
+
+ - allow editing in upper layers, avoiding innaproriate access to a constant
+
+ (cherry picked from commit d83fee0a31f292af731269cbd361db39be0a4b9b)
+
+commit feaed39802a86b1701f3db4aff0e64bed9d1cd04
+Author: Charles Chance <charles.chance at sipcentric.com>
+Date: Mon Sep 7 13:02:02 2015 +0100
+
+ dmq_usrloc: check existence of usrloc domain before continuing.
+
+ - avoids crash caused by passing null pointer to get_urecord_by_ruid().
+ - eventually need to implement multi-domain replication but usrloc API needs enhancing first.
+
+commit b9e924a1068d85e90afbb17baf627fe2c8836b92
+Author: Federico Cabiddu <federico.cabiddu at gmail.com>
+Date: Fri Sep 4 15:48:56 2015 +0200
+
+ tm: removed history from t_append_branches.c
+
+ (cherry picked from commit 2de2b27d1fba15b0ca6e5472f43dfc869ccb41ee)
+
+commit 23e851e9bae21640153b57495929bd3fa0002617
+Author: Federico Cabiddu <federico.cabiddu at gmail.com>
+Date: Fri Sep 4 15:45:58 2015 +0200
+
+ tm: iterate over the destination set starting from 0
+
+ (cherry picked from commit 380712accd89ba1f520314f5caf3cded6d8253ea)
+
+commit 340c40ac4b282c57f20009e987aec26c5877d62e
+Author: Federico Cabiddu <federico.cabiddu at gmail.com>
+Date: Fri Sep 4 15:12:29 2015 +0200
+
+ tm: check all the outgoing branches when appending a new branch
+
+ (cherry picked from commit 27bed654dcc4e9dd543a7f2f92e2174478bf7f26)
+
+commit 4d1b658b2b380349b7d74fae7083661a18f04bf1
+Author: Chris Double <chris.double at double.co.nz>
+Date: Tue Sep 1 00:17:40 2015 +1200
+
+ tsilo: Fix transaction removal to update list head
+
+ - When transaction being removed is the head of the list,
+ correctly update the head to point to the next transaction.
+
+ (cherry picked from commit 6ce6803d57dabe287d7d6fa859e93c1df402d821)
+
+commit 4c24d4acbca4e5ec99b5de1dd5f29d2cdeae9e2b
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Aug 28 12:31:24 2015 +0200
+
+ geoip: set null termination to the field used for query
+
+ (cherry picked from commit ec2a72d75dc0a2c9c3d88361094fdda7a7477935)
+
+commit 558a65e48e6819140b409cf58a0340aa78b8c2cf
+Author: Carsten Bock <carsten at ng-voice.com>
+Date: Fri Aug 28 10:56:37 2015 +0200
+
+ utils: Fix buffer overflow; do not NULL-terminate HTTP result
+
+ Fix buffer overflow in the `write_function` that takes the resulting
+ data from libcurl. The function was trying to NULL terminate the
+ string, but this could result in overwriting the buffer by one byte
+ when size*nmemb == 1.
+ This also caused some memory corruptions, reported on sr-dev.
+
+ Reported by: Travis Cross <tc at traviscross.com>
+
+commit d495aafb98d3560c36b681dae21b671ce8b23e86
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Aug 25 16:12:51 2015 +0200
+
+ mi_datagram: free async handler when command completed
+
+ - reported by Torge Szczepanek, GH#298
+
+ (cherry picked from commit 374bfb1c467d6bf2a4cc143d22868c37143783bd)
+
+commit 48b4261dd6eb25e2898cac9412b13b46baacf79f
+Author: Federico Cabiddu <federico.cabiddu at gmail.com>
+Date: Tue Aug 25 07:26:19 2015 +0200
+
+ modules/dialog: make dialog context available in event route tm:local-request
+
+ (cherry picked from commit 5002f66a98b6104702c8c862e7335ff189e7b7d8)
+
+commit 48d78ce87e2f42bdc77e688a0f45ff725ea97de5
+Author: Camille Oudot <camille.oudot at orange.com>
+Date: Wed Aug 12 17:33:00 2015 +0200
+
+ auth: modify doc to reflect current implementation
+
+ (cherry picked from commit 0868ed0ef12e65c7790beeccf139b5fdc245efdb)
+
+commit 68a12663a7bb5b3822312e66e00c34780b031933
+Author: Stefan Mititelu <stefan.mititelu at 1and1.ro>
+Date: Tue Aug 11 15:31:02 2015 +0300
+
+ dtrie: Set child to NULL when run out of SHM
+
+ The stop condition in dtrie_delete is node==NULL. Suppose the case when there
+ is no SHM memory left when trying to dtrie_insert(). The memory gets freed
+ by shm_free() but the pointer still points to it. This leads to segfault when
+ dtrie_delete tries to access that memory zone, in the given case. GDB says:
+ "Cannot access memory at address 0x1130000001d"
+
+ (cherry picked from commit 60ffee9cf54ff362026497036935746c9dbe62e5)
+
+commit 084fb2db62b133eb528bb8682fc057001e64e91d
+Author: Camille Oudot <camille.oudot at orange.com>
+Date: Mon Aug 10 15:35:09 2015 +0200
+
+ rtpengine: regenerate README
+
+commit df5761a59bc4da1854b081f0e68e98f6392aee5d
+Author: Camille Oudot <camille.oudot at orange.com>
+Date: Mon Aug 10 15:24:27 2015 +0200
+
+ rtpengine: fix typo in documentation
+
+ (cherry picked from commit e8927be015b4034d252479ba6fede4b749a43eed)
+
+commit a2b8efe1c24a213ef6c4221a59af544a3873e9d2
+Author: Victor Seva <linuxmaniac at torreviejawireless.org>
+Date: Thu Aug 6 20:36:22 2015 +0200
+
+ registrar: get instance and ref_id when using msg
+
+ needed for check max_contacts properly if sip.instance exists
+ as contact parameter
+
+ See: #278
+ (cherry picked from commit 99ce64fc555cc0b6b0189d812c6156cb05fb2e1b)
+
+commit cb644d50f76c80f0f24b34e5adf8723d89aab636
+Author: Victor Seva <linuxmaniac at torreviejawireless.org>
+Date: Thu Aug 6 15:22:34 2015 +0200
+
+ Revert "pua_reginfo: use ul.get_urecord_by_ruid instead of ul.get_urecord"
+
+ This reverts commit 9a6d8d2bffe13b442ed5e880fb0dd2c6572c29e2.
+
+commit 4717b5bdf9701bbe39a315cfe9ea6cf57a2f4ebd
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Jul 29 12:16:40 2015 +0200
+
+ tm: readme regenerated
+
+commit 03faa73eff6c341b0f49989a11478ec0b92b611e
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Jul 29 12:16:23 2015 +0200
+
+ pv: readme regenerated
+
+commit 40a66072179da324859864af8caee654e5c143e5
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Wed Jul 29 12:15:59 2015 +0200
+
+ pipelimit: regenerated the readme
+
+commit 4c7e676cdec3213c27cc689bdb5e6bbb8a9ec1ea
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Jul 28 10:23:28 2015 +0200
+
+ tm: added note in docs for t_set_no_e2e_cancel_reason()
+
+ - it has to be used when processing the INVITE
+
+ (cherry picked from commit e5f472ca5d8d2e16adb8b5a5a316521a618c8d9f)
+
+commit 64028d658a788b74f6f9c71f2e2aa3b0b5a1c803
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Jul 28 10:02:03 2015 +0200
+
+ permissions: check if hash tables exist for address config functions
+
+ - reported by Olle E. Johansson, GH#248
+
+ (cherry picked from commit 6fcd35ba5bb71df680b89c2bafceccde0439b6f1)
+
+commit 5db29ed56f2a682861e34a455ae76e0d43b4ff4c
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Tue Jul 28 09:47:48 2015 +0200
+
+ permissions: safety check if hash tables exist for rpc dump commands
+
+ - reported by Olle E. Johansson, GH#248
+
+ (cherry picked from commit 56e41533cae52cf5f782064ed23393d2d18aff08)
+
+commit cb4f55b26f51a929b2db08373c1b97a95b8ad6a6
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Jul 27 18:57:53 2015 +0200
+
+ rr: fix detecting next strict router
+
+ - a regression after adding support for sip-outbound
+ - more verbose debug messages
+ - reported by Antonio Real, GH #267
+
+ (cherry picked from commit 0c42a848258d475f57ea25458bc75e55dcee948d)
+
+commit ff1d3f06840928aace36780ecbc898cd2e90ce0a
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Jul 27 12:01:03 2015 +0200
+
+ kamcmd: use NAME to build help message
+
+ (cherry picked from commit 7038d12dbb9c8db1b46c0874bfd8fce72d6e72ed)
+
+commit 5a0b8a4550df2de15e40b5d7e664322815a48aea
+Author: Victor Seva <linuxmaniac at torreviejawireless.org>
+Date: Mon Jul 20 20:36:28 2015 +0200
+
+ core: fix mips compilation
+
+ Patch from
+ http://anonscm.debian.org/cgit/pkg-voip/kamailio.git/tree/debian/patches/fix-mips.patch
+ by Dejan Latinovic <Dejan.Latinovic at imgtec.com>
+
+ (cherry picked from commit ed894111f6f15170f87336bfa73ec4e8fce1c7d1)
+
+commit fb2af6107a9c6cd3552fe0a95c699c30e4edad4c
+Author: Victor Seva <linuxmaniac at torreviejawireless.org>
+Date: Mon Jul 20 19:38:32 2015 +0200
+
+ kex: support VERSION_NODATE and VERSION_DATE for reproducible builds
+
+ support added e03d1279f49709e0d320478fa1ff7c27161c30ed
+
+ Related: #60
+ (cherry picked from commit 8f1fbd7b17440b1b7d87cbee5793ae9b1adebf90)
+
+commit c68a6dcad598130bc6894f1de5ef3b39eb789660
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Jul 27 18:24:09 2015 +0200
+
+ acc: note about setting acc flag for ACKs that should be recorded
+
+ (cherry picked from commit 6656d4459f0c7d4c1b7cb5d2b214201c5a587c5c)
+
+commit e5f8d6282eefbe4c8ad0b0309ac06ab468e9b1f2
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Jul 27 15:04:30 2015 +0200
+
+ uac: reset ongoing registration state if retry interval is exceeded
+
+ - cover the case of remote registration process stuck in ongoing state
+ for long time
+ - reported by Andy J Robinson, GH #255
+
+ (cherry picked from commit cfa6831f9a81988dc1844ba3e4e6048c12841606)
+
+commit aa91d8ba178624c08ffcbb6af55efa777f6ca640
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Jul 27 15:03:21 2015 +0200
+
+ tm: more verbose debug message when local transaction is completed
+
+ (cherry picked from commit 54fea03a078f8258d124a83443617c54bdbc2574)
+
+commit a18915e019ebcfa35805d3985383705028fbc00c
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Jul 27 13:42:33 2015 +0200
+
+ acc: use proper ack message struct for external engine accounting of ACK
+
+ - reported by Yasin Caner - GH #266
+
+ (cherry picked from commit 58acd28f620c4a4e6b9abb1b9a2dfa2d8556708c)
+
+commit 96ffc362f1acdf8ae22f833e3c9fb0e1a675e5d1
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Jul 27 12:07:38 2015 +0200
+
+ Makefile.defs: separate RUNBASEDIR from BASEDIR
+
+ - not sharing same purpose, a common value can still be forced via
+ DESTDIR
+
+ (cherry picked from commit 747c3284c6eb31fab3b143c4217c84aa29fb9ca5)
+
+commit bfdddc685d95377393a90bd911b333045c7feb38
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Mon Jul 27 10:23:39 2015 +0200
+
+ dispatcher: free parsed params at reload time
+
+ (cherry picked from commit fc53c424f4ab7454bfd1e644291906392fc495fa)
+
+commit 8ba3be202f70a90ea88cdaac47fd2a7f9a9ef4f4
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Jul 24 12:43:26 2015 +0200
+
+ siptrace: check if To header is parsed and available
+
+ - it is accessed and can lead to crash if not prepared
+ - reported by GH #263
+
+ (cherry picked from commit 93b297e16134b0e74cf83e3604da01355a52e700)
+
+commit ba7b0eaba0c14db6ea27190787aea25d30cfb2ca
+Author: Daniel-Constantin Mierla <miconda at gmail.com>
+Date: Fri Jul 24 12:30:58 2015 +0200
+
+ siptrace: safety check if db connection is set
+
+ - reported in GH #262
+
+ (cherry picked from commit 740cfa0ebed20ba7b5ae2cab1b25aa2f6cd83899)
+
+commit 5100ba7f3e15456d45b78444c415cefd36485921
+Author: Federico Cabiddu <federico.cabiddu at gmail.com>
+Date: Thu Jul 23 15:25:44 2015 +0200
+
+ modules/tm: cycle through all the uac while checking for already existing branches
+
+ (cherry picked from commit 96ac163139976e8a9dea0e7252c66294054281b4)
+
+
===================== 2015-07-20 Version 4.3.1 Released =====================
===================== Changes Since Version 4.3.0 ===========================
diff --git a/Makefile b/Makefile
index 2d28777..e89b8fc 100644
--- a/Makefile
+++ b/Makefile
@@ -997,9 +997,11 @@ install_initd_centos install-initd-centos:
-e "s#GROUP=kamailio#GROUP=$(NAME)#g" \
< pkg/kamailio/rpm/kamailio.default \
> /etc/default/$(NAME)
+ mkdir -p /var/run/$(NAME)
/usr/sbin/groupadd -r $(NAME)
/usr/sbin/useradd -r -g $(NAME) -s /bin/false -c "Kamailio Daemon" \
-d /var/run/$(NAME) $(NAME)
+ chown $(NAME):$(NAME) /var/run/$(NAME)
.PHONY: dbschema
dbschema:
diff --git a/Makefile.defs b/Makefile.defs
index 11d49a9..b225355 100644
--- a/Makefile.defs
+++ b/Makefile.defs
@@ -96,13 +96,13 @@ INSTALL_FLAVOUR=$(FLAVOUR)
# version number
VERSION = 4
PATCHLEVEL = 3
-SUBLEVEL = 1
+SUBLEVEL = 3
# memory manager switcher
# 0 - f_malloc (fast malloc)
# 1 - q_malloc (quick malloc)
# 2 - tlsf_malloc (O(1) malloc and free)
-MEMMNG ?= 0
+MEMMNG ?= 1
# memory debugger switcher
# 0 - off (no-debug mode)
# 1 - on (debug mode)
@@ -433,7 +433,8 @@ doxygen_dir=doc/doxygen
BASEDIR ?= $(DESTDIR)
basedir = $(BASEDIR)
-runbasedir = $(BASEDIR)
+RUNBASEDIR ?= $(DESTDIR)
+runbasedir = $(RUNBASEDIR)
# install location
PREFIX ?= $(LOCALBASE)
@@ -1317,12 +1318,13 @@ ifeq ($(CC_NAME), gcc)
CFLAGS= -mips2 $(CC_OPT) -funroll-loops $(PROFILE)
#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
+ CFLAGS+=-ftree-vectorize -fno-strict-overflow
+ # not supported on mips: -minline-all-stringops
else
#if gcc 4.0+
ifeq ($(CC_SHORTVER), 4.x)
- CFLAGS+=-minline-all-stringops -ftree-vectorize
+ CFLAGS+=-ftree-vectorize
+ # not supported on mips: -minline-all-stringops
else
#if gcc 3.4+
ifeq ($(CC_SHORTVER), 3.4)
@@ -1362,12 +1364,14 @@ ifeq ($(CC_NAME), gcc)
CFLAGS= -mips64 $(CC_OPT) -funroll-loops $(PROFILE)
#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
+ CFLAGS+=-ftree-vectorize -fno-strict-overflow
+ # not supported on mips: -minline-all-stringops
+
else
#if gcc 4.0+
ifeq ($(CC_SHORTVER), 4.x)
- CFLAGS+=-minline-all-stringops -ftree-vectorize
+ CFLAGS+=-ftree-vectorize
+ # not supported on mips: -minline-all-stringops
else
#if gcc 3.4+
ifeq ($(CC_SHORTVER), 3.4)
diff --git a/autover.h b/autover.h
index 54ca25e..347edbe 100644
--- a/autover.h
+++ b/autover.h
@@ -2,6 +2,6 @@
* DO NOT EDIT IT
*/
-#define REPO_VER "f38e67"
-#define REPO_HASH "f38e67"
+#define REPO_VER "e275bc"
+#define REPO_HASH "e275bc"
#define REPO_STATE ""
diff --git a/core_cmd.c b/core_cmd.c
index 966bcbf..21c1387 100644
--- a/core_cmd.c
+++ b/core_cmd.c
@@ -925,7 +925,7 @@ static void core_sockets_list(rpc_t* rpc, void* c)
rpc->struct_add(ha, "ss",
"address", ai->address_str.s);
rpc->struct_add(ha, "sss",
- "proto", si->port_no_str.s,
+ "port", si->port_no_str.s,
"mcast", si->flags & SI_IS_MCAST ? "yes" : "no",
"mhomed", si->flags & SI_IS_MHOMED ? "yes" : "no");
} else {
@@ -939,7 +939,7 @@ static void core_sockets_list(rpc_t* rpc, void* c)
rpc->struct_add(ha, "s",
"ipaddress", si->address_str.s);
rpc->struct_add(ha, "sss",
- "proto", si->port_no_str.s,
+ "port", si->port_no_str.s,
"mcast", si->flags & SI_IS_MCAST ? "yes" : "no",
"mhomed", si->flags & SI_IS_MHOMED ? "yes" : "no");
}
diff --git a/dset.c b/dset.c
index 46cc40d..314b2c5 100644
--- a/dset.c
+++ b/dset.c
@@ -893,3 +893,22 @@ int uri_restore_rcv_alias(str *uri, str *nuri, str *suri)
return 0;
}
+
+/* address of record (aor) management */
+
+/* address of record considered case sensitive
+ * - 0 = no; 1 = yes */
+static int aor_case_sensitive=0;
+
+int set_aor_case_sensitive(int mode)
+{
+ int r;
+ r = aor_case_sensitive;
+ aor_case_sensitive = mode;
+ return r;
+}
+
+int get_aor_case_sensitive(void)
+{
+ return aor_case_sensitive;
+}
diff --git a/dset.h b/dset.h
index 752450f..603b202 100644
--- a/dset.h
+++ b/dset.h
@@ -258,4 +258,8 @@ int uri_restore_rcv_alias(str *uri, str *nuri, str *suri);
int init_dst_set(void);
+int set_aor_case_sensitive(int mode);
+
+int get_aor_case_sensitive(void);
+
#endif /* _DSET_H */
diff --git a/etc/kamailio.cfg b/etc/kamailio.cfg
index 1190e80..7f5f3db 100644
--- a/etc/kamailio.cfg
+++ b/etc/kamailio.cfg
@@ -546,7 +546,7 @@ route[RELAY] {
# Per SIP request initial checks
route[REQINIT] {
#!ifdef WITH_ANTIFLOOD
- # flood dection from same IP and traffic ban for a while
+ # flood detection from same IP and traffic ban for a while
# be sure you exclude checking trusted peers, such as pstn gateways
# - local host excluded (e.g., loop to self)
if(src_ip!=myself) {
@@ -721,7 +721,7 @@ route[PRESENCE] {
return;
}
-# IP authorization and user uthentication
+# IP authorization and user authentication
route[AUTH] {
#!ifdef WITH_AUTH
@@ -771,7 +771,7 @@ route[NATDETECT] {
return;
}
-# RTPProxy control and singaling updates for NAT traversal
+# RTPProxy control and signaling updates for NAT traversal
route[NATMANAGE] {
#!ifdef WITH_NAT
if (is_request()) {
@@ -827,7 +827,7 @@ route[PSTN] {
#!ifdef WITH_PSTN
# check if PSTN GW IP is defined
if (strempty($sel(cfg_get.pstn.gw_ip))) {
- xlog("SCRIPT: PSTN rotuing enabled but pstn.gw_ip not defined\n");
+ xlog("SCRIPT: PSTN routing enabled but pstn.gw_ip not defined\n");
return;
}
@@ -884,7 +884,7 @@ route[TOVOICEMAIL] {
# check if VoiceMail server IP is defined
if (strempty($sel(cfg_get.voicemail.srv_ip))) {
- xlog("SCRIPT: VoiceMail rotuing enabled but IP not defined\n");
+ xlog("SCRIPT: VoiceMail routing enabled but IP not defined\n");
return;
}
if(is_method("INVITE")) {
diff --git a/lib/binrpc/binrpc_api.c b/lib/binrpc/binrpc_api.c
index 656b623..e67c589 100644
--- a/lib/binrpc/binrpc_api.c
+++ b/lib/binrpc/binrpc_api.c
@@ -815,7 +815,7 @@ int binrpc_print_response(struct binrpc_response_handle *resp_handle, char* fmt)
read_value:
val.name.s=0;
val.name.len=0;
- p=binrpc_read_record(&resp_handle->in_pkt, p, end, &val, &ret);
+ p=binrpc_read_record(&resp_handle->in_pkt, p, end, &val, 0, &ret);
if (ret<0){
if (fmt)
putchar('\n');
@@ -898,7 +898,7 @@ int binrpc_parse_response(struct binrpc_val** vals, int* val_count,
val.type = BINRPC_T_ALL;
val.name.s = 0;
val.name.len = 0;
- p = binrpc_read_record(&resp_handle->in_pkt, p, end, &val, &ret);
+ p = binrpc_read_record(&resp_handle->in_pkt, p, end, &val, 0, &ret);
if (ret<0){
if (ret==E_BINRPC_EOP){
break;
@@ -982,7 +982,7 @@ int binrpc_parse_error_response(
val.type=BINRPC_T_INT;
val.name.s=0;
val.name.len=0;
- p = binrpc_read_record(&resp_handle->in_pkt, p, end, &val, &ret);
+ p = binrpc_read_record(&resp_handle->in_pkt, p, end, &val, 0, &ret);
if (ret < 0) {
snprintf(binrpc_last_errs, sizeof(binrpc_last_errs)-1,
"parse_error_response: error when parsing reply (code): %s", binrpc_error(ret)
@@ -992,7 +992,7 @@ int binrpc_parse_error_response(
*err_no = val.u.intval;
val.type=BINRPC_T_STR;
- p = binrpc_read_record(&resp_handle->in_pkt, p, end, &val, &ret);
+ p = binrpc_read_record(&resp_handle->in_pkt, p, end, &val, 0, &ret);
if (ret < 0) {
snprintf(binrpc_last_errs, sizeof(binrpc_last_errs)-1,
"parse_error_response: error when parsing reply (str): %s", binrpc_error(ret)
@@ -1170,7 +1170,7 @@ int binrpc_response_to_text(
val.type=BINRPC_T_ALL;
val.name.s=0;
val.name.len=0;
- p = binrpc_read_record(&resp_handle->in_pkt, p, end, &val, &ret);
+ p = binrpc_read_record(&resp_handle->in_pkt, p, end, &val, 0, &ret);
if (ret < 0) {
if (ret == E_BINRPC_EOP) {
printf("end of message detected\n");
diff --git a/lib/srdb1/db.c b/lib/srdb1/db.c
index e7323e3..fda8f9e 100644
--- a/lib/srdb1/db.c
+++ b/lib/srdb1/db.c
@@ -199,6 +199,10 @@ int db_bind_mod(const str* mod, db_func_t* mydbf)
tmp = name;
}
+ if (!find_module_by_name(tmp)) {
+ LM_ERR("Module %s not found. Missing loadmodule? \n", tmp);
+ goto error;
+ }
dbind = (db_bind_api_f)find_mod_export(tmp, "db_bind_api", 0, 0);
if(dbind != NULL)
{
diff --git a/lib/srdb1/db_val.c b/lib/srdb1/db_val.c
index 4a1b0a7..67f52a7 100644
--- a/lib/srdb1/db_val.c
+++ b/lib/srdb1/db_val.c
@@ -44,6 +44,7 @@ int db_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l,
const unsigned int _cpy)
{
static str dummy_string = {"", 0};
+ static char dummy_string_buf[2];
if (!_v) {
LM_ERR("invalid parameter value\n");
@@ -57,6 +58,8 @@ int db_str2val(const db_type_t _t, db_val_t* _v, const char* _s, const int _l,
* string so that we do not crash when the NULL flag
* is set but the module does not check it properly
*/
+ dummy_string_buf[0] = '\0';
+ dummy_string.s = dummy_string_buf;
VAL_STRING(_v) = dummy_string.s;
VAL_STR(_v) = dummy_string;
VAL_BLOB(_v) = dummy_string;
diff --git a/lib/trie/dtrie.c b/lib/trie/dtrie.c
index a57f85d..2883829 100644
--- a/lib/trie/dtrie.c
+++ b/lib/trie/dtrie.c
@@ -152,6 +152,7 @@ int dtrie_insert(struct dtrie_node_t *root, const char *number, const unsigned i
if(node->child[digit]->child == NULL){
SHM_MEM_ERROR;
shm_free(node->child[digit]);
+ node->child[digit] = NULL;
return -1;
}
LM_DBG("allocate %lu bytes for %d root children pointer at %p\n",
diff --git a/main.c b/main.c
index 1ff7f6a..acb8ce4 100644
--- a/main.c
+++ b/main.c
@@ -1793,6 +1793,7 @@ int main(int argc, char** argv)
int dont_fork_cnt;
struct name_lst* n_lst;
char *p;
+ struct stat st = {0};
/*init*/
time(&up_since);
@@ -2312,6 +2313,19 @@ try_again:
}
sock_gid = gid;
}
+ /* create runtime dir if doesn't exist */
+ if (stat(runtime_dir, &st) == -1) {
+ if(mkdir(runtime_dir, 0700) == -1) {
+ fprintf(stderr, "failed to create runtime dir\n");
+ goto error;
+ }
+ if(sock_uid!=-1 || sock_gid!=-1) {
+ if(chown(runtime_dir, sock_uid, sock_gid) == -1) {
+ fprintf(stderr, "failed to change owner of runtime dir\n");
+ goto error;
+ }
+ }
+ }
if (fix_all_socket_lists()!=0){
fprintf(stderr, "failed to initialize list addresses\n");
goto error;
diff --git a/mem/f_malloc.c b/mem/f_malloc.c
index fa8cb49..cac914f 100644
--- a/mem/f_malloc.c
+++ b/mem/f_malloc.c
@@ -91,6 +91,7 @@
((qm)->free_bitmap[(b)/FM_HASH_BMP_BITS] & (1UL<<((b)%FM_HASH_BMP_BITS)))
+#define fm_is_free(f) ((f)->is_free)
/**
* \brief Find the first free fragment in a memory block
@@ -158,12 +159,10 @@ inline static int fm_bmp_first_set(struct fm_block* qm, int start)
* \name Memory manager boundary check pattern
*/
/*@{ */
-#ifdef DBG_F_MALLOC
#define ST_CHECK_PATTERN 0xf0f0f0f0 /** inserted at the beginning */
#define END_CHECK_PATTERN1 0xc0c0c0c0 /** inserted at the end */
#define END_CHECK_PATTERN2 0xabcdefed /** inserted at the end */
/*@} */
-#endif
/**
@@ -173,15 +172,22 @@ inline static int fm_bmp_first_set(struct fm_block* qm, int start)
*/
static inline void fm_extract_free(struct fm_block* qm, struct fm_frag* frag)
{
- struct fm_frag** pf;
int hash;
- pf = frag->prv_free;
hash = GET_HASH(frag->size);
- *pf=frag->u.nxt_free;
+ if(frag->prev_free) {
+ frag->prev_free->next_free = frag->next_free;
+ } else {
+ qm->free_hash[hash].first = frag->next_free;
+ }
+ if(frag->next_free) {
+ frag->next_free->prev_free = frag->prev_free;
+ }
- if(frag->u.nxt_free) frag->u.nxt_free->prv_free = pf;
+ frag->prev_free = NULL;
+ frag->next_free = NULL;
+ frag->is_free = 0;
qm->ffrags--;
qm->free_hash[hash].no--;
@@ -189,7 +195,6 @@ static inline void fm_extract_free(struct fm_block* qm, struct fm_frag* frag)
if (qm->free_hash[hash].no==0)
fm_bmp_reset(qm, hash);
#endif /* F_MALLOC_HASH_BITMAP */
- frag->prv_free = NULL;
qm->real_used+=frag->size;
qm->used+=frag->size;
@@ -202,24 +207,42 @@ static inline void fm_extract_free(struct fm_block* qm, struct fm_frag* frag)
*/
static inline void fm_insert_free(struct fm_block* qm, struct fm_frag* frag)
{
- struct fm_frag** f;
+ struct fm_frag* f;
+ struct fm_frag* p;
int hash;
hash=GET_HASH(frag->size);
- f=&(qm->free_hash[hash].first);
+ f=qm->free_hash[hash].first;
+ p=NULL;
if (frag->size > F_MALLOC_OPTIMIZE){ /* because of '<=' in GET_HASH,
(different from 0.8.1[24] on
purpose --andrei ) */
- for(; *f; f=&((*f)->u.nxt_free)){
- if (frag->size <= (*f)->size) break;
+ /* large fragments list -- add at a position ordered by size */
+ for(; f; f=f->next_free){
+ if (frag->size <= f->size) break;
+ p = f;
}
- }
- /*insert it here*/
- frag->prv_free = f;
- frag->u.nxt_free=*f;
- if (*f) (*f)->prv_free = &(frag->u.nxt_free);
- *f=frag;
+ frag->next_free = f;
+ frag->prev_free = p;
+ if(f) {
+ f->prev_free = frag;
+ }
+ if(p) {
+ p->next_free = frag;
+ } else {
+ qm->free_hash[hash].first = frag;
+ }
+ } else {
+ /* fixed fragment size list -- add first */
+ frag->prev_free = 0;
+ frag->next_free = f;
+ if(f) {
+ f->prev_free = frag;
+ }
+ qm->free_hash[hash].first = frag;
+ }
+ frag->is_free = 1;
qm->ffrags++;
qm->free_hash[hash].no++;
#ifdef F_MALLOC_HASH_BITMAP
@@ -268,8 +291,8 @@ void fm_split_frag(struct fm_block* qm, struct fm_frag* frag,
n->file=file;
n->func="frag. from fm_split_frag";
n->line=line;
- n->check=ST_CHECK_PATTERN;
#endif
+ n->check=ST_CHECK_PATTERN;
/* reinsert n in free list*/
qm->used-=FRAG_OVERHEAD;
fm_insert_free(qm, n);
@@ -327,15 +350,17 @@ struct fm_block* fm_malloc_init(char* address, unsigned long size, int type)
qm->last_frag=(struct fm_frag*)(end-sizeof(struct fm_frag));
/* init first fragment*/
qm->first_frag->size=size;
- qm->first_frag->prv_free=0;
+ qm->first_frag->prev_free=0;
+ qm->first_frag->next_free=0;
+ qm->first_frag->is_free=0;
/* init last fragment*/
qm->last_frag->size=0;
- qm->last_frag->prv_free=0;
+ qm->last_frag->prev_free=0;
+ qm->last_frag->next_free=0;
+ qm->last_frag->is_free=0;
-#ifdef DBG_F_MALLOC
qm->first_frag->check=ST_CHECK_PATTERN;
qm->last_frag->check=END_CHECK_PATTERN1;
-#endif
/* link initial fragment into the free list*/
@@ -359,22 +384,23 @@ struct fm_frag* fm_search_defrag(struct fm_block* qm, unsigned long size)
while((char*)frag < (char*)qm->last_frag) {
nxt = FRAG_NEXT(frag);
- if ( ((char*)nxt < (char*)qm->last_frag) && frag->prv_free
- && nxt->prv_free) {
- /* join frag + nxt */
+ if ( ((char*)nxt < (char*)qm->last_frag) && fm_is_free(frag)
+ && fm_is_free(nxt)) {
+ /* join frag with all next consecutive free frags */
fm_extract_free(qm, frag);
do {
fm_extract_free(qm, nxt);
frag->size += nxt->size + FRAG_OVERHEAD;
- /* join - one frag less, add overhead to used */
+ /* after join - one frag less, add its overhead to used
+ * (real_used already has it - f and n were extracted */
qm->used += FRAG_OVERHEAD;
if( frag->size >size )
return frag;
nxt = FRAG_NEXT(frag);
- } while (((char*)nxt < (char*)qm->last_frag) && nxt->prv_free);
+ } while (((char*)nxt < (char*)qm->last_frag) && fm_is_free(nxt));
fm_insert_free(qm, frag);
}
@@ -399,7 +425,7 @@ void* fm_malloc(struct fm_block* qm, unsigned long size,
void* fm_malloc(struct fm_block* qm, unsigned long size)
#endif
{
- struct fm_frag** f;
+ struct fm_frag* f;
struct fm_frag* frag;
int hash;
@@ -418,8 +444,8 @@ void* fm_malloc(struct fm_block* qm, unsigned long size)
hash=fm_bmp_first_set(qm, GET_HASH(size));
if (likely(hash>=0)){
if (likely(hash<=F_MALLOC_OPTIMIZE/ROUNDTO)) { /* return first match */
- f=&(qm->free_hash[hash].first);
- if(likely(*f)) goto found;
+ f=qm->free_hash[hash].first;
+ if(likely(f)) goto found;
#ifdef DBG_F_MALLOC
MDBG(" block %p hash %d empty but no. is %lu\n", qm,
hash, qm->free_hash[hash].no);
@@ -437,17 +463,17 @@ void* fm_malloc(struct fm_block* qm, unsigned long size)
hash buckets.
*/
do {
- for(f=&(qm->free_hash[hash].first);(*f); f=&((*f)->u.nxt_free))
- if ((*f)->size>=size) goto found;
+ for(f=qm->free_hash[hash].first; f; f=f->next_free)
+ if (f->size>=size) goto found;
hash++; /* try in next hash cell */
}while((hash < F_HASH_SIZE) &&
((hash=fm_bmp_first_set(qm, hash)) >= 0));
}
#else /* F_MALLOC_HASH_BITMAP */
for(hash=GET_HASH(size);hash<F_HASH_SIZE;hash++){
- f=&(qm->free_hash[hash].first);
- for(;(*f); f=&((*f)->u.nxt_free))
- if ((*f)->size>=size) goto found;
+ f=qm->free_hash[hash].first;
+ for(; f; f=f->u.nxt_free)
+ if (f->size>=size) goto found;
/* try in a bigger bucket */
}
#endif /* F_MALLOC_HASH_BITMAP */
@@ -462,7 +488,7 @@ void* fm_malloc(struct fm_block* qm, unsigned long size)
found:
/* we found it!*/
/* detach it from the free list*/
- frag=*f;
+ frag=f;
fm_extract_free(qm, frag);
/*see if use full frag or split it in two*/
@@ -478,10 +504,10 @@ finish:
frag->file=file;
frag->func=func;
frag->line=line;
- frag->check=ST_CHECK_PATTERN;
MDBG("fm_malloc(%p, %lu) returns address %p \n", qm, size,
(char*)frag+sizeof(struct fm_frag));
#endif
+ frag->check=ST_CHECK_PATTERN;
if (qm->max_real_used<qm->real_used)
qm->max_real_used=qm->real_used;
@@ -495,40 +521,28 @@ finish:
#ifdef MEM_JOIN_FREE
/**
- * join fragment f with next one (if it is free)
+ * join fragment free frag f with next one (if it is free)
*/
static void fm_join_frag(struct fm_block* qm, struct fm_frag* f)
{
- int hash;
- struct fm_frag **pf;
- struct fm_frag* n;
+ struct fm_frag *n;
n=FRAG_NEXT(f);
- /* check if valid and if in free list */
- if (((char*)n >= (char*)qm->last_frag) || (n->prv_free==NULL))
+
+ /* check if n is valid and if in free list */
+ if (((char*)n >= (char*)qm->last_frag) || !fm_is_free(n))
return;
/* detach n from the free list */
- hash=GET_HASH(n->size);
- pf=n->prv_free;
- if (*pf==0){
- /* not found, bad! */
- LM_WARN("could not find %p in free list (hash=%ld)\n", n, GET_HASH(n->size));
- return;
- }
- /* detach */
- *pf=n->u.nxt_free;
- if(n->u.nxt_free) n->u.nxt_free->prv_free = pf;
- qm->ffrags--;
- qm->free_hash[hash].no--;
-#ifdef F_MALLOC_HASH_BITMAP
- if (qm->free_hash[hash].no==0)
- fm_bmp_reset(qm, hash);
-#endif /* F_MALLOC_HASH_BITMAP */
- /* join */
+ fm_extract_free(qm, n);
+
+ /* join - f extended with size of n plus its overhead */
f->size+=n->size+FRAG_OVERHEAD;
- qm->real_used+=n->size;
- qm->used+=n->size + FRAG_OVERHEAD;
+
+ /* after join - one frag less, add its overhead to used
+ * (real_used already has it - f and n were extracted */
+ qm->used += FRAG_OVERHEAD;
+
}
#endif /*MEM_JOIN_FREE*/
@@ -570,7 +584,7 @@ void fm_free(struct fm_block* qm, void* p)
MDBG("fm_free: freeing block alloc'ed from %s: %s(%ld)\n",
f->file, f->func, f->line);
#endif
- if(unlikely(f->prv_free!=NULL)) {
+ if(unlikely(fm_is_free(f))) {
LM_INFO("freeing a free fragment (%p/%p) - ignore\n",
f, p);
return;
@@ -659,11 +673,12 @@ void* fm_realloc(struct fm_block* qm, void* p, unsigned long size)
#endif
diff=size-f->size;
n=FRAG_NEXT(f);
+ /*if next frag is free, check if a join has enough size*/
if (((char*)n < (char*)qm->last_frag) &&
- (n->prv_free) && ((n->size+FRAG_OVERHEAD)>=diff)){
+ fm_is_free(n) && ((n->size+FRAG_OVERHEAD)>=diff)){
/* detach n from the free list */
fm_extract_free(qm, n);
- /* join */
+ /* join */
f->size+=n->size+FRAG_OVERHEAD;
qm->used+=FRAG_OVERHEAD;
@@ -761,7 +776,7 @@ void fm_status(struct fm_block* qm)
for(h=0,i=0,size=0;h<F_HASH_SIZE;h++){
unused=0;
for (f=qm->free_hash[h].first,j=0; f;
- size+=f->size,f=f->u.nxt_free,i++,j++){
+ size+=f->size,f=f->next_free,i++,j++){
if (!FRAG_WAS_USED(f)){
unused++;
#ifdef DBG_F_MALLOC
@@ -892,7 +907,7 @@ void fm_sums(struct fm_block* qm)
for (f=qm->first_frag, i=0; (char*)f<(char*)qm->last_frag;
f=FRAG_NEXT(f), i++){
- if (f->prv_free==0){
+ if (!fm_is_free(f)){
x = get_mem_counter(&root,f);
x->count++;
x->size+=f->size;
diff --git a/mem/f_malloc.h b/mem/f_malloc.h
index fef53cb..75e0cdf 100644
--- a/mem/f_malloc.h
+++ b/mem/f_malloc.h
@@ -80,18 +80,16 @@ typedef unsigned long fm_hash_bitmap_t;
* - +1 .... end - size = 2^k, big buckets
*/
struct fm_frag{
- unsigned long size;
- union{
- struct fm_frag* nxt_free;
- long reserved;
- }u;
- struct fm_frag** prv_free;
+ unsigned long size; /* size of fragment */
+ struct fm_frag* next_free; /* next free frag in slot */
+ struct fm_frag* prev_free; /* prev free frag in slot - for faster join/defrag */
+ unsigned int is_free; /* used to detect if fragment is free (when not 0) */
#ifdef DBG_F_MALLOC
const char* file;
const char* func;
unsigned long line;
- unsigned long check;
#endif
+ unsigned int check;
};
struct fm_frag_lnk{
diff --git a/modules/acc/README b/modules/acc/README
index 2c742ee..a019b0e 100644
--- a/modules/acc/README
+++ b/modules/acc/README
@@ -767,7 +767,8 @@ modparam("acc", "failed_filter", "404,407")
Shall acc attempt to account e2e ACKs too ? Note that this is really
only an attempt, as e2e ACKs may take a different path (unless RR
enabled) and mismatch original INVITE (e2e ACKs are a separate
- transaction).
+ transaction). The flag for accounting has to be set for each ACK as
+ well.
Default value is 0 (no).
diff --git a/modules/acc/acc_logic.c b/modules/acc/acc_logic.c
index bd3f1cc..16a97e5 100644
--- a/modules/acc/acc_logic.c
+++ b/modules/acc/acc_logic.c
@@ -615,7 +615,7 @@ static inline void acc_onack( struct cell* t, struct sip_msg *req,
#endif
/* run extra acc engines */
- acc_run_engines(req, 0, NULL);
+ acc_run_engines(ack, 0, NULL);
}
diff --git a/modules/acc/doc/acc_admin.xml b/modules/acc/doc/acc_admin.xml
index 820f480..fbe7dc3 100644
--- a/modules/acc/doc/acc_admin.xml
+++ b/modules/acc/doc/acc_admin.xml
@@ -559,7 +559,8 @@ modparam("acc", "failed_filter", "404,407")
Shall acc attempt to account e2e ACKs too ? Note that this is really
only an attempt, as e2e ACKs may take a different path
(unless RR enabled) and mismatch original INVITE (e2e ACKs are
- a separate transaction).
+ a separate transaction). The flag for accounting has to be set
+ for each ACK as well.
</para>
<para>
Default value is 0 (no).
diff --git a/modules/acc_radius/acc_radius_mod.c b/modules/acc_radius/acc_radius_mod.c
index b1843d6..f9327ad 100644
--- a/modules/acc_radius/acc_radius_mod.c
+++ b/modules/acc_radius/acc_radius_mod.c
@@ -1,6 +1,4 @@
/*
- * $Id$
- *
* Accounting module
*
* Copyright (C) 2001-2003 FhG Fokus
@@ -21,9 +19,6 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
- * History:
- * -------
- * 2010-07-28 - moved out radius account out of acc module (daniel)
*/
/*! \file
@@ -49,6 +44,7 @@
#include "../../lib/kcore/radius.h"
#include "../../modules/acc/acc_api.h"
#include "acc_radius_mod.h"
+#include "../../modules/acc/acc_extra.h"
MODULE_VERSION
@@ -129,7 +125,7 @@ static int mod_init( void )
LM_ERR("radius config file not set\n");
return -1;
}
-
+
/* bind the ACC API */
if (acc_load_api(&accb)<0) {
LM_ERR("cannot bind to ACC API\n");
@@ -141,7 +137,7 @@ static int mod_init( void )
LM_ERR("failed to parse rad_extra param\n");
return -1;
}
-
+
memset(&_acc_radius_engine, 0, sizeof(acc_engine_t));
if(radius_flag != -1)
@@ -196,7 +192,7 @@ static int acc_api_fixup(void** param, int param_no)
accp->reason.len = strlen(p);
/* any code? */
if (accp->reason.len>=3 && isdigit((int)p[0])
- && isdigit((int)p[1]) && isdigit((int)p[2]) ) {
+ && isdigit((int)p[1]) && isdigit((int)p[2]) ) {
accp->code = (p[0]-'0')*100 + (p[1]-'0')*10 + (p[2]-'0');
accp->code_s.s = p;
accp->code_s.len = 3;
@@ -233,7 +229,7 @@ enum { RA_ACCT_STATUS_TYPE=0, RA_SERVICE_TYPE, RA_SIP_RESPONSE_CODE,
enum {RV_STATUS_START=0, RV_STATUS_STOP, RV_STATUS_ALIVE, RV_STATUS_FAILED,
RV_SIP_SESSION, RV_STATIC_MAX};
static struct attr
- rd_attrs[RA_STATIC_MAX+ACC_CORE_LEN-2+MAX_ACC_EXTRA+MAX_ACC_LEG];
+ rd_attrs[RA_STATIC_MAX+ACC_CORE_LEN-2+MAX_ACC_EXTRA+MAX_ACC_LEG];
static struct val rd_vals[RV_STATIC_MAX];
int init_acc_rad(acc_extra_t *leg_info, char *rad_cfg, int srv_type)
@@ -297,30 +293,30 @@ int acc_radius_init(acc_init_info_t *inf)
static inline uint32_t rad_status( struct sip_msg *req, int code )
{
- str tag;
- unsigned int in_dialog_req = 0;
+ str tag;
+ unsigned int in_dialog_req = 0;
- tag = get_to(req)->tag_value;
- if(tag.s!=0 && tag.len!=0)
+ tag = get_to(req)->tag_value;
+ if(tag.s!=0 && tag.len!=0)
in_dialog_req = 1;
if (req->REQ_METHOD==METHOD_INVITE && in_dialog_req == 0
- && code>=200 && code<300)
- return rd_vals[RV_STATUS_START].v;
- if ((req->REQ_METHOD==METHOD_BYE || req->REQ_METHOD==METHOD_CANCEL))
- return rd_vals[RV_STATUS_STOP].v;
+ && code>=200 && code<300)
+ return rd_vals[RV_STATUS_START].v;
+ if ((req->REQ_METHOD==METHOD_BYE || req->REQ_METHOD==METHOD_CANCEL))
+ return rd_vals[RV_STATUS_STOP].v;
if (in_dialog_req != 0)
return rd_vals[RV_STATUS_ALIVE].v;
- return rd_vals[RV_STATUS_FAILED].v;
- }
+ return rd_vals[RV_STATUS_FAILED].v;
+}
#define ADD_RAD_AVPAIR(_attr,_val,_len) \
- do { \
- if (!rc_avpair_add(rh, &send, rd_attrs[_attr].v, _val, _len, 0)) { \
- LM_ERR("failed to add %s, %d\n", rd_attrs[_attr].n, _attr); \
- goto error; \
- } \
- }while(0)
+ do { \
+ if (!rc_avpair_add(rh, &send, rd_attrs[_attr].v, _val, _len, 0)) { \
+ LM_ERR("failed to add %s, %d\n", rd_attrs[_attr].n, _attr); \
+ goto error; \
+ } \
+ }while(0)
int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
{
@@ -329,6 +325,8 @@ int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
uint32_t av_type;
int offset;
int i;
+ int m=0;
+ int o=0;
send=NULL;
@@ -353,23 +351,26 @@ int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
ADD_RAD_AVPAIR( RA_TIME_STAMP, &av_type, -1);
/* add extra also */
- attr_cnt += accb.get_extra_attrs(rad_extra, req, inf->varr+attr_cnt,
- inf->iarr+attr_cnt, inf->tarr+attr_cnt);
+ o = accb.get_extra_attrs(rad_extra, req, inf->varr+attr_cnt,
+ inf->iarr+attr_cnt, inf->tarr+attr_cnt);
+ attr_cnt += o;
+ m = attr_cnt;
+
/* add the values for the vector - start from 1 instead of
* 0 to skip the first value which is the METHOD as string */
offset = RA_STATIC_MAX-1;
for( i=1; i<attr_cnt; i++) {
- switch (inf->tarr[i]) {
- case TYPE_STR:
- ADD_RAD_AVPAIR(offset+i, inf->varr[i].s, inf->varr[i].len);
- break;
- case TYPE_INT:
- ADD_RAD_AVPAIR(offset+i, &(inf->iarr[i]), -1);
- break;
- default:
- break;
- }
+ switch (inf->tarr[i]) {
+ case TYPE_STR:
+ ADD_RAD_AVPAIR(offset+i, inf->varr[i].s, inf->varr[i].len);
+ break;
+ case TYPE_INT:
+ ADD_RAD_AVPAIR(offset+i, &(inf->iarr[i]), -1);
+ break;
+ default:
+ break;
+ }
}
/* call-legs attributes also get inserted */
@@ -380,7 +381,7 @@ int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
for (i=0; i<attr_cnt; i++)
ADD_RAD_AVPAIR( offset+i, inf->varr[i].s, inf->varr[i].len );
}while ( (attr_cnt=accb.get_leg_attrs(inf->leg_info,req,inf->varr,inf->iarr,
- inf->tarr, 0))!=0 );
+ inf->tarr, 0))!=0 );
}
if (rc_acct(rh, SIP_PORT, send)!=OK_RC) {
@@ -388,10 +389,14 @@ int acc_radius_send_request(struct sip_msg *req, acc_info_t *inf)
goto error;
}
rc_avpair_free(send);
+ /* free memory allocated by extra2strar */
+ free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m);
return 1;
error:
rc_avpair_free(send);
+ /* free memory allocated by extra2strar */
+ free_strar_mem( &(inf->tarr[m-o]), &(inf->varr[m-o]), o, m);
return -1;
}
diff --git a/modules/app_perl/app_perl_mod.c b/modules/app_perl/app_perl_mod.c
index 3089097..0560a7c 100644
--- a/modules/app_perl/app_perl_mod.c
+++ b/modules/app_perl/app_perl_mod.c
@@ -167,7 +167,7 @@ static mi_export_t mi_cmds[] = {
/*
* Module interface
*/
-struct module_exports exports = {
+struct module_exports _app_perl_exports = {
"app_perl",
RTLD_NOW | RTLD_GLOBAL,
cmds, /* Exported functions */
@@ -351,7 +351,7 @@ static int mod_init(void) {
struct timeval t1;
struct timeval t2;
- if(register_mi_mod(exports.name, mi_cmds)!=0)
+ if(register_mi_mod(_app_perl_exports.name, mi_cmds)!=0)
{
LM_ERR("failed to register MI commands\n");
return -1;
diff --git a/modules/async/async_mod.c b/modules/async/async_mod.c
index 8cd6fac..be0ee11 100644
--- a/modules/async/async_mod.c
+++ b/modules/async/async_mod.c
@@ -94,7 +94,7 @@ static int mod_init(void)
{
if (load_tm_api( &tmb ) == -1)
{
- LM_ERR("cannot load the TM-functions\n");
+ LM_ERR("cannot load the TM-functions. Missing TM module?\n");
return -1;
}
@@ -151,7 +151,7 @@ static int w_async_sleep(struct sip_msg* msg, char* sec, char* str2)
if(async_workers<=0)
{
- LM_ERR("no async mod timer wokers\n");
+ LM_ERR("no async mod timer workers (modparam missing?)\n");
return -1;
}
@@ -188,7 +188,7 @@ static int fixup_async_sleep(void** param, int param_no)
ap = (async_param_t*)pkg_malloc(sizeof(async_param_t));
if(ap==NULL)
{
- LM_ERR("no more pkg\n");
+ LM_ERR("no more pkg memory available\n");
return -1;
}
memset(ap, 0, sizeof(async_param_t));
@@ -215,7 +215,7 @@ static int w_async_route(struct sip_msg* msg, char* rt, char* sec)
if(async_workers<=0)
{
- LM_ERR("no async mod timer wokers\n");
+ LM_ERR("no async mod timer workers\n");
return -1;
}
diff --git a/modules/async/async_sleep.c b/modules/async/async_sleep.c
index 8ed62e6..240b693 100644
--- a/modules/async/async_sleep.c
+++ b/modules/async/async_sleep.c
@@ -141,7 +141,7 @@ int async_sleep(struct sip_msg* msg, int seconds, cfg_action_t *act)
ai = (async_item_t*)shm_malloc(sizeof(async_item_t));
if(ai==NULL)
{
- LM_ERR("no more shm\n");
+ LM_ERR("no more shm memory\n");
return -1;
}
memset(ai, 0, sizeof(async_item_t));
@@ -149,7 +149,7 @@ int async_sleep(struct sip_msg* msg, int seconds, cfg_action_t *act)
ai->act = act;
if(tmb.t_suspend(msg, &ai->tindex, &ai->tlabel)<0)
{
- LM_ERR("failed to suppend the processing\n");
+ LM_ERR("failed to suspend the processing\n");
shm_free(ai);
return -1;
}
@@ -239,13 +239,13 @@ int async_send_task(sip_msg_t* msg, cfg_action_t *act)
at = (async_task_t*)shm_malloc(dsize);
if(at==NULL)
{
- LM_ERR("no more shm\n");
+ LM_ERR("no more shm memory\n");
return -1;
}
memset(at, 0, dsize);
if(tmb.t_suspend(msg, &tindex, &tlabel)<0)
{
- LM_ERR("failed to suppend the processing\n");
+ LM_ERR("failed to suspend the processing\n");
shm_free(at);
return -1;
}
diff --git a/modules/auth/README b/modules/auth/README
index ef54125..71b990a 100644
--- a/modules/auth/README
+++ b/modules/auth/README
@@ -15,46 +15,46 @@ Daniel-Constantin Mierla
asipto.com
<miconda at gmail.com>
- Copyright © 2002, 2003 FhG FOKUS
+ Copyright � 2002, 2003 FhG FOKUS
__________________________________________________________________
Table of Contents
1. Admin Guide
- 1.1. Overview
- 1.2. Dependencies
- 1.3. Parameters
-
- 1.3.1. auth_checks_register (flags)
- 1.3.2. auth_checks_no_dlg (flags)
- 1.3.3. auth_checks_in_dlg (flags)
- 1.3.4. qop (string)
- 1.3.5. nonce_count (boolean)
- 1.3.6. one_time_nonce (boolean)
- 1.3.7. nid_pool_no (integer)
- 1.3.8. nc_array_size (integer)
- 1.3.9. nc_array_order (integer)
- 1.3.10. otn_in_flight_no (integer)
- 1.3.11. otn_in_flight_order (integer)
- 1.3.12. secret (string)
- 1.3.13. nonce_expire (integer)
- 1.3.14. nonce_auth_max_drift (integer)
- 1.3.15. force_stateless_reply (boolean)
- 1.3.16. realm_prefix (string)
- 1.3.17. use_domain (boolean)
-
- 1.4. Functions
-
- 1.4.1. consume_credentials()
- 1.4.2. has_credentials(realm)
- 1.4.3. www_challenge(realm, flags)
- 1.4.4. proxy_challenge(realm, flags)
- 1.4.5. auth_challenge(realm, flags)
- 1.4.6. pv_www_authenticate(realm, passwd, flags [, method])
- 1.4.7. pv_proxy_authenticate(realm, passwd, flags)
- 1.4.8. pv_auth_check(realm, passwd, flags, checks)
- 1.4.9. auth_get_www_authenticate(realm, flags, pvdest)
+ 1. Overview
+ 2. Dependencies
+ 3. Parameters
+
+ 3.1. auth_checks_register (flags)
+ 3.2. auth_checks_no_dlg (flags)
+ 3.3. auth_checks_in_dlg (flags)
+ 3.4. qop (string)
+ 3.5. nonce_count (boolean)
+ 3.6. one_time_nonce (boolean)
+ 3.7. nid_pool_no (integer)
+ 3.8. nc_array_size (integer)
+ 3.9. nc_array_order (integer)
+ 3.10. otn_in_flight_no (integer)
+ 3.11. otn_in_flight_order (integer)
+ 3.12. secret (string)
+ 3.13. nonce_expire (integer)
+ 3.14. nonce_auth_max_drift (integer)
+ 3.15. force_stateless_reply (boolean)
+ 3.16. realm_prefix (string)
+ 3.17. use_domain (boolean)
+
+ 4. Functions
+
+ 4.1. consume_credentials()
+ 4.2. has_credentials(realm)
+ 4.3. www_challenge(realm, flags)
+ 4.4. proxy_challenge(realm, flags)
+ 4.5. auth_challenge(realm, flags)
+ 4.6. pv_www_authenticate(realm, passwd, flags [, method])
+ 4.7. pv_proxy_authenticate(realm, passwd, flags)
+ 4.8. pv_auth_check(realm, passwd, flags, checks)
+ 4.9. auth_get_www_authenticate(realm, flags, pvdest)
List of Examples
@@ -85,7 +85,43 @@ Daniel-Constantin Mierla
Chapter 1. Admin Guide
-1.1. Overview
+ Table of Contents
+
+ 1. Overview
+ 2. Dependencies
+ 3. Parameters
+
+ 3.1. auth_checks_register (flags)
+ 3.2. auth_checks_no_dlg (flags)
+ 3.3. auth_checks_in_dlg (flags)
+ 3.4. qop (string)
+ 3.5. nonce_count (boolean)
+ 3.6. one_time_nonce (boolean)
+ 3.7. nid_pool_no (integer)
+ 3.8. nc_array_size (integer)
+ 3.9. nc_array_order (integer)
+ 3.10. otn_in_flight_no (integer)
+ 3.11. otn_in_flight_order (integer)
+ 3.12. secret (string)
+ 3.13. nonce_expire (integer)
+ 3.14. nonce_auth_max_drift (integer)
+ 3.15. force_stateless_reply (boolean)
+ 3.16. realm_prefix (string)
+ 3.17. use_domain (boolean)
+
+ 4. Functions
+
+ 4.1. consume_credentials()
+ 4.2. has_credentials(realm)
+ 4.3. www_challenge(realm, flags)
+ 4.4. proxy_challenge(realm, flags)
+ 4.5. auth_challenge(realm, flags)
+ 4.6. pv_www_authenticate(realm, passwd, flags [, method])
+ 4.7. pv_proxy_authenticate(realm, passwd, flags)
+ 4.8. pv_auth_check(realm, passwd, flags, checks)
+ 4.9. auth_get_www_authenticate(realm, flags, pvdest)
+
+1. Overview
This is a generic module that itself doesn't provide all functions
necessary for authentication but provides functions that are needed by
@@ -99,21 +135,39 @@ Chapter 1. Admin Guide
functionality. This also allows us to avoid unnecessary dependencies in
the binary packages.
-1.2. Dependencies
+2. Dependencies
The module does not depend on any other module.
-1.3. Parameters
-
-1.3.1. auth_checks_register (flags)
+3. Parameters
+
+ 3.1. auth_checks_register (flags)
+ 3.2. auth_checks_no_dlg (flags)
+ 3.3. auth_checks_in_dlg (flags)
+ 3.4. qop (string)
+ 3.5. nonce_count (boolean)
+ 3.6. one_time_nonce (boolean)
+ 3.7. nid_pool_no (integer)
+ 3.8. nc_array_size (integer)
+ 3.9. nc_array_order (integer)
+ 3.10. otn_in_flight_no (integer)
+ 3.11. otn_in_flight_order (integer)
+ 3.12. secret (string)
+ 3.13. nonce_expire (integer)
+ 3.14. nonce_auth_max_drift (integer)
+ 3.15. force_stateless_reply (boolean)
+ 3.16. realm_prefix (string)
+ 3.17. use_domain (boolean)
+
+3.1. auth_checks_register (flags)
See description of parameter auth_checks_in_dlg.
-1.3.2. auth_checks_no_dlg (flags)
+3.2. auth_checks_no_dlg (flags)
See description of parameter auth_checks_in_dlg.
-1.3.3. auth_checks_in_dlg (flags)
+3.3. auth_checks_in_dlg (flags)
These three module parameters control which optional integrity checks
will be performed on the SIP message carrying digest response during
@@ -198,7 +252,7 @@ modparam("auth", "auth_checks_in_dlg", 15)
...
-1.3.4. qop (string)
+3.4. qop (string)
If set, enable qop for challenges: each challenge will include a qop
parameter. This is the recommended way, but some older non rfc3261
@@ -220,7 +274,7 @@ modparam("auth", "auth_checks_in_dlg", 15)
modparam("auth", "qop", "auth") # set qop=auth
...
-1.3.5. nonce_count (boolean)
+3.5. nonce_count (boolean)
If enabled the received nc value is remembered and checked against the
older value (for a successful authentication the received nc must be
@@ -316,7 +370,7 @@ route{
}
...
-1.3.6. one_time_nonce (boolean)
+3.6. one_time_nonce (boolean)
If set to 1 nonce reuse is disabled: each nonce is allowed only once,
in the first reponse to a challenge. All the messages will be
@@ -360,7 +414,7 @@ modparam("auth", "one_time_nonce", 1)
# Note: stateful mode should be used, see the nonce_count example
...
-1.3.7. nid_pool_no (integer)
+3.7. nid_pool_no (integer)
Controls the number of partitions for the nonce_count and
one_time_nonce arrays (it's common to both of them to reduce the nonce
@@ -396,7 +450,7 @@ modparam("auth", "one_time_nonce", 1)
modparam("auth", "nid_pool_no", 4)
...
-1.3.8. nc_array_size (integer)
+3.8. nc_array_size (integer)
Maximum number of in-flight nonces for nonce_count. It represents the
maximum nonces for which state will be kept. When this number is
@@ -420,7 +474,7 @@ modparam("auth", "nid_pool_no", 4)
modparam("auth", "nc_array_size", 4194304) # 4Mb
...
-1.3.9. nc_array_order (integer)
+3.9. nc_array_order (integer)
Equivalent to nc_array_size, but instead of directly specifying the
size, its value is the power at which 2 should be raised
@@ -437,7 +491,7 @@ modparam("auth", "nc_array_size", 4194304) # 4Mb
modparam("auth", "nc_array_order", 22) # 4Mb
...
-1.3.10. otn_in_flight_no (integer)
+3.10. otn_in_flight_no (integer)
Maximum number of in-flight nonces for one_time_nonce. It represents
the maximum number of nonces remembered for the one-time-nonce check.
@@ -463,7 +517,7 @@ modparam("auth", "nc_array_order", 22) # 4Mb
modparam("auth", "otn_in_flight_no", 8388608) # 8 Mb (1Mb memory)
...
-1.3.11. otn_in_flight_order (integer)
+3.11. otn_in_flight_order (integer)
Equivalent to otn_in_flight_no, but instead of directly specifying the
size, its value is the power at which 2 should be raised
@@ -481,7 +535,7 @@ modparam("auth", "otn_in_flight_no", 8388608) # 8 Mb (1Mb memory)
modparam("auth", "otn_in_flight_order", 23) # 8 Mb (1Mb memory)
...
-1.3.12. secret (string)
+3.12. secret (string)
Secret phrase used to calculate the nonce value used to challenge the
client for authentication.
@@ -501,7 +555,7 @@ modparam("auth", "otn_in_flight_order", 23) # 8 Mb (1Mb memory)
modparam("auth", "secret", "johndoessecretphrase")
...
-1.3.13. nonce_expire (integer)
+3.13. nonce_expire (integer)
Nonces have limited lifetime. After a given period of time nonces will
be considered invalid. This is to protect replay attacks. Credentials
@@ -518,7 +572,7 @@ modparam("auth", "secret", "johndoessecretphrase")
modparam("auth", "nonce_expire", 600) # Set nonce_expire to 600s
...
-1.3.14. nonce_auth_max_drift (integer)
+3.14. nonce_auth_max_drift (integer)
Maximum difference in seconds between a nonce creation time and the
current time, if the nonce creation time appears to be in the future.
@@ -540,7 +594,7 @@ modparam("auth", "nonce_expire", 600) # Set nonce_expire to 600s
modparam("auth", "nonce_auth_max_drift", 1) # set max drift to 1 s
...
-1.3.15. force_stateless_reply (boolean)
+3.15. force_stateless_reply (boolean)
If set to 1, www_challenge() and proxy_challenge() functions send reply
statelessly no matter if transaction exists or not. If set to 0
@@ -552,13 +606,13 @@ modparam("auth", "nonce_auth_max_drift", 1) # set max drift to 1 s
modparam("auth", "force_stateless_reply", 1)
...
-1.3.16. realm_prefix (string)
+3.16. realm_prefix (string)
Prefix to be automatically strip from realm. As an alternative to SRV
records (not all SIP clients support SRV lookup), a subdomain of the
master domain can be defined for SIP purposes (like sip.mydomain.net
pointing to same IP address as the SRV record for mydomain.net). By
- ignoring the realm_prefix “sip.”, at authentication, sip.mydomain.net
+ ignoring the realm_prefix "sip.", at authentication, sip.mydomain.net
will be equivalent to mydomain.net .
Default value is empty string.
@@ -566,7 +620,7 @@ modparam("auth", "force_stateless_reply", 1)
Example 1.14. realm_prefix parameter example
modparam("auth", "realm_prefix", "sip.")
-1.3.17. use_domain (boolean)
+3.17. use_domain (boolean)
If set to 1, pv_auth_check() uses domain parts of the URIs to check
user identity.
@@ -576,9 +630,19 @@ modparam("auth", "realm_prefix", "sip.")
modparam("auth", "use_domain", 1)
...
-1.4. Functions
+4. Functions
-1.4.1. consume_credentials()
+ 4.1. consume_credentials()
+ 4.2. has_credentials(realm)
+ 4.3. www_challenge(realm, flags)
+ 4.4. proxy_challenge(realm, flags)
+ 4.5. auth_challenge(realm, flags)
+ 4.6. pv_www_authenticate(realm, passwd, flags [, method])
+ 4.7. pv_proxy_authenticate(realm, passwd, flags)
+ 4.8. pv_auth_check(realm, passwd, flags, checks)
+ 4.9. auth_get_www_authenticate(realm, flags, pvdest)
+
+4.1. consume_credentials()
This function removes previously authorized credential headers from the
message being processed by the server. That means that the downstream
@@ -595,7 +659,7 @@ if (www_authenticate("realm", "subscriber")) {
};
...
-1.4.2. has_credentials(realm)
+4.2. has_credentials(realm)
This function returns true of the request has Autorization or
Proxy-Authorization header with provided realm. The parameter can be
@@ -608,7 +672,7 @@ if (has_credentials("myrealm")) {
}
...
-1.4.3. www_challenge(realm, flags)
+4.3. www_challenge(realm, flags)
The function challenges a user agent. It will generate a WWW-Authorize
header field containing a digest challenge, it will put the header
@@ -622,7 +686,7 @@ if (has_credentials("myrealm")) {
* realm - Realm is a opaque string that the user agent should present
to the user so he can decide what username and password to use.
Usually this is domain of the host the server is running on.
- It must not be empty string “”. In case of REGISTER requests, the
+ It must not be empty string "". In case of REGISTER requests, the
To header field domain (e.g., variable $td) can be used (because
this header field represents the user being registered), for all
other messages From header field domain can be used (e.g., variable
@@ -645,7 +709,7 @@ if (!www_authenticate("$td", "subscriber")) {
}
...
-1.4.4. proxy_challenge(realm, flags)
+4.4. proxy_challenge(realm, flags)
The function challenges a user agent. It will generate a
Proxy-Authorize header field containing a digest challenge, it will put
@@ -667,7 +731,7 @@ if (!proxy_authenticate("$fd", "subscriber")) {
};
...
-1.4.5. auth_challenge(realm, flags)
+4.5. auth_challenge(realm, flags)
The function challenges a user agent for authentication. It combines
the functions www_challenge() and proxy_challenge(), by calling
@@ -686,7 +750,7 @@ if (!auth_check("$fd", "subscriber", "1")) {
};
...
-1.4.6. pv_www_authenticate(realm, passwd, flags [, method])
+4.6. pv_www_authenticate(realm, passwd, flags [, method])
The function verifies credentials according to RFC2617. If the
credentials are verified successfully then the function will succeed
@@ -699,20 +763,17 @@ if (!auth_check("$fd", "subscriber", "1")) {
* -1 (generic error) - some generic error occurred and no reply was
sent out
* -2 (invalid password) - wrong password
- * -3 (invalid user) - authentication user does not exist
* -4 (nonce expired) - the nonce has expired
* -5 (no credentials) - request does not contain an Authorization
header with the correct realm
* -6 (nonce reused) - the nonce has already been used to authenticate
a previous request
- * -8 (auth user mismatch) - the auth user is different then the
- From/To user
Meaning of the parameters is as follows:
* realm - Realm is a opaque string that the user agent should present
to the user so he can decide what username and password to use.
Usually this is domain of the host the server is running on.
- It must not be empty string “”. In case of REGISTER requests To
+ It must not be empty string "". In case of REGISTER requests To
header field domain (e.g., varibale $td) can be used (because this
header field represents a user being registered), for all other
messages From header field domain can be used (e.g., varibale $fd).
@@ -741,7 +802,7 @@ if (!pv_www_authenticate("$td", "123abc", "0")) {
};
...
-1.4.7. pv_proxy_authenticate(realm, passwd, flags)
+4.7. pv_proxy_authenticate(realm, passwd, flags)
The function verifies credentials according to RFC2617. If the
credentials are verified successfully then the function will succeed
@@ -764,7 +825,7 @@ if (!pv_proxy_authenticate("$fd", "$avp(password)", "0")) {
};
...
-1.4.8. pv_auth_check(realm, passwd, flags, checks)
+4.8. pv_auth_check(realm, passwd, flags, checks)
The function combines the functionalities of pv_www_authenticate and
pv_proxy_authenticate, first being exectuted if the SIP request is a
@@ -779,6 +840,12 @@ if (!pv_proxy_authenticate("$fd", "$avp(password)", "0")) {
it is for a REGISTER request or not. The parameter may be a pseudo
variable.
+ The set of possible return codes is the same than
+ pv_{www,proxy}_authenticate, with one more possible value:
+
+ -8 (auth user mismatch) - the auth user is different than the From/To
+ user
+
This function can be used from REQUEST_ROUTE.
Example 1.23. pv_auth_check usage
@@ -789,7 +856,7 @@ if (!pv_auth_check("$fd", "$avp(password)", "0", "1")) {
};
...
-1.4.9. auth_get_www_authenticate(realm, flags, pvdest)
+4.9. auth_get_www_authenticate(realm, flags, pvdest)
Build WWW-Authentication header and set the resulting value in 'pvdest'
pseudo-variable parameter.
diff --git a/modules/auth/doc/auth_functions.xml b/modules/auth/doc/auth_functions.xml
index ec33324..225dbb3 100644
--- a/modules/auth/doc/auth_functions.xml
+++ b/modules/auth/doc/auth_functions.xml
@@ -204,10 +204,6 @@ if (!auth_check("$fd", "subscriber", "1")) {
<emphasis>-2 (invalid password)</emphasis> - wrong password
</para></listitem>
<listitem><para>
- <emphasis>-3 (invalid user)</emphasis> - authentication user does
- not exist
- </para></listitem>
- <listitem><para>
<emphasis>-4 (nonce expired)</emphasis> - the nonce has expired
</para></listitem>
<listitem><para>
@@ -218,10 +214,6 @@ if (!auth_check("$fd", "subscriber", "1")) {
<emphasis>-6 (nonce reused)</emphasis> - the nonce has already been
used to authenticate a previous request
</para></listitem>
- <listitem><para>
- <emphasis>-8 (auth user mismatch)</emphasis> - the auth user is different
- then the From/To user
- </para></listitem>
</itemizedlist>
<para>Meaning of the parameters is as follows:</para>
<itemizedlist>
@@ -357,6 +349,13 @@ if (!pv_proxy_authenticate("$fd", "$avp(password)", "0")) {
request or not. The parameter may be a pseudo variable.
</para>
<para>
+ The set of possible return codes is the same than pv_{www,proxy}_authenticate, with
+ one more possible value:
+ <para><emphasis>-8 (auth user mismatch)</emphasis> - the auth user is different
+ than the From/To user
+ </para>
+ </para>
+ <para>
This function can be used from REQUEST_ROUTE.
</para>
<example>
diff --git a/modules/auth/nonce.c b/modules/auth/nonce.c
index 95b967e..d65d9cd 100644
--- a/modules/auth/nonce.c
+++ b/modules/auth/nonce.c
@@ -357,7 +357,13 @@ int check_nonce(auth_body_t* auth, str* secret1, str* secret2,
different length (for example because of different auth.
checks).. Therefore we force credentials to be rebuilt by UAC
without prompting for password */
- return 4;
+ /* if current time is less than start time, reset the start time
+ * (e.g., after start, the system clock was set in the past) */
+ t=time(0);
+ if (t < up_since)
+ up_since = t;
+ if (since < t)
+ return 4;
}
t=time(0);
if (unlikely((since > t) && ((since-t) > nonce_auth_max_drift) )){
diff --git a/modules/auth_db/authorize.c b/modules/auth_db/authorize.c
index 6d582c2..86e1cb7 100644
--- a/modules/auth_db/authorize.c
+++ b/modules/auth_db/authorize.c
@@ -512,30 +512,40 @@ int auth_check(struct sip_msg* _m, char* _realm, char* _table, char *_flags)
|| _m->REQ_METHOD==METHOD_PRACK || _m->REQ_METHOD==METHOD_UPDATE
|| _m->REQ_METHOD==METHOD_MESSAGE))) {
if(srealm.len!=uri->user.len
- || strncmp(srealm.s, uri->user.s, srealm.len)!=0)
+ || strncmp(srealm.s, uri->user.s, srealm.len)!=0) {
+ LM_DBG("authentication username mismatch with from/to username\n");
return AUTH_USER_MISMATCH;
+ }
}
if(_m->REQ_METHOD==METHOD_REGISTER || _m->REQ_METHOD==METHOD_PUBLISH) {
/* check from==to */
if(furi->user.len!=turi->user.len
- || strncmp(furi->user.s, turi->user.s, furi->user.len)!=0)
+ || strncmp(furi->user.s, turi->user.s, furi->user.len)!=0) {
+ LM_DBG("from username mismatch with to username\n");
return AUTH_USER_MISMATCH;
+ }
if(use_domain!=0 && (furi->host.len!=turi->host.len
- || strncmp(furi->host.s, turi->host.s, furi->host.len)!=0))
+ || strncmp(furi->host.s, turi->host.s, furi->host.len)!=0)) {
+ LM_DBG("from domain mismatch with to domain\n");
return AUTH_USER_MISMATCH;
+ }
/* check r-uri==from for publish */
if(_m->REQ_METHOD==METHOD_PUBLISH) {
if(parse_sip_msg_uri(_m)<0)
return AUTH_ERROR;
uri = &_m->parsed_uri;
if(furi->user.len!=uri->user.len
- || strncmp(furi->user.s, uri->user.s, furi->user.len)!=0)
+ || strncmp(furi->user.s, uri->user.s, furi->user.len)!=0) {
+ LM_DBG("from username mismatch with r-uri username\n");
return AUTH_USER_MISMATCH;
+ }
if(use_domain!=0 && (furi->host.len!=uri->host.len
- || strncmp(furi->host.s, uri->host.s, furi->host.len)!=0))
+ || strncmp(furi->host.s, uri->host.s, furi->host.len)!=0)) {
+ LM_DBG("from domain mismatch with r-uri domain\n");
return AUTH_USER_MISMATCH;
}
+ }
}
return AUTH_OK;
}
diff --git a/modules/cnxcc/cnxcc_mod.c b/modules/cnxcc/cnxcc_mod.c
index 2c7f03e..21242f4 100644
--- a/modules/cnxcc/cnxcc_mod.c
+++ b/modules/cnxcc/cnxcc_mod.c
@@ -118,7 +118,7 @@ static int __add_call_by_cid(str *cid, call_t *call, credit_type_t type);
static call_t *__alloc_new_call_by_time(credit_data_t *credit_data, struct sip_msg *msg, int max_secs);
static call_t *__alloc_new_call_by_money(credit_data_t *credit_data, struct sip_msg *msg, double credit,
double cost_per_second, int initial_pulse, int final_pulse);
-static void __notify_call_termination(sip_data_t *data);
+static void __notify_call_termination(sip_msg_t *msg);
static void __free_call(call_t *call);
static int __has_to_tag(struct sip_msg *msg);
static credit_data_t *__alloc_new_credit_data(str *client_id, credit_type_t type);
@@ -454,18 +454,8 @@ static void __dialog_terminated_callback(struct dlg_cell *cell, int type, struct
__stop_billing(&cell->callid);
}
-static void __notify_call_termination(sip_data_t *data) {
+static void __notify_call_termination(sip_msg_t *msg) {
struct run_act_ctx ra_ctx;
- struct sip_msg *msg;
-
- if (_data.cs_route_number < 0)
- return;
-
- if (faked_msg_init_with_dlg_info(&data->callid, &data->from_uri, &data->from_tag,
- &data->to_uri, &data->to_tag, &msg) != 0) {
- LM_ERR("[%.*s]: error generating faked sip message\n", data->callid.len, data->callid.s);
- return;
- }
init_run_actions_ctx(&ra_ctx);
//run_top_route(event_rt.rlist[_data.cs_route_number], msg, &ra_ctx);
@@ -958,6 +948,9 @@ static int __shm_str_hash_alloc(struct str_hash_table *ht, int size) {
}
int terminate_call(call_t *call) {
+ sip_msg_t *dmsg = NULL;
+ sip_data_t *data = NULL;
+
LM_DBG("Got kill signal for call [%.*s] client [%.*s] h_id [%u] h_entry [%u]. Dropping it now\n",
call->sip_data.callid.len,
call->sip_data.callid.s,
@@ -970,6 +963,14 @@ int terminate_call(call_t *call) {
struct mi_node *node, *node1 = NULL;
struct mi_cmd *end_dlg_cmd = NULL;
+ if (_data.cs_route_number >= 0) {
+ data = &call->sip_data;
+ if (faked_msg_init_with_dlg_info(&data->callid, &data->from_uri, &data->from_tag,
+ &data->to_uri, &data->to_tag, &dmsg) != 0) {
+ LM_ERR("[%.*s]: error generating faked sip message\n", data->callid.len, data->callid.s);
+ dmsg = NULL;
+ }
+ }
root = init_mi_tree(0, 0, 0);
if (root == NULL) {
LM_ERR("Error initializing tree to terminate call\n");
@@ -1006,7 +1007,7 @@ int terminate_call(call_t *call) {
free_mi_tree(root);
free_mi_tree(result);
- __notify_call_termination(&call->sip_data);
+ if(dmsg) __notify_call_termination(dmsg);
return 0;
}
diff --git a/modules/cnxcc/cnxcc_redis.h b/modules/cnxcc/cnxcc_redis.h
index 7dade38..af24c7a 100644
--- a/modules/cnxcc/cnxcc_redis.h
+++ b/modules/cnxcc/cnxcc_redis.h
@@ -22,7 +22,7 @@
*
*/
-#ifndef CNXCC_STORAGE_H_
+#ifndef CNXCC_REDIS_H_
#define CNXCC_REDIS_H_
#include <hiredis/hiredis.h>
diff --git a/modules/corex/corex_rpc.c b/modules/corex/corex_rpc.c
index 77ef0d3..f26965d 100644
--- a/modules/corex/corex_rpc.c
+++ b/modules/corex/corex_rpc.c
@@ -156,6 +156,7 @@ static const char* corex_rpc_shm_status_doc[2] = {
*/
static void corex_rpc_shm_status(rpc_t* rpc, void* ctx)
{
+ LM_DBG("printing shared memory status report\n");
shm_status();
}
@@ -169,6 +170,7 @@ static const char* corex_rpc_shm_summary_doc[2] = {
*/
static void corex_rpc_shm_summary(rpc_t* rpc, void* ctx)
{
+ LM_DBG("printing shared memory summary report\n");
shm_sums();
}
diff --git a/modules/ctl/binrpc.h b/modules/ctl/binrpc.h
index 5b47d88..4c27ed2 100644
--- a/modules/ctl/binrpc.h
+++ b/modules/ctl/binrpc.h
@@ -614,12 +614,15 @@ inline static int binrpc_bytes_needed(struct binrpc_parse_ctx *ctx)
/* prefill v with the requested type, if type==BINRPC_T_ALL it
* will be replaced by the actual record type
* known problems: no support for arrays inside STRUCT
+ * param smode: allow simple vals inside struct (needed for
+ * not-strict-formatted rpc responses)
* returns position after the record and *err==0 if succesfull
* original position and *err<0 if not */
inline static unsigned char* binrpc_read_record(struct binrpc_parse_ctx* ctx,
unsigned char* buf,
unsigned char* end,
struct binrpc_val* v,
+ int smode,
int* err
)
{
@@ -664,18 +667,30 @@ inline static unsigned char* binrpc_read_record(struct binrpc_parse_ctx* ctx,
goto error_type;
}
v->type=type;
- if (ctx->in_struct){
- switch(type){
- case BINRPC_T_STRUCT:
+ switch(type){
+ case BINRPC_T_STRUCT:
+ if (ctx->in_struct){
if (end_tag){
ctx->in_struct--;
v->u.end=1;
}else{
- goto error_record;
+ if(smode==0) {
+ goto error_record;
+ } else {
+ v->u.end=0;
+ ctx->in_struct++;
+ }
}
- break;
- case BINRPC_T_AVP:
- /* name | value */
+ } else {
+ if (end_tag)
+ goto error_record;
+ v->u.end=0;
+ ctx->in_struct++;
+ }
+ break;
+ case BINRPC_T_AVP:
+ /* name | value */
+ if (ctx->in_struct){
v->name.s=(char*)p;
v->name.len=(len-1); /* don't include 0 term */
p+=len;
@@ -689,7 +704,7 @@ inline static unsigned char* binrpc_read_record(struct binrpc_parse_ctx* ctx,
tmp=ctx->in_struct;
ctx->in_struct=0; /* hack to parse a normal record */
v->type=type; /* hack */
- p=binrpc_read_record(ctx, p, end, v, err);
+ p=binrpc_read_record(ctx, p, end, v, smode, err);
if (err<0){
ctx->in_struct=tmp;
goto error;
@@ -701,50 +716,51 @@ inline static unsigned char* binrpc_read_record(struct binrpc_parse_ctx* ctx,
}else{
goto error_record;
}
- break;
- default:
- goto error_record;
- }
- }else{
- switch(type){
- case BINRPC_T_INT:
- p=binrpc_read_int(&v->u.intval, len, p, end, err);
- break;
- case BINRPC_T_STR:
- v->u.strval.s=(char*)p;
- v->u.strval.len=(len-1); /* don't include terminating 0 */
- p+=len;
- break;
- case BINRPC_T_BYTES:
- v->u.strval.s=(char*)p;
- v->u.strval.len=len;
- p+=len;
- case BINRPC_T_STRUCT:
- if (end_tag)
- goto error_record;
- v->u.end=0;
- ctx->in_struct++;
- break;
- case BINRPC_T_ARRAY:
- if (end_tag){
- if (ctx->in_array>0){
- ctx->in_array--;
- v->u.end=1;
- }else
- goto error_record;
+ } else {
+ goto error_type;
+ }
+ break;
+ case BINRPC_T_INT:
+ if (ctx->in_struct && smode==0) goto error_record;
+ p=binrpc_read_int(&v->u.intval, len, p, end, err);
+ break;
+ case BINRPC_T_STR:
+ if (ctx->in_struct && smode==0) goto error_record;
+ v->u.strval.s=(char*)p;
+ v->u.strval.len=(len-1); /* don't include terminating 0 */
+ p+=len;
+ break;
+ case BINRPC_T_BYTES:
+ if (ctx->in_struct && smode==0) goto error_record;
+ v->u.strval.s=(char*)p;
+ v->u.strval.len=len;
+ p+=len;
+ case BINRPC_T_ARRAY:
+ if (ctx->in_struct && smode==0) goto error_record;
+ if (end_tag){
+ if (ctx->in_array>0){
+ ctx->in_array--;
+ v->u.end=1;
}else{
- ctx->in_array++;
- v->u.end=0;
+ goto error_record;
}
- break;
- case BINRPC_T_DOUBLE: /* FIXME: hack: represented as fixed point
- inside an int */
- p=binrpc_read_int(&i, len, p, end, err);
- v->u.fval=((double)i)/1000;
- break;
- default:
+ }else{
+ ctx->in_array++;
+ v->u.end=0;
+ }
+ break;
+ case BINRPC_T_DOUBLE: /* FIXME: hack: represented as fixed point
+ inside an int */
+ if (ctx->in_struct && smode==0) goto error_record;
+ p=binrpc_read_int(&i, len, p, end, err);
+ v->u.fval=((double)i)/1000;
+ break;
+ default:
+ if (ctx->in_struct){
+ goto error_record;
+ } else {
goto error_type;
- }
+ }
}
ctx->offset+=(int)(p-buf);
no_offs_update:
diff --git a/modules/ctl/binrpc_run.c b/modules/ctl/binrpc_run.c
index b06781b..c4b7297 100644
--- a/modules/ctl/binrpc_run.c
+++ b/modules/ctl/binrpc_run.c
@@ -655,7 +655,7 @@ int process_rpc_req(unsigned char* buf, int size, int* bytes_needed,
/* get rpc method */
val.type=BINRPC_T_STR;
- f_ctx.in.s=binrpc_read_record(ctx, f_ctx.in.s, f_ctx.in.end, &val, &err);
+ f_ctx.in.s=binrpc_read_record(ctx, f_ctx.in.s, f_ctx.in.end, &val, 0, &err);
if (err<0){
LOG(L_CRIT, "ERROR: bad rpc request method, binrpc error: %s (%d)\n",
binrpc_error(err), err);
@@ -857,7 +857,7 @@ static int rpc_scan(struct binrpc_ctx* ctx, char* fmt, ...)
case 'd': /* int */
v.type=autoconv?BINRPC_T_ALL:BINRPC_T_INT;
ctx->in.s=binrpc_read_record(&ctx->in.ctx, ctx->in.s,
- ctx->in.end, &v, &err);
+ ctx->in.end, &v, 0, &err);
if (err<0 || ((i=binrpc_val_conv_int(&v, &err))==0 && err<0))
goto error_read;
*(va_arg(ap, int*))=i;
@@ -865,7 +865,7 @@ static int rpc_scan(struct binrpc_ctx* ctx, char* fmt, ...)
case 'f':
v.type=autoconv?BINRPC_T_ALL:BINRPC_T_DOUBLE;
ctx->in.s=binrpc_read_record(&ctx->in.ctx, ctx->in.s,
- ctx->in.end, &v, &err);
+ ctx->in.end, &v, 0, &err);
if (err<0 || ((d=binrpc_val_conv_double(&v, &err))==0 &&
err<0))
goto error_read;
@@ -875,7 +875,7 @@ static int rpc_scan(struct binrpc_ctx* ctx, char* fmt, ...)
case 'S': /* str */
v.type=autoconv?BINRPC_T_ALL:BINRPC_T_STR;
ctx->in.s=binrpc_read_record(&ctx->in.ctx, ctx->in.s,
- ctx->in.end, &v,&err);
+ ctx->in.end, &v, 0, &err);
if (err<0 || ((s=binrpc_val_conv_str(ctx, &v, &err))==0 &&
err<0)){
v.u.strval.s="if you get this string, you don't"
@@ -895,7 +895,7 @@ static int rpc_scan(struct binrpc_ctx* ctx, char* fmt, ...)
/* FIXME: structure reading doesn't work for now */
#if 0
ctx->in.s=binrpc_read_record(&ctx->in.ctx, ctx->in.s,
- ctx->in.end, &v, &err);
+ ctx->in.end, &v, 0, &err);
if (err<0) goto error_read;
ctx->in.in_struct++;
*(va_arg(ap, void**))=ctx; /* use the same context */
diff --git a/modules/db_postgres/km_pg_con.c b/modules/db_postgres/km_pg_con.c
index d053c55..ec98add 100644
--- a/modules/db_postgres/km_pg_con.c
+++ b/modules/db_postgres/km_pg_con.c
@@ -71,6 +71,10 @@ struct pg_con* db_postgres_new_connection(struct db_id* id)
memset(ptr, 0, sizeof(struct pg_con));
ptr->ref = 1;
+ memset(keywords, 0, (sizeof(char*) * 10));
+ memset(values, 0, (sizeof(char*) * 10));
+ memset(to, 0, (sizeof(char) * 16));
+
if (id->port) {
ports = int2str(id->port, 0);
keywords[i] = "port";
diff --git a/modules/dialog/dlg_db_handler.c b/modules/dialog/dlg_db_handler.c
index 9e8d2c4..aed40e7 100644
--- a/modules/dialog/dlg_db_handler.c
+++ b/modules/dialog/dlg_db_handler.c
@@ -711,15 +711,23 @@ int update_dialog_dbinfo_unsafe(struct dlg_cell * cell)
&sflags_column, &toroute_name_column, &req_uri_column,
&xdata_column, &iflags_column };
+ if(cell->state<DLG_STATE_EARLY || cell->state==DLG_STATE_DELETED) {
+ LM_DBG("not storing dlg in db during initial or deleted states\n");
+ return 0;
+ }
+
+ i = 0;
if( (cell->dflags & DLG_FLAG_NEW) != 0
|| (cell->dflags & DLG_FLAG_CHANGED_VARS) != 0) {
/* iterate the list */
for(var=cell->vars ; var ; var=var->next) {
if (update_dialog_vars_dbinfo(cell, var) != 0)
return -1;
+ i++;
}
/* Remove the flag */
cell->dflags &= ~DLG_FLAG_CHANGED_VARS;
+ LM_DBG("updated %d vars for dlg [%d:%d]\n", i, cell->h_entry, cell->h_id);
}
if(use_dialog_table()!=0)
@@ -854,43 +862,31 @@ error:
int update_dialog_dbinfo(struct dlg_cell * cell)
{
- struct dlg_entry entry;
/* lock the entry */
- entry = (d_table->entries)[cell->h_entry];
- dlg_lock( d_table, &entry);
+ dlg_lock(d_table, &d_table->entries[cell->h_entry]);
if (update_dialog_dbinfo_unsafe(cell) != 0) {
- dlg_unlock( d_table, &entry);
+ dlg_unlock(d_table, &d_table->entries[cell->h_entry]);
return -1;
}
- dlg_unlock( d_table, &entry);
+ dlg_unlock(d_table, &d_table->entries[cell->h_entry]);
return 0;
}
void dialog_update_db(unsigned int ticks, void * param)
{
- int index;
- struct dlg_entry entry;
- struct dlg_cell * cell;
+ int i;
+ struct dlg_cell *cell;
LM_DBG("saving current_info \n");
-
- for(index = 0; index< d_table->size; index++){
- /* lock the whole entry */
- entry = (d_table->entries)[index];
- dlg_lock( d_table, &entry);
-
- for(cell = entry.first; cell != NULL; cell = cell->next){
- if (update_dialog_dbinfo_unsafe(cell) != 0) {
- dlg_unlock( d_table, &entry);
- goto error;
- }
- }
- dlg_unlock( d_table, &entry);
+ for(i = 0; i < d_table->size; i++){
+ /* lock the slot */
+ dlg_lock(d_table, &d_table->entries[i]);
+ for(cell = d_table->entries[i].first; cell != NULL; cell = cell->next){
+ /* if update fails for one dlg, still do it for the next ones */
+ update_dialog_dbinfo_unsafe(cell);
+ }
+ dlg_unlock(d_table, &d_table->entries[i]);
}
-
return;
-
-error:
- dlg_unlock( d_table, &entry);
}
diff --git a/modules/dialog/dlg_handlers.c b/modules/dialog/dlg_handlers.c
index aae6efb..75dc86f 100644
--- a/modules/dialog/dlg_handlers.c
+++ b/modules/dialog/dlg_handlers.c
@@ -766,7 +766,6 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
str ttag;
str req_uri;
unsigned int dir;
- int mlock;
dlg = dlg_get_ctx_dialog();
if(dlg != NULL) {
@@ -792,17 +791,15 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
trim(&req_uri);
dir = DLG_DIR_NONE;
- mlock = 1;
/* search dialog by SIP attributes
- * - if not found, hash table slot is left locked, to avoid races
- * to add 'same' dialog on parallel forking or not-handled-yet
- * retransmissions. Release slot after linking new dialog */
- dlg = search_dlg(&callid, &ftag, &ttag, &dir);
+ * - hash table slot is left locked */
+ dlg = dlg_search(&callid, &ftag, &ttag, &dir);
if(dlg) {
- mlock = 0;
if (detect_spirals) {
- if (spiral_detected == 1)
+ if (spiral_detected == 1) {
+ dlg_hash_release(&callid);
return 0;
+ }
if ( dlg->state != DLG_STATE_DELETED ) {
LM_DBG("Callid '%.*s' found, must be a spiraled request\n",
@@ -817,10 +814,11 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
_dlg_ctx.iuid.h_id = dlg->h_id;
/* search_dlg() has incremented the ref count by 1 */
dlg_release(dlg);
+ dlg_hash_release(&callid);
return 0;
}
dlg_release(dlg);
- }
+ }
}
spiral_detected = 0;
@@ -831,7 +829,7 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
&req_uri /*r-uri*/ );
if (dlg==0) {
- if(likely(mlock==1)) dlg_hash_release(&callid);
+ dlg_hash_release(&callid);
LM_ERR("failed to create new dialog\n");
return -1;
}
@@ -839,7 +837,7 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
/* save caller's tag, cseq, contact and record route*/
if (populate_leg_info(dlg, req, t, DLG_CALLER_LEG,
&(get_from(req)->tag_value)) !=0) {
- if(likely(mlock==1)) dlg_hash_release(&callid);
+ dlg_hash_release(&callid);
LM_ERR("could not add further info to the dialog\n");
shm_free(dlg);
return -1;
@@ -848,9 +846,10 @@ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs)
/* Populate initial varlist: */
dlg->vars = get_local_varlist_pointer(req, 1);
- /* if search_dlg() returned NULL, slot was kept locked */
- link_dlg(dlg, 0, mlock);
- if(likely(mlock==1)) dlg_hash_release(&callid);
+ /* after dlg_search() slot was kept locked */
+ link_dlg(dlg, 0, 1);
+ /* unlock after dlg_search() */
+ dlg_hash_release(&callid);
dlg->lifetime = get_dlg_timeout(req);
s.s = _dlg_ctx.to_route_name;
@@ -1402,8 +1401,13 @@ void dlg_ontimeout(struct dlg_tl *tl)
if(dlg->iflags&DLG_IFLAG_TIMEOUTBYE)
{
+ /* set the dialog context so that it's available in
+ * tm:local-request event route */
+ dlg_set_ctx_iuid(dlg);
if(dlg_bye_all(dlg, NULL)<0)
dlg_unref(dlg, 1);
+ dlg_reset_ctx_iuid();
+
/* run event route for end of dlg */
dlg_run_event_route(dlg, NULL, dlg->state, DLG_STATE_DELETED);
diff --git a/modules/dialog/dlg_hash.c b/modules/dialog/dlg_hash.c
index 420caea..656833c 100644
--- a/modules/dialog/dlg_hash.c
+++ b/modules/dialog/dlg_hash.c
@@ -651,7 +651,7 @@ dlg_cell_t* dlg_get_by_iuid(dlg_iuid_t *diuid)
* \param ftag from tag
* \param ttag to tag
* \param dir direction
- * \param mode let hash table slot locked if dialog is not found
+ * \param mode let hash table slot locked or not
* \return dialog structure on success, NULL on failure
*/
static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
@@ -669,7 +669,7 @@ static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry,
/* Check callid / fromtag / totag */
if (match_dialog( dlg, callid, ftag, ttag, dir)==1) {
ref_dlg_unsafe(dlg, 1);
- dlg_unlock( d_table, d_entry);
+ if(likely(mode==0)) dlg_unlock( d_table, d_entry);
LM_DBG("dialog callid='%.*s' found on entry %u, dir=%d\n",
callid->len, callid->s,h_entry,*dir);
return dlg;
@@ -725,15 +725,15 @@ struct dlg_cell* get_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir)
* referred to as a dialog."
* Note that the caller is responsible for decrementing (or reusing)
* the reference counter by one again if a dialog has been found.
- * If the dialog is not found, the hash slot is left locked, to allow
- * linking the structure of a new dialog.
+ * Important: the hash slot is left locked (e.g., needed to allow
+ * linking the structure of a new dialog).
* \param callid callid
* \param ftag from tag
* \param ttag to tag
* \param dir direction
* \return dialog structure on success, NULL on failure (and slot locked)
*/
-dlg_cell_t* search_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir)
+dlg_cell_t* dlg_search( str *callid, str *ftag, str *ttag, unsigned int *dir)
{
struct dlg_cell *dlg;
unsigned int he;
@@ -750,6 +750,21 @@ dlg_cell_t* search_dlg( str *callid, str *ftag, str *ttag, unsigned int *dir)
/*!
+ * \brief Lock hash table slot by call-id
+ * \param callid call-id value
+ */
+void dlg_hash_lock(str *callid)
+{
+ unsigned int he;
+ struct dlg_entry *d_entry;
+
+ he = core_hash(callid, 0, d_table->size);
+ d_entry = &(d_table->entries[he]);
+ dlg_lock(d_table, d_entry);
+}
+
+
+/*!
* \brief Release hash table slot by call-id
* \param callid call-id value
*/
@@ -764,7 +779,6 @@ void dlg_hash_release(str *callid)
}
-
/*!
* \brief Link a dialog structure
* \param dlg dialog
diff --git a/modules/dialog/dlg_hash.h b/modules/dialog/dlg_hash.h
index b09fe38..64fb037 100644
--- a/modules/dialog/dlg_hash.h
+++ b/modules/dialog/dlg_hash.h
@@ -335,15 +335,22 @@ dlg_cell_t* get_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
* referred to as a dialog."
* Note that the caller is responsible for decrementing (or reusing)
* the reference counter by one again if a dialog has been found.
- * If the dialog is not found, the hash slot is left locked, to allow
- * linking the structure of a new dialog.
+ * Important: the hash slot is left locked (e.g., needed to allow
+ * linking the structure of a new dialog).
* \param callid callid
* \param ftag from tag
* \param ttag to tag
* \param dir direction
* \return dialog structure on success, NULL on failure (and slot locked)
*/
-dlg_cell_t* search_dlg(str *callid, str *ftag, str *ttag, unsigned int *dir);
+dlg_cell_t* dlg_search(str *callid, str *ftag, str *ttag, unsigned int *dir);
+
+
+/*!
+ * \brief Lock hash table slot by call-id
+ * \param callid call-id value
+ */
+void dlg_hash_lock(str *callid);
/*!
diff --git a/modules/dialog/dlg_profile.c b/modules/dialog/dlg_profile.c
index 39dc1df..9a47082 100644
--- a/modules/dialog/dlg_profile.c
+++ b/modules/dialog/dlg_profile.c
@@ -394,6 +394,7 @@ int remove_profile(dlg_profile_table_t *profile, str *value, str *puid)
lh->next = lh->prev = NULL;
if(lh->linker) shm_free(lh->linker);
p_entry->content--;
+ lock_release(&profile->lock );
return 1;
}
lh = lh->next;
diff --git a/modules/dialog/dlg_var.c b/modules/dialog/dlg_var.c
index b4f821e..e8c84ed 100644
--- a/modules/dialog/dlg_var.c
+++ b/modules/dialog/dlg_var.c
@@ -40,7 +40,7 @@ dlg_ctx_t _dlg_ctx;
extern int spiral_detected;
/*! global variable table, in case the dialog does not exist yet */
-struct dlg_var * var_table = 0;
+static struct dlg_var *_dlg_var_table = 0;
/*! ID of the current message */
int msg_id;
@@ -99,7 +99,7 @@ static inline struct dlg_var *new_dlg_var(str *key, str *val)
LM_ERR("no more shm mem\n");
return NULL;
}
- var->next = NULL;
+ memset(var, 0, sizeof(struct dlg_var));
var->vflags = DLG_FLAG_NEW;
/* set key */
var->key.len = key->len;
@@ -113,7 +113,7 @@ static inline struct dlg_var *new_dlg_var(str *key, str *val)
var->key.s[var->key.len] = '\0';
/* set value */
var->value.len = val->len;
- var->value.s = (char*)shm_malloc(var->value.len);
+ var->value.s = (char*)shm_malloc(var->value.len+1);
if (var->value.s==NULL) {
shm_free(var->key.s);
shm_free(var);
@@ -121,19 +121,21 @@ static inline struct dlg_var *new_dlg_var(str *key, str *val)
return NULL;
}
memcpy(var->value.s, val->s, val->len);
+ var->value.s[var->value.len] = '\0';
return var;
}
/*! Delete the current var-list */
void free_local_varlist() {
struct dlg_var *var;
- while (var_table) {
- var = var_table;
- var_table = var_table->next;
+ while (_dlg_var_table) {
+ var = _dlg_var_table;
+ _dlg_var_table = _dlg_var_table->next;
shm_free(var->key.s);
shm_free(var->value.s);
shm_free(var);
}
+ _dlg_var_table = NULL;
}
/*! Retrieve the local var-list pointer */
@@ -144,9 +146,9 @@ struct dlg_var * get_local_varlist_pointer(struct sip_msg *msg, int clear_pointe
free_local_varlist();
msg_id = msg->id;
}
- var = var_table;
+ var = _dlg_var_table;
if (clear_pointer)
- var_table = NULL;
+ _dlg_var_table = NULL;
return var;
}
@@ -161,7 +163,7 @@ int set_dlg_variable_unsafe(struct dlg_cell *dlg, str *key, str *val)
if (dlg)
var_list = &dlg->vars;
else
- var_list = &var_table;
+ var_list = &_dlg_var_table;
if ( val && (var=new_dlg_var(key, val))==NULL) {
LM_ERR("failed to create new dialog variable\n");
@@ -216,7 +218,7 @@ str * get_dlg_variable_unsafe(struct dlg_cell *dlg, str *key)
if (dlg)
var_list = dlg->vars;
else
- var_list = var_table;
+ var_list = _dlg_var_table;
/* iterate the list */
for(var=var_list ; var ; var=var->next) {
@@ -244,7 +246,7 @@ int pv_parse_dialog_var_name(pv_spec_p sp, str *in)
/*! Internal debugging function: Prints the list of dialogs */
void print_lists(struct dlg_cell *dlg) {
struct dlg_var *varlist;
- varlist = var_table;
+ varlist = _dlg_var_table;
LM_DBG("Internal var-list (%p):\n", varlist);
while (varlist) {
LM_DBG("%.*s=%.*s (flags %i)\n",
diff --git a/modules/dispatcher/dispatch.c b/modules/dispatcher/dispatch.c
index 7491a5f..a5f8a2a 100644
--- a/modules/dispatcher/dispatch.c
+++ b/modules/dispatcher/dispatch.c
@@ -219,6 +219,7 @@ int ds_set_attrs(ds_dest_t *dest, str *attrs)
dest->attrs.socket = pit->body;
}
}
+ if(params_list) free_params(params_list);
return 0;
}
diff --git a/modules/dmq_usrloc/usrloc_sync.c b/modules/dmq_usrloc/usrloc_sync.c
index 3bd0c24..40e89d3 100644
--- a/modules/dmq_usrloc/usrloc_sync.c
+++ b/modules/dmq_usrloc/usrloc_sync.c
@@ -51,7 +51,10 @@ static int add_contact(str aor, ucontact_info_t* ci)
str contact;
int res;
- dmq_ul.get_udomain("location", &_d);
+ if (dmq_ul.get_udomain("location", &_d) < 0) {
+ LM_ERR("Failed to get domain\n");
+ return -1;
+ }
res = dmq_ul.get_urecord(_d, &aor, &r);
if (res < 0) {
LM_ERR("failed to retrieve record from usrloc\n");
@@ -92,6 +95,33 @@ static int add_contact(str aor, ucontact_info_t* ci)
return -1;
}
+static int delete_contact(str aor, ucontact_info_t* ci)
+{
+ udomain_t* _d;
+ urecord_t* r;
+ ucontact_t* c;
+
+ if (dmq_ul.get_udomain("location", &_d) < 0) {
+ LM_ERR("Failed to get domain\n");
+ return -1;
+ }
+
+ if (dmq_ul.get_urecord_by_ruid(_d, dmq_ul.get_aorhash(&aor),
+ &ci->ruid, &r, &c) != 0) {
+ LM_WARN("AOR/Contact not found\n");
+ return -1;
+ }
+ if (dmq_ul.delete_ucontact(r, c) != 0) {
+ dmq_ul.unlock_udomain(_d, &aor);
+ LM_WARN("could not delete contact\n");
+ return -1;
+ }
+ dmq_ul.release_urecord(r);
+ dmq_ul.unlock_udomain(_d, &aor);
+
+ return 0;
+}
+
void usrloc_get_all_ucontact(dmq_node_t* node)
{
int rval, len=0;
@@ -116,6 +146,12 @@ void usrloc_get_all_ucontact(dmq_node_t* node)
LM_ERR("dmq_ul.get_all_ucontacts is NULL\n");
goto done;
}
+
+ if (dmq_ul.get_udomain("location", &_d) < 0) {
+ LM_ERR("Failed to get domain\n");
+ goto done;
+ }
+
rval = dmq_ul.get_all_ucontacts(buf, len, 0, 0, 1);
if (rval<0) {
LM_ERR("failed to fetch contacts\n");
@@ -161,8 +197,6 @@ void usrloc_get_all_ucontact(dmq_node_t* node)
memcpy( &aorhash, cp, sizeof(aorhash));
cp = (char*)cp + sizeof(aorhash);
- dmq_ul.get_udomain("location", &_d);
-
res = dmq_ul.get_urecord_by_ruid(_d, aorhash, &ruid, &r, &ptr);
aor = r->aor;
if (res > 0) {
@@ -357,6 +391,7 @@ int usrloc_dmq_handle_msg(struct sip_msg* msg, peer_reponse_t* resp, dmq_node_t*
break;
case DMQ_RM:
LM_DBG("Received DMQ_RM. Delete contact info...\n");
+ delete_contact(aor, &ci);
break;
case DMQ_SYNC:
LM_DBG("Received DMQ_SYNC. Sending all contacts...\n");
@@ -510,8 +545,7 @@ void dmq_ul_cb_contact(ucontact_t* ptr, int type, void* param)
usrloc_dmq_send_contact(ptr, aor, DMQ_UPDATE, 0);
break;
case UL_CONTACT_DELETE:
- //usrloc_dmq_send_contact(ptr, aor, DMQ_RM);
- LM_DBG("Contact <%.*s> deleted\n", aor.len, aor.s);
+ usrloc_dmq_send_contact(ptr, aor, DMQ_RM, 0);
break;
case UL_CONTACT_EXPIRE:
//usrloc_dmq_send_contact(ptr, aor, DMQ_UPDATE);
diff --git a/modules/domain/domain_mod.c b/modules/domain/domain_mod.c
index 81f3091..1d567a0 100644
--- a/modules/domain/domain_mod.c
+++ b/modules/domain/domain_mod.c
@@ -210,9 +210,9 @@ static int mod_init(void)
goto error;
}
memset(hash_table_1, 0, sizeof(struct domain_list *) *
- DOM_HASH_SIZE + 1);
+ (DOM_HASH_SIZE + 1));
memset(hash_table_2, 0, sizeof(struct domain_list *) *
- DOM_HASH_SIZE + 1);
+ (DOM_HASH_SIZE + 1));
*hash_table = hash_table_1;
/* Allocate and initialize locks */
diff --git a/modules/drouting/README b/modules/drouting/README
index a1171f9..d9f858f 100644
--- a/modules/drouting/README
+++ b/modules/drouting/README
@@ -10,7 +10,7 @@ Edited by
Anca-Maria Vamanu
- Copyright © 2005-2008 Voice Sistem SRL
+ Copyright � 2005-2008 Voice Sistem SRL
__________________________________________________________________
Table of Contents
@@ -234,7 +234,7 @@ Chapter 1. Admin Guide
1.4.1. Gateway Addresses
- Default name for the table storing gateway addresses is “dr_gateways”.
+ Default name for the table storing gateway addresses is "dr_gateways".
Gateway addresses are stored in a separate table because of need to
access them independent of Dynamic Routing processing (e.g., adding/
removing gateway PRI prefix before/after performing other operation --
@@ -270,12 +270,12 @@ Chapter 1. Admin Guide
group of destinations is delimited by semi-colon char. inside the whole
destination list ( like: 2,4;5,78,23;4;7;2 ). The destinations from
within a group may be act differently (like load-balancing, random
- selection, etc), depending of the “sort_order” module parameter - more
+ selection, etc), depending of the "sort_order" module parameter - more
about this is available under the module paramters section.
1.4.3. Routing Rules
- Default name for the table storing rule definitions is “dr_rules”.
+ Default name for the table storing rule definitions is "dr_rules".
Table 1.3. Definition of dr_rules table
Column name Type Default Description
@@ -304,18 +304,18 @@ Chapter 1. Admin Guide
draft 09):
Table 1.4. Time recurrence attributes
- Attribute Description
- dastard Start of interval (RFC 2445 DATE-TIME)
- duration Length of interval (RFC 2445 DURATION)
- freq Frequency of recurrence (secondly,minutely,hourly, daily,weekly,
- monthly, or yearly).
- until bound of recurrence (RFC 2445 DATE-TIME)
- interval How often the recurrence repeats
- byday List of days of the week
- bymonthday List of days of the month
- byyearday List of days of the year
- byweekno List of weeks of the year
- bymonth List of months of the year
+ Attribute Description
+ dastard Start of interval (RFC 2445 DATE-TIME)
+ duration Length of interval (RFC 2445 DURATION)
+ freq Frequency of recurrence (secondly,minutely,hourly, daily,weekly,
+ monthly, or yearly).
+ until bound of recurrence (RFC 2445 DATE-TIME)
+ interval How often the recurrence repeats
+ byday List of days of the week
+ bymonthday List of days of the month
+ byyearday List of days of the year
+ byweekno List of weeks of the year
+ bymonth List of months of the year
The value stored in database has the format of:
<dtstart>|<duration>|<freq>|<until>|<interval>|<byday>|<bymonthday>
|<byyearday>|<byweekno>|<bymonth>
@@ -325,48 +325,52 @@ Chapter 1. Admin Guide
Detailed description of time recurrence attributes:
+ dtstart - specifies the beginning of the first period.
+ duration - specifies the duration of the period. For a
- recurring interval, the “duration” parameter MUST be small
+ recurring interval, the "duration" parameter MUST be small
enough such that subsequent intervals do not overlap. For
non-recurring intervals, durations of any positive length are
- permitted, zero-length duration means “forever”.
- Negative-length durations are not allowed.
- + freq - takes one of the following values: “daily”, to specify
+ permitted, zero-length duration means "forever".
+ Negative-length durations are not allowed. In the common case
+ of a duration less than one day, the value starts with 'PT'
+ followed by number of hours, minutes and seconds, e.g., a
+ duration of 8 hours and 30 minutes is written 'PT8H30M'. See
+ RFC 2445 DURATION specifications for full format.
+ + freq - takes one of the following values: "daily", to specify
repeating periods based on an interval of a day or more;
- “weekly”, to specify repeating periods based on an interval of
- a week or more; “monthly”, to specify repeating periods based
- on an interval of a month or more; and “yearly”, to specify
+ "weekly", to specify repeating periods based on an interval of
+ a week or more; "monthly", to specify repeating periods based
+ on an interval of a month or more; and "yearly", to specify
repeating periods based on an interval of a year or more.
These values are not case-sensitive.
+ until - defines an iCalendar COS DATE or DATE-TIME value which
bounds the recurrence rule in an inclusive manner. If the
- value specified by “until” is synchronized with the specified
+ value specified by "until" is synchronized with the specified
recurrence, this date or date-time becomes the last instance
of the recurrence. If not present, the recurrence is
considered to repeat forever.
+ interval - contains a positive integer representing how often
- the recurrence rule repeats. The default value is “1”, meaning
- every day for a “daily” rule, every week for a “weekly” rule,
- every month for a “monthly” rule and every year for a “yearly”
+ the recurrence rule repeats. The default value is "1", meaning
+ every day for a "daily" rule, every week for a "weekly" rule,
+ every month for a "monthly" rule and every year for a "yearly"
rule.
+ interval - contains a positive integer representing how often
- the recurrence rule repeats. The default value is “1”, meaning
- every day for a “daily” rule, every week for a “weekly” rule,
- every month for a “monthly” rule and every year for a “yearly”
+ the recurrence rule repeats. The default value is "1", meaning
+ every day for a "daily" rule, every week for a "weekly" rule,
+ every month for a "monthly" rule and every year for a "yearly"
rule.
+ byday - specifies a comma-separated list of days of the week.
- “MO” indicates Monday; “TU” indicates Tuesday; “WE” indicates
- Wednesday; “TH” indicates Thursday; “FR” indicates Friday;
- “SA” indicates Saturday; “SU” indicates Sunday. These values
+ "MO" indicates Monday; "TU" indicates Tuesday; "WE" indicates
+ Wednesday; "TH" indicates Thursday; "FR" indicates Friday;
+ "SA" indicates Saturday; "SU" indicates Sunday. These values
are not case-sensitive.
- Each “byday” value can also be preceded by a positive (+n) or
+ Each "byday" value can also be preceded by a positive (+n) or
negative (-n) integer. If present, this indicates the nth
- occurrence of the specific day within the “monthly” or
- “yearly” recurrence. For example, within a “monthly” rule,
+ occurrence of the specific day within the "monthly" or
+ "yearly" recurrence. For example, within a "monthly" rule,
+1MO (or simply 1MO) represents the first Monday within the
month, whereas -1MO represents the last Monday of the month.
If an integer modifier is not present, it means all days of
this type within the specified frequency. For example, within
- a “monthly” rule, MO represents all Mondays within the month.
+ a "monthly" rule, MO represents all Mondays within the month.
+ bymonthday - parameter specifies a comma-separated list of
days of the month. Valid values are 1 to 31 or -31 to -1. For
example, -10 represents the tenth to the last day of the
@@ -380,37 +384,37 @@ Chapter 1. Admin Guide
to -1.
+ bymonth - parameter specifies a comma-separated list of months
of the year. Valid values are 1 to 12.
- A recurrence is specified by including the “freq” parameter, which
+ A recurrence is specified by including the "freq" parameter, which
indicates the type of recurrence rule. Parameters other than
- “dtstart” and “duration” SHOULD NOT be specified unless “freq” is
+ "dtstart" and "duration" SHOULD NOT be specified unless "freq" is
present.
If byxxx parameter values are found which are beyond the available
- scope (ie, bymonthday=“30” in February), they are simply ignored.
+ scope (ie, bymonthday="30" in February), they are simply ignored.
Byxxx parameters modify the recurrence in some manner. Byxxx rule
parts for a period of time which is the same or greater than the
frequency generally reduce or limit the number of occurrences of
- the recurrence generated. For example, freq=“daily” bymonth=“1”
+ the recurrence generated. For example, freq="daily" bymonth="1"
reduces the number of recurrence instances from all days (if the
- “bymonth” parameter is not present) to all days in January. Byxxx
+ "bymonth" parameter is not present) to all days in January. Byxxx
parameters for a period of time less than the frequency generally
increase or expand the number of occurrences of the recurrence. For
- example, freq=“yearly” bymonth=“1,2” increases the number of days
- within the yearly recurrence set from 1 (if “bymonth” parameter is
+ example, freq="yearly" bymonth="1,2" increases the number of days
+ within the yearly recurrence set from 1 (if "bymonth" parameter is
not present) to 2.
If multiple Byxxx parameters are specified, then after evaluating
- the specified “freq” and “interval” parameters, the Byxxx
+ the specified "freq" and "interval" parameters, the Byxxx
parameters are applied to the current set of evaluated occurrences
- in the following order: “bymonth”, “byweekno”, “byyearday”,
- “bymonthday”, “byday”; then “until” is evaluated.
+ in the following order: "bymonth", "byweekno", "byyearday",
+ "bymonthday", "byday"; then "until" is evaluated.
Here is an example of evaluating multiple Byxxx parameters.
- dtstart=“19970105T083000” duration=“10M” freq=“yearly” interval=“2”
- bymonth=“1” byday=“SU”
- First, the interval=“2” would be applied to freq=“yearly” to arrive
- at “every other year” . Then, bymonth=“1” would be applied to
- arrive at “every January, every other year”. Then, byday=“SU” would
- be applied to arrive at “every Sunday in January, every other year,
- from 8:30 to 8:40 ”. The appropriate minutes and hours have been
- retrieved from the “dtstart” and “duration” parameters.
+ dtstart="19970105T083000" duration="PT10M" freq="yearly"
+ interval="2" bymonth="1" byday="SU"
+ First, the interval="2" would be applied to freq="yearly" to arrive
+ at "every other year" . Then, bymonth="1" would be applied to
+ arrive at "every January, every other year". Then, byday="SU" would
+ be applied to arrive at "every Sunday in January, every other year,
+ from 8:30 to 8:40 ". The appropriate minutes and hours have been
+ retrieved from the "dtstart" and "duration" parameters.
d. priority column
If many rules are eligible, choose the one with highest priority.
e. routeid column
@@ -420,8 +424,8 @@ Chapter 1. Admin Guide
level.
f. gwlist column
A comma separated list of gateway identifiers corresponding to a
- row in table “dr_gateways”. You can use a predefined list from the
- table “dr_gw_lists” preceded by the character “#”. The first
+ row in table "dr_gateways". You can use a predefined list from the
+ table "dr_gw_lists" preceded by the character "#". The first
gateway is tried first and if routing to it fails, then the second
one, and so one. If no gateway is left a negative response is sent
back to caller.
@@ -433,7 +437,7 @@ Chapter 1. Admin Guide
2 8 0049 20040101T083000 0 0 1,2 Rule 2
3 7,8,9 0049 20040101T083000 0 0 3 Rule 3
(The time recurrence for first rule is:
- “20040101T083000|10H|weekly|||MO,TU,WE,TH,FR”)
+ "20040101T083000|10H|weekly|||MO,TU,WE,TH,FR")
1.5. Routing Rule Processing
@@ -501,7 +505,7 @@ Chapter 1. Admin Guide
The database url.
- Default value is “NULL”.
+ Default value is "NULL".
Example 1.1. Set db_url parameter
...
@@ -513,7 +517,7 @@ modparam("drouting", "db_url",
The name of the db table storing gateway addresses.
- Default value is “dr_gateways”.
+ Default value is "dr_gateways".
Example 1.2. Set drd_table parameter
...
@@ -524,7 +528,7 @@ modparam("drouting", "drd_table", "dr_gateways")
The name of the db table storing routing rules.
- Default value is “dr_rules”.
+ Default value is "dr_rules".
Example 1.3. Set drr_table parameter
...
@@ -535,7 +539,7 @@ modparam("drouting", "drr_table", "rules")
The name of the db table storing groups.
- Default value is “dr_groups”.
+ Default value is "dr_groups".
Example 1.4. Set drg_table parameter
...
@@ -550,7 +554,7 @@ modparam("drouting", "drg_table", "groups")
individual elements. Very useful to reuse a list of gateways in
different places.
- Default value is “dr_gw_lists”.
+ Default value is "dr_gw_lists".
Example 1.5. Set drl_table parameter
...
@@ -581,7 +585,7 @@ modparam("drouting", "drl_table", "my_gw_lists")
case there are 2 failures, all the three gateways (1,2,3) will be
tried in a random order.
- Default value is “0”.
+ Default value is "0".
Example 1.6. Set sort_order parameter
...
@@ -593,7 +597,7 @@ modparam("drouting", "sort_order", 2)
The name of the avp for storing Request URIs to be later used
(alternative destiantions for the current one).
- Default value is “NULL”.
+ Default value is "NULL".
Example 1.7. Set ruri_avp parameter
...
@@ -608,7 +612,7 @@ modparam("drouting", "ruri_avp", '$avp(i:33)')
function), the AVP will be updated with the attrs of the new used
destination.
- Default value is “NULL”.
+ Default value is "NULL".
Example 1.8. Set attrs_avp parameter
...
@@ -621,7 +625,7 @@ modparam("drouting", "atrrs_avp", '$avp(i:67)')
Flag to configure whether to use domain match when querying database
for user's routing group.
- Default value is “1”.
+ Default value is "1".
Example 1.9. Set use_domain parameter
...
@@ -632,7 +636,7 @@ modparam("drouting", "use_domain", 0)
The name of the column in group db table where the username is stored.
- Default value is “username”.
+ Default value is "username".
Example 1.10. Set drg_user_col parameter
...
@@ -643,7 +647,7 @@ modparam("drouting", "drg_user_col", "user")
The name of the column in group db table where the domain is stored.
- Default value is “domain”.
+ Default value is "domain".
Example 1.11. Set drg_domain_col parameter
...
@@ -654,7 +658,7 @@ modparam("drouting", "drg_domain_col", "host")
The name of the column in group db table where the group id is stored.
- Default value is “groupid”.
+ Default value is "groupid".
Example 1.12. Set drg_grpid_col parameter
...
@@ -666,7 +670,7 @@ modparam("drouting", "drg_grpid_col", "grpid")
The number of rows that should be fetched from the result of a query in
rules db table.
- Default value is “2000”.
+ Default value is "2000".
Example 1.13. Set fetch_rows parameter
...
@@ -679,7 +683,7 @@ modparam("drouting", "fetch_rows", 1500)
startup. If not enabled, the GW name will be blindly used during
routing.
- Default value is “1 (enabled)”.
+ Default value is "1 (enabled)".
Example 1.14. Set force_dns parameter
...
@@ -694,7 +698,7 @@ modparam("drouting", "force_dns", 0)
4.4. is_from_gw([type])
4.5. is_from_gw( type, [flag])
-4.1. do_routing("[groupID]")
+4.1. do_routing("[groupID]")
Function to trigger routing of the message according to the rules in
the database table and the configured parameters.
@@ -714,7 +718,7 @@ do_routing("0");
...
do_routing("$avp(i:10)");
-4.2. use_next_gw()/next_routing()
+4.2. use_next_gw()/next_routing()
The function takes the next available destination (set by do_routing,
as alternative destinations) and push it into RURI. Note that the
@@ -737,7 +741,7 @@ if (use_next_gw()) {
}
...
-4.3. goes_to_gw([type])
+4.3. goes_to_gw([type])
Function returns true if the destination of the current request
(destination URI or Request URI) points (as IP) to one of the gateways.
@@ -758,7 +762,7 @@ if (goes_to_gw("1")) {
}
...
-4.4. is_from_gw([type])
+4.4. is_from_gw([type])
The function checks if the sender of the message is a gateway from a
certain group.
@@ -777,7 +781,7 @@ if (is_from_gw("1") {
}
...
-4.5. is_from_gw( type, [flag])
+4.5. is_from_gw( type, [flag])
The function checks if the sender of the message is a gateway from a
certain group.
@@ -799,7 +803,7 @@ if (is_from_gw("3","1") {
5.1. drouting.reload
-5.1. drouting.reload
+5.1. drouting.reload
Command to reload routing rules from database.
diff --git a/modules/drouting/doc/drouting_admin.xml b/modules/drouting/doc/drouting_admin.xml
index cebbe60..f3cffd9 100644
--- a/modules/drouting/doc/drouting_admin.xml
+++ b/modules/drouting/doc/drouting_admin.xml
@@ -469,7 +469,11 @@
be small enough such that subsequent intervals do not overlap.
For non-recurring intervals, durations of any positive length are
permitted, zero-length duration means <quote>forever</quote>.
- Negative-length durations are not allowed.
+ Negative-length durations are not allowed. In the common case of
+ a duration less than one day, the value starts with 'PT' followed by
+ number of hours, minutes and seconds, e.g., a duration of 8 hours
+ and 30 minutes is written 'PT8H30M'. See RFC 2445 DURATION
+ specifications for full format.
</para>
</listitem>
<listitem>
@@ -612,7 +616,7 @@
Here is an example of evaluating multiple Byxxx parameters.
</para>
<para>
- dtstart=<quote>19970105T083000</quote> duration=<quote>10M</quote>
+ dtstart=<quote>19970105T083000</quote> duration=<quote>PT10M</quote>
freq=<quote>yearly</quote> interval=<quote>2</quote>
bymonth=<quote>1</quote> byday=<quote>SU</quote>
</para>
diff --git a/modules/drouting/drouting.c b/modules/drouting/drouting.c
index 3c79f26..989558e 100644
--- a/modules/drouting/drouting.c
+++ b/modules/drouting/drouting.c
@@ -466,7 +466,7 @@ static void rpc_reload(rpc_t *rpc, void *c)
return;
}
- rpc->rpl_printf(c, "relaad OK");
+ rpc->rpl_printf(c, "reload ok");
return;
}
diff --git a/modules/evapi/README b/modules/evapi/README
index 6035cce..4d61f8e 100644
--- a/modules/evapi/README
+++ b/modules/evapi/README
@@ -160,8 +160,16 @@ modparam("evapi", "netstring_format", 0)
4.1. evapi_relay(evdata)
- 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.
+
+ 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.
+
+ 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().
This function can be used from ANY_ROUTE.
@@ -182,10 +190,17 @@ evapi_relay("{ \"event\": \"test\",\n \"data\": { \"fU\": \"$fU\" }\n}");
4.2. evapi_async_relay(evdata)
- Relay the event data give as parameter to connected applications. The
- format on the network is netstring with evdata payload. Before
- evaluating the parameter, the request processing is suspended using tm
- module.
+ Relay the event data given as parameter to connected applications.
+ Before evaluating the parameter, the request processing is suspended
+ using 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;.
+
+ 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.
This function can be used from REQUEST_ROUTE.
diff --git a/modules/evapi/evapi_dispatch.c b/modules/evapi/evapi_dispatch.c
index 159d14e..b0aa8f5 100644
--- a/modules/evapi/evapi_dispatch.c
+++ b/modules/evapi/evapi_dispatch.c
@@ -36,6 +36,7 @@
#include "../../sr_module.h"
#include "../../dprint.h"
#include "../../ut.h"
+#include "../../cfg/cfg_struct.h"
#include "../../lib/kcore/faked_msg.h"
#include "evapi_dispatch.h"
@@ -44,12 +45,15 @@ static int _evapi_notify_sockets[2];
static int _evapi_netstring_format = 1;
#define EVAPI_IPADDR_SIZE 64
+#define CLIENT_BUFFER_SIZE 32768
typedef struct _evapi_client {
int connected;
int sock;
unsigned short af;
unsigned short src_port;
char src_addr[EVAPI_IPADDR_SIZE];
+ char rbuffer[CLIENT_BUFFER_SIZE];
+ unsigned int rpos;
} evapi_client_t;
typedef struct _evapi_env {
@@ -59,7 +63,8 @@ typedef struct _evapi_env {
} evapi_env_t;
#define EVAPI_MAX_CLIENTS 8
-static evapi_client_t _evapi_clients[EVAPI_MAX_CLIENTS];
+/* last one used for error handling, not a real connected client */
+static evapi_client_t _evapi_clients[EVAPI_MAX_CLIENTS+1];
typedef struct _evapi_evroutes {
int con_new;
@@ -224,26 +229,18 @@ int evapi_dispatch_notify(char *obuf, int olen)
*/
void evapi_recv_client(struct ev_loop *loop, struct ev_io *watcher, int revents)
{
-#define CLIENT_BUFFER_SIZE 4096
- char rbuffer[CLIENT_BUFFER_SIZE];
ssize_t rlen;
int i, k;
evapi_env_t evenv;
str frame;
+ char *sfp;
+ char *efp;
if(EV_ERROR & revents) {
perror("received invalid event\n");
return;
}
- /* read message from client */
- rlen = recv(watcher->fd, rbuffer, CLIENT_BUFFER_SIZE-1, 0);
-
- if(rlen < 0) {
- LM_ERR("cannot read the client message\n");
- return;
- }
-
for(i=0; i<EVAPI_MAX_CLIENTS; i++) {
if(_evapi_clients[i].connected==1 && _evapi_clients[i].sock==watcher->fd) {
break;
@@ -251,9 +248,24 @@ void evapi_recv_client(struct ev_loop *loop, struct ev_io *watcher, int revents)
}
if(i==EVAPI_MAX_CLIENTS) {
LM_ERR("cannot lookup client socket %d\n", watcher->fd);
+ /* try to empty the socket anyhow */
+ rlen = recv(watcher->fd, _evapi_clients[i].rbuffer, CLIENT_BUFFER_SIZE-1, 0);
+ return;
+ }
+
+ /* read message from client */
+ rlen = recv(watcher->fd, _evapi_clients[i].rbuffer + _evapi_clients[i].rpos,
+ CLIENT_BUFFER_SIZE - 1 - _evapi_clients[i].rpos, 0);
+
+ if(rlen < 0) {
+ LM_ERR("cannot read the client message\n");
+ _evapi_clients[i].rpos = 0;
return;
}
+
+ cfg_update();
+
evapi_env_reset(&evenv);
if(rlen == 0) {
/* client is gone */
@@ -262,6 +274,7 @@ void evapi_recv_client(struct ev_loop *loop, struct ev_io *watcher, int revents)
evapi_run_cfg_route(&evenv, _evapi_rts.con_closed);
_evapi_clients[i].connected = 0;
_evapi_clients[i].sock = 0;
+ _evapi_clients[i].rpos = 0;
ev_io_stop(loop, watcher);
free(watcher);
LM_INFO("client closing connection - pos [%d] addr [%s:%d]\n",
@@ -269,50 +282,97 @@ void evapi_recv_client(struct ev_loop *loop, struct ev_io *watcher, int revents)
return;
}
- rbuffer[rlen] = '\0';
+ _evapi_clients[i].rbuffer[_evapi_clients[i].rpos+rlen] = '\0';
- LM_NOTICE("{%d} [%s:%d] - received [%.*s]\n",
+ LM_NOTICE("{%d} [%s:%d] - received [%.*s] (%d) (%d)\n",
i, _evapi_clients[i].src_addr, _evapi_clients[i].src_port,
- (int)rlen, rbuffer);
+ (int)rlen, _evapi_clients[i].rbuffer+_evapi_clients[i].rpos,
+ (int)rlen, (int)_evapi_clients[i].rpos);
evenv.conidx = i;
evenv.eset = 1;
if(_evapi_netstring_format) {
/* netstring decapsulation */
k = 0;
- while(k<rlen) {
+ while(k<_evapi_clients[i].rpos+rlen) {
frame.len = 0;
- while(k<rlen) {
- if(rbuffer[k]==' ' || rbuffer[k]=='\t'
- || rbuffer[k]=='\r' || rbuffer[k]=='\n')
+ while(k<_evapi_clients[i].rpos+rlen) {
+ if(_evapi_clients[i].rbuffer[k]==' '
+ || _evapi_clients[i].rbuffer[k]=='\t'
+ || _evapi_clients[i].rbuffer[k]=='\r'
+ || _evapi_clients[i].rbuffer[k]=='\n')
k++;
else break;
}
- if(k==rlen) return;
- while(k<rlen) {
- if(rbuffer[k]>='0' && rbuffer[k]<='9') {
- frame.len = frame.len*10 + rbuffer[k] - '0';
+ if(k==_evapi_clients[i].rpos+rlen) {
+ _evapi_clients[i].rpos = 0;
+ LM_DBG("empty content\n");
+ return;
+ }
+ /* pointer to start of whole frame */
+ sfp = _evapi_clients[i].rbuffer + k;
+ while(k<_evapi_clients[i].rpos+rlen) {
+ if(_evapi_clients[i].rbuffer[k]>='0' && _evapi_clients[i].rbuffer[k]<='9') {
+ frame.len = frame.len*10 + _evapi_clients[i].rbuffer[k] - '0';
} else {
- if(rbuffer[k]==':')
+ if(_evapi_clients[i].rbuffer[k]==':')
break;
/* invalid character - discard the rest */
+ _evapi_clients[i].rpos = 0;
+ LM_DBG("invalid char when searching for size [%c] [%.*s] (%d) (%d)\n",
+ _evapi_clients[i].rbuffer[k],
+ (int)(_evapi_clients[i].rpos+rlen), _evapi_clients[i].rbuffer,
+ (int)(_evapi_clients[i].rpos+rlen), k);
return;
}
k++;
}
- if(k==rlen || frame.len<=0) return;
- if(frame.len + k>=rlen) return;
+ if(k==_evapi_clients[i].rpos+rlen || frame.len<=0) {
+ LM_DBG("invalid frame len: %d kpos: %d rpos: %u rlen: %lu\n",
+ frame.len, k, _evapi_clients[i].rpos, rlen);
+ _evapi_clients[i].rpos = 0;
+ return;
+ }
+ if(frame.len + k>=_evapi_clients[i].rpos + rlen) {
+ /* partial data - shift back in buffer and wait to read more */
+ efp = _evapi_clients[i].rbuffer + _evapi_clients[i].rpos + rlen;
+ if(efp<=sfp) {
+ _evapi_clients[i].rpos = 0;
+ LM_DBG("weird - invalid size for residual data\n");
+ return;
+ }
+ _evapi_clients[i].rpos = (unsigned int)(efp-sfp);
+ if(efp-sfp > sfp-_evapi_clients[i].rbuffer) {
+ memcpy(_evapi_clients[i].rbuffer, sfp, _evapi_clients[i].rpos);
+ } else {
+ for(k=0; k<_evapi_clients[i].rpos; k++) {
+ _evapi_clients[i].rbuffer[k] = sfp[k];
+ }
+ }
+ LM_DBG("residual data [%.*s] (%d)\n",
+ _evapi_clients[i].rpos, _evapi_clients[i].rbuffer,
+ _evapi_clients[i].rpos);
+ return;
+ }
k++;
- frame.s = rbuffer + k;
- if(frame.s[frame.len]!=',') return;
+ frame.s = _evapi_clients[i].rbuffer + k;
+ if(frame.s[frame.len]!=',') {
+ /* invalid data - discard and reset buffer */
+ LM_DBG("frame size mismatch the ending char (%c): [%.*s] (%d)\n",
+ frame.s[frame.len], frame.len, frame.s, frame.len);
+ _evapi_clients[i].rpos = 0 ;
+ return;
+ }
frame.s[frame.len] = '\0';
k += frame.len ;
evenv.msg.s = frame.s;
evenv.msg.len = frame.len;
+ LM_DBG("executing event route for frame: [%.*s] (%d)\n",
+ frame.len, frame.s, frame.len);
evapi_run_cfg_route(&evenv, _evapi_rts.msg_received);
k++;
}
} else {
- evenv.msg.s = rbuffer;
+ evenv.msg.s = _evapi_clients[i].rbuffer;
evenv.msg.len = rlen;
evapi_run_cfg_route(&evenv, _evapi_rts.msg_received);
}
@@ -342,6 +402,8 @@ void evapi_accept_client(struct ev_loop *loop, struct ev_io *watcher, int revent
return;
}
+ cfg_update();
+
/* accept new client connection */
csock = accept(watcher->fd, (struct sockaddr *)&caddr, &clen);
@@ -417,6 +479,8 @@ void evapi_recv_notify(struct ev_loop *loop, struct ev_io *watcher, int revents)
return;
}
+ cfg_update();
+
/* read message from client */
rlen = read(watcher->fd, &sbuf, sizeof(str*));
diff --git a/modules/geoip/geoip_pv.c b/modules/geoip/geoip_pv.c
index 46c4dff..ba12f16 100644
--- a/modules/geoip/geoip_pv.c
+++ b/modules/geoip/geoip_pv.c
@@ -422,7 +422,7 @@ int geoip_update_pv(str *tomatch, str *name)
}
strncpy(gr->tomatch, tomatch->s, tomatch->len);
- tomatch->s[tomatch->len] = '\0';
+ gr->tomatch[tomatch->len] = '\0';
gr->record = GeoIP_record_by_name(_handle_GeoIP,
(const char*)gr->tomatch);
LM_DBG("attempt to match: %s\n", gr->tomatch);
diff --git a/modules/htable/ht_api.c b/modules/htable/ht_api.c
index fb0b117..b281729 100644
--- a/modules/htable/ht_api.c
+++ b/modules/htable/ht_api.c
@@ -460,7 +460,10 @@ int ht_set_cell(ht_t *ht, str *name, int type, int_str *val, int mode)
}
cell->next = it->next;
cell->prev = it->prev;
- cell->expire = now + ht->htexpire;
+ if(ht->updateexpire)
+ cell->expire = now + ht->htexpire;
+ else
+ cell->expire = it->expire;
if(it->prev)
it->prev->next = cell;
else
@@ -489,7 +492,10 @@ int ht_set_cell(ht_t *ht, str *name, int type, int_str *val, int mode)
if(mode) ht_slot_unlock(ht, idx);
return -1;
}
- cell->expire = now + ht->htexpire;
+ if(ht->updateexpire)
+ cell->expire = now + ht->htexpire;
+ else
+ cell->expire = it->expire;
cell->next = it->next;
cell->prev = it->prev;
if(it->prev)
@@ -649,7 +655,8 @@ ht_cell_t* ht_cell_value_add(ht_t *ht, str *name, int val, int mode,
return NULL;
} else {
it->value.n += val;
- it->expire = now + ht->htexpire;
+ if(ht->updateexpire)
+ it->expire = now + ht->htexpire;
if(old!=NULL)
{
if(old->msize>=it->msize)
diff --git a/modules/htable/ht_var.c b/modules/htable/ht_var.c
index 4bcc2b1..5eeafa3 100644
--- a/modules/htable/ht_var.c
+++ b/modules/htable/ht_var.c
@@ -393,13 +393,10 @@ int pv_get_ht_expired_cell(struct sip_msg *msg, pv_param_t *param,
strncmp(param->pvn.u.isname.name.s.s, "value", 5) == 0)
{
if(ht_expired_cell->flags&AVP_VAL_STR) {
- res->rs = ht_expired_cell->value.s;
- res->flags = PV_VAL_STR;
+ return pv_get_strval(msg, param, res, &ht_expired_cell->value.s);
} else {
- res->ri = ht_expired_cell->value.n;
- res->flags = PV_VAL_INT|PV_TYPE_INT;
+ return pv_get_sintval(msg, param, res, ht_expired_cell->value.n);
}
- return 0;
}
if (res->rs.s == NULL)
diff --git a/modules/htable/htable.c b/modules/htable/htable.c
index 13ec1dd..0a31fd7 100644
--- a/modules/htable/htable.c
+++ b/modules/htable/htable.c
@@ -1042,7 +1042,7 @@ static void htable_rpc_list(rpc_t* rpc, void* c)
if (ht->dbtable.len > 0) {
len = ht->dbtable.len > 127 ? 127 : ht->dbtable.len;
memcpy(dbname, ht->dbtable.s, len);
- dbname[ht->dbtable.len] = '\0';
+ dbname[len] = '\0';
} else {
dbname[0] = '\0';
}
diff --git a/modules/ims_registrar_scscf/README b/modules/ims_registrar_scscf/README
new file mode 100644
index 0000000..a3ef80c
--- /dev/null
+++ b/modules/ims_registrar_scscf/README
@@ -0,0 +1,818 @@
+IMS Usrloc PCSCF Module
+
+Jason Penton
+
+ Smile Communications
+
+Edited by
+
+Richard Good
+
+ Smile Communications
+
+ Copyright � 2012 Smile Communications
+ __________________________________________________________________
+
+ Table of Contents
+
+ 1. Admin Guide
+
+ 1. Overview
+ 2. Dependencies
+
+ 2.1. Kamailio Modules
+ 2.2. External Libraries or Applications
+
+ 3. Parameters
+
+ 3.1. default_expires (int)
+ 3.2. default_expires_range (int)
+ 3.3. min_expires (int)
+ 3.4. max_expires (int)
+ 3.5. subscription_default_expires (int)
+ 3.6. subscription_expires_range (int)
+ 3.7. subscription_min_expires (int)
+ 3.8. subscription_max_expires (int)
+ 3.9. user_data_dtd (string)
+ 3.10. user_data_xsd (string)
+ 3.11. support_wildcardPSI (int)
+ 3.12. scscf_name (string)
+ 3.13. store_profile_dereg (int)
+ 3.14. cxdx_dest_realm (string)
+ 3.15. cxdx_forced_peer (string)
+ 3.16. append_branches (integer)
+ 3.17. method_filtering (integer)
+ 3.18. user_data_always (integer)
+
+ 4. Functions
+
+ 4.1. save(async_reply_route, domain)
+ 4.2. lookup(domain)
+ 4.3. lookup_path_to_contact(uri)
+ 4.4. unregister(domain)
+ 4.5. assign_server_unreg(aysnc_reply_route, domain,
+ direction)
+
+ 4.6. impu_registered(domain)
+ 4.7. term_impu_registered(domain)
+ 4.8. reg_fetch_contacts(domain, uri, profile)
+ 4.9. reg_free_contacts(profile)
+ 4.10. can_subscribe_to_reg(domain)
+ 4.11. subscribe_to_reg(domain)
+ 4.12. can_publish_reg(domain)
+ 4.13. publish_reg(domain)
+
+ 5. RPC Commands
+
+ 5.1. ulpcscf.status
+
+ 6. Statistics
+
+ 6.1. registered contacts
+ 6.2. impus
+ 6.3. expired contacts
+
+ 2. Frequently Asked Questions
+
+ List of Examples
+
+ 1.1. Set default_expires parameter
+ 1.2. Set default_expires_range parameter
+ 1.3. Set min_expiresparameter
+ 1.4. Set max_expiresparameter
+ 1.5. Set subscription_default_expires parameter
+ 1.6. Set subscription_expires_range parameter
+ 1.7. Set subscription_min_expiresparameter
+ 1.8. Set subscription_max_expiresparameter
+ 1.9. Set user_data_dtdparameter
+ 1.10. Set user_data_xsdparameter
+ 1.11. Set support_wildcardPSIparameter
+ 1.12. Set scscf_nameparameter
+ 1.13. Set store_profile_deregparameter
+ 1.14. Set cxdx_dest_realmparameter
+ 1.15. Set cxdx_forced_peerparameter
+ 1.16. Set cxdx_forced_peerparameter
+ 1.17. Set cxdx_forced_peerparameter
+ 1.18. Set user_data_alwaysparameter
+ 1.19. save usage
+ 1.20. lookup usage
+ 1.21. lookup usage
+ 1.22. unregister usage
+ 1.23. impu_registered usage
+ 1.24. term_impu_registered usage
+ 1.25. reg_fetch_contacts usage
+ 1.26. reg_free_contacts usage
+ 1.27. can_subscribe_to_reg usage
+ 1.28. subscribe_to_reg usage
+ 1.29. can_publish_reg usage
+ 1.30. publish_reg usage
+
+Chapter 1. Admin Guide
+
+ Table of Contents
+
+ 1. Overview
+ 2. Dependencies
+
+ 2.1. Kamailio Modules
+ 2.2. External Libraries or Applications
+
+ 3. Parameters
+
+ 3.1. default_expires (int)
+ 3.2. default_expires_range (int)
+ 3.3. min_expires (int)
+ 3.4. max_expires (int)
+ 3.5. subscription_default_expires (int)
+ 3.6. subscription_expires_range (int)
+ 3.7. subscription_min_expires (int)
+ 3.8. subscription_max_expires (int)
+ 3.9. user_data_dtd (string)
+ 3.10. user_data_xsd (string)
+ 3.11. support_wildcardPSI (int)
+ 3.12. scscf_name (string)
+ 3.13. store_profile_dereg (int)
+ 3.14. cxdx_dest_realm (string)
+ 3.15. cxdx_forced_peer (string)
+ 3.16. append_branches (integer)
+ 3.17. method_filtering (integer)
+ 3.18. user_data_always (integer)
+
+ 4. Functions
+
+ 4.1. save(async_reply_route, domain)
+ 4.2. lookup(domain)
+ 4.3. lookup_path_to_contact(uri)
+ 4.4. unregister(domain)
+ 4.5. assign_server_unreg(aysnc_reply_route, domain, direction)
+ 4.6. impu_registered(domain)
+ 4.7. term_impu_registered(domain)
+ 4.8. reg_fetch_contacts(domain, uri, profile)
+ 4.9. reg_free_contacts(profile)
+ 4.10. can_subscribe_to_reg(domain)
+ 4.11. subscribe_to_reg(domain)
+ 4.12. can_publish_reg(domain)
+ 4.13. publish_reg(domain)
+
+ 5. RPC Commands
+
+ 5.1. ulpcscf.status
+
+ 6. Statistics
+
+ 6.1. registered contacts
+ 6.2. impus
+ 6.3. expired contacts
+
+1. Overview
+
+ This module contains REGISTER processing logic for the S-CSCF. The
+ 'storage engine' of this module is provided by the ims_usrloc_scscf
+ module:
+
+2. Dependencies
+
+ 2.1. Kamailio Modules
+ 2.2. External Libraries or Applications
+
+2.1. Kamailio Modules
+
+ The following modules must be loaded before this module:
+ * CDP
+ * CDP_AVP
+ * TM
+ * ims_usrloc_scscf
+
+2.2. External Libraries or Applications
+
+ The following libraries or applications must be installed before
+ running Kamailio with this module loaded:
+ * LibXML2 - used for parsing the XML Subscription information
+ obtained from the HSS (Home Subscriber Server)
+
+3. Parameters
+
+ 3.1. default_expires (int)
+ 3.2. default_expires_range (int)
+ 3.3. min_expires (int)
+ 3.4. max_expires (int)
+ 3.5. subscription_default_expires (int)
+ 3.6. subscription_expires_range (int)
+ 3.7. subscription_min_expires (int)
+ 3.8. subscription_max_expires (int)
+ 3.9. user_data_dtd (string)
+ 3.10. user_data_xsd (string)
+ 3.11. support_wildcardPSI (int)
+ 3.12. scscf_name (string)
+ 3.13. store_profile_dereg (int)
+ 3.14. cxdx_dest_realm (string)
+ 3.15. cxdx_forced_peer (string)
+ 3.16. append_branches (integer)
+ 3.17. method_filtering (integer)
+ 3.18. user_data_always (integer)
+
+3.1. default_expires (int)
+
+ If the processed message contains neither Expires HFs nor expires
+ contact parameters, this value will be used for newly created S-CSCF
+ usrloc records. The parameter contains number of second to expire (for
+ example use 3600 for one hour). If it is set to a lower value than the
+ min_expires parameter then it will be ignored. This parameter can be
+ modified via ser config framework. A random value in a specific
+ interval can be selected by using the default_expires_range parameter
+
+ Default value is 3600.
+
+ Example 1.1. Set default_expires parameter
+...
+ modparam("ims_registrar_scscf", "default_expires", 3600)
+...
+
+3.2. default_expires_range (int)
+
+ This parameter specifies that the expiry used for newly created S-CSCF
+ usrloc records are not fixed(when default_expires applies), but a
+ random value in the intervalrdq
+ [default_expires-default_expires_range%,
+ default_expires+default_expires_range%]. The value is between 0 and 100
+ and represent the maximim percentage from default_expires that will be
+ substracted or added when computing the value. Default in 0, meaning
+ default_expires is left unmodified. This parameter can be modified via
+ ser config framework.
+
+ Default value is 0.
+
+ Example 1.2. Set default_expires_range parameter
+...
+ modparam("ims_registrar_scscf", "default_expires_range", 30) # +- 30% fr
+om default_expires
+...
+
+3.3. min_expires (int)
+
+ The minimum expires value of a Contact, values lower than this minimum
+ will be automatically set to the minimum. Value 0 disables the
+ checking. This parameter can be modified via ser config framework.
+
+ Default value is 60.
+
+ Example 1.3. Set min_expiresparameter
+...
+ modparam("ims_registrar_scscf", "min_expires", 1800)
+...
+
+3.4. max_expires (int)
+
+ The maximum expires value of a Contact, values higher than this maximum
+ will be automatically set to the maximum. Value 0 disables the
+ checking. This parameter can be modified via ser config framework.
+
+ Default value is 0.
+
+ Example 1.4. Set max_expiresparameter
+...
+ modparam("ims_registrar_scscf", "max_expires", 3600)
+...
+
+3.5. subscription_default_expires (int)
+
+ If the processed message contains neither Expires HFs nor expires
+ contact parameters, this value will be used for newly created
+ subscriptions. The parameter contains number of second to expire (for
+ example use 3600 for one hour). If it is set to a lower value than the
+ subscription_min_expires parameter then it will be ignored. A random
+ value in a specific interval can be selected by using the
+ subscription_expires_range parameter
+
+ Default value is 3600.
+
+ Example 1.5. Set subscription_default_expires parameter
+...
+ modparam("ims_registrar_scscf", "subscription_default_expires", 3600)
+...
+
+3.6. subscription_expires_range (int)
+
+ This parameter specifies that the expiry used for newly created
+ subscriptions are not fixed(when subscription_default_expires applies),
+ but a random value in the interval
+ [subscription_default_expires-subscription_expires_range%,
+ subscription_default_expires+subscription_expires_range%]. The value is
+ between 0 and 100 and represent the maximim percentage from
+ subscription_default_expires that will be substracted or added when
+ computing the value. Default in 0, meaning subscription_default_expires
+ is left unmodified.
+
+ Default value is 0.
+
+ Example 1.6. Set subscription_expires_range parameter
+...
+ modparam("ims_registrar_scscf", "subscription_expires_range", 30) # +- 3
+0% from subscription_expires_range
+...
+
+3.7. subscription_min_expires (int)
+
+ The minimum expires value of a subscription, values lower than this
+ minimum will be automatically set to the minimum. Value 0 disables the
+ checking.
+
+ Default value is 10.
+
+ Example 1.7. Set subscription_min_expiresparameter
+...
+ modparam("subscription_min_expires", "min_expires", 1800)
+...
+
+3.8. subscription_max_expires (int)
+
+ The maximum expires value of a subscription, values higher than this
+ maximum will be automatically set to the maximum. Value 0 disables the
+ checking.
+
+ Default value is 1000000.
+
+ Example 1.8. Set subscription_max_expiresparameter
+...
+ modparam("ims_registrar_scscf", "subscription_max_expires", 3600)
+...
+
+3.9. user_data_dtd (string)
+
+ DTD to check the user data received in SAA (Server Assignment Answer).
+
+ Default value is NULL (none).
+
+ Example 1.9. Set user_data_dtdparameter
+...
+ modparam("ims_registrar_scscf", "user_data_dtd", "/usr/local/etc/kamaili
+o/CxDataType_Rel7.dtd")
+...
+
+3.10. user_data_xsd (string)
+
+ XSD to check the user data received in SAA (Server Assignment Answer).
+
+ Default value is NULL (none).
+
+ Example 1.10. Set user_data_xsdparameter
+...
+ modparam("ims_registrar_scscf", "user_data_xsd", "/usr/local/etc/kamaili
+o/CxDataType_Rel7.xsd")
+...
+
+3.11. support_wildcardPSI (int)
+
+ indicate support for wildcard PSI is subscription profile (SAA)
+
+ Default value is 0.
+
+ Example 1.11. Set support_wildcardPSIparameter
+...
+ modparam("ims_registrar_scscf", "support_wildcardPSI", 1)
+...
+
+3.12. scscf_name (string)
+
+ The name of the S-CSCF
+
+ Default value is sip:scscf.ims.smilecoms.com:6060.
+
+ Example 1.12. Set scscf_nameparameter
+...
+ modparam("ims_registrar_scscf", "scscf_name", "sip:scscf2.ims.smilecoms.
+com:6060")
+...
+
+3.13. store_profile_dereg (int)
+
+ Should the subscription profile be stored on de-registration
+
+ Default value 0.
+
+ Example 1.13. Set store_profile_deregparameter
+...
+ modparam("ims_registrar_scscf", "store_profile_dereg", 1)
+...
+
+3.14. cxdx_dest_realm (string)
+
+ Destination realm to be used in Diameter messages
+
+ Default value "ims.smilecoms.com"
+
+ Example 1.14. Set cxdx_dest_realmparameter
+...
+ modparam("ims_registrar_scscf", "cxdx_dest_realm", "my.domain,org")
+...
+
+3.15. cxdx_forced_peer (string)
+
+ FQDN of Diameter Peer (HSS) to use for communication (SAR). If you use
+ this, the routing defined in your diameter xml configuration file (CDP)
+ will be ignored and as a result you will lose the benefits of load
+ balancing and failover.
+
+ Default value NULL (none)
+
+ Example 1.15. Set cxdx_forced_peerparameter
+...
+ modparam("ims_registrar_scscf", "cxdx_forced_peer", "hss.ims.smilecoms.c
+om")
+...
+
+3.16. append_branches (integer)
+
+ The parameter controls how lookup function processes multiple contacts.
+ If there are multiple contacts for the given username in usrloc and
+ this parameter is set to 1, Request-URI will be overwritten with the
+ highest-q rated contact and the rest will be appended to sip_msg
+ structure and can be later used by tm for forking. If the parameter is
+ set to 0, only Request-URI will be overwritten with the highest-q rated
+ contact and the rest will be left unprocessed. This parameter can be
+ modified via Kamailio config framework.
+
+ Default value is 0 (disabled)
+
+ Example 1.16. Set cxdx_forced_peerparameter
+...
+ modparam("ims_registrar_scscf", "append_branches", 1)
+...
+
+3.17. method_filtering (integer)
+
+ Tells if the contact filtering based on supported methods should be
+ performed during lookup. It's enabled only if it has a non zero value.
+
+ Default value is 0 (disabled)
+
+ Example 1.17. Set cxdx_forced_peerparameter
+...
+ modparam("ims_registrar_scscf", "method_filtering", 1)
+...
+
+3.18. user_data_always (integer)
+
+ If specified this will make the S-CSCF always request user data from
+ HSS.
+
+ Default value is 0 (disabled)
+
+ Example 1.18. Set user_data_alwaysparameter
+...
+ modparam("ims_registrar_scscf", "user_data_always", 1)
+...
+
+4. Functions
+
+ 4.1. save(async_reply_route, domain)
+ 4.2. lookup(domain)
+ 4.3. lookup_path_to_contact(uri)
+ 4.4. unregister(domain)
+ 4.5. assign_server_unreg(aysnc_reply_route, domain, direction)
+ 4.6. impu_registered(domain)
+ 4.7. term_impu_registered(domain)
+ 4.8. reg_fetch_contacts(domain, uri, profile)
+ 4.9. reg_free_contacts(profile)
+ 4.10. can_subscribe_to_reg(domain)
+ 4.11. subscribe_to_reg(domain)
+ 4.12. can_publish_reg(domain)
+ 4.13. publish_reg(domain)
+
+4.1. save(async_reply_route, domain)
+
+ The function processes a REGISTER message. It can add, remove or modify
+ usrloc records depending on Contact and Expires HFs in the REGISTER
+ message. On success and when called from the REQUEST_ROUTE, 200 OK will
+ be returned listing all contacts that are currently in usrloc. On an
+ error, error message will be sent with a short description in reason
+ phrase. In case of internal errors the function will return FALSE,
+ otherwise a force to exit the cfg is file is actioned by returning 0
+ (asynchronous processing)
+
+ Meaning of the parameters is as follows:
+ * async_reply_route- the route to execute after the save has
+ completed. This is required because the save function is executed
+ asynchronously (Diameter).
+ * domain- Logical domain within registrar.
+
+ This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE
+
+ Example 1.19. save usage
+...
+if (!impu_registered("location")) {
+ save("PRE_REG_SAR_REPLY","location");
+}
+...
+
+4.2. lookup(domain)
+
+ This function extract the IMPU from the Request-URI and tries to find
+ all registered contacts in usrloc. If there are no such contacts, -1 is
+ returned. If there are, Request-URI will be rewritten with the contact
+ that has the highest q value. The rest of the contacts will be appended
+ to the sip msg structure (if append_branches is set) and can be later
+ used by TM module for forking for example...
+
+ If the method filtering option is enabled, the lookup function will
+ only return contacts that support the method of the request being
+ processed (see allows header)
+
+ Meaning of the parameters is as follows:
+ * domain - Logical domain within registrar.
+
+ Return codes:
+ * -1 - Not found
+ * -2 - Found, but method not allowed (check Allows header for INVITE,
+ MESSAGE, etc).
+ * -3 - Error ocurred internally during processing
+
+ This function can be used from REQUEST_ROUTE, FAILURE_ROUTE
+
+ Example 1.20. lookup usage
+...
+lookup("location");
+switch ($retcode) {
+ case -1:
+ case -3:
+ sl_send_reply("404", "Not Found");
+ exit;
+ case -2:
+ sl_send_reply("405", "Not Found");
+ exit;
+};
+...
+
+4.3. lookup_path_to_contact(uri)
+
+ This function take a URI and tries to find the contact in usrloc. If
+ the contact is found and has a path set, then a path header is added to
+ the SIP message so it can be loose routed.
+
+ Meaning of the parameters is as follows:
+ * uri - URI of contact to lookup
+
+ Return codes:
+ * 1 - Success
+ * -1 - Failure
+
+ This function can be used from REQUEST_ROUTE, FAILURE_ROUTE
+
+ Example 1.21. lookup usage
+...
+lookup_path_to_contact($ruri);
+...
+
+4.4. unregister(domain)
+
+ This function will remove all bindings for the IMPU found in the
+ Request-URI.
+
+ Meaning of the parameters is as follows:
+ * Domain- Logical domain within registrar.
+
+ This function can be used in REQUEST_ROUTE, FAILURE_ROUTE
+
+ Example 1.22. unregister usage
+...
+unregister("location");
+...
+
+4.5. assign_server_unreg(aysnc_reply_route, domain, direction)
+
+ TBD
+
+ used in REQUEST_ROUTE
+
+4.6. impu_registered(domain)
+
+ This function checks if the IMPU in the To header is registered in
+ usrloc.
+
+ Meaning of the parameters is as follows:
+ * domain- Logical domain within registrar.
+
+ Return codes:
+ * 1 - True, IMPU exists in registered state in usrloc
+ * -1 - False, IMPU not registered
+
+ This function can be used in REQUEST_ROUTE, FAILURE_ROUTE
+
+ Example 1.23. impu_registered usage
+...
+impu_registered("location");
+switch ($retcode) {
+ case -1:
+ sl_send_reply("404", "Not Found");
+ exit;
+ case 1:
+ #true, continue with normal processing
+};
+...
+
+4.7. term_impu_registered(domain)
+
+ This function checks if the IMPU in the Request-URI is registered in
+ usrloc.
+
+ Meaning of the parameters is as follows:
+ * domain- Logical domain within registrar.
+
+ Return codes:
+ * 1 - True, IMPU exists in registered state in usrloc
+ * -1 - False, IMPU not registered
+
+ This function can be used in REQUEST_ROUTE, FAILURE_ROUTE
+
+ Example 1.24. term_impu_registered usage
+...
+term_impu_registered("location");
+switch ($retcode) {
+ case -1:
+ sl_send_reply("404", "Not Found");
+ exit;
+ case 1:
+ #true, continue with normal processing
+};
+...
+
+4.8. reg_fetch_contacts(domain, uri, profile)
+
+ The function fetches the contacts for 'uri' from table 'domain' to
+ pseudo-variable $imssulc(profile) [imssulc = ims scscf ulc].
+
+ Meaning of the parameters is as follows:
+ * domain - Name of table that should be used for the lookup of
+ contact addresses.
+ * uri - The SIP URI address of the user which to fetch the contact
+ addresses for. It can contain pseudo-variables that are evaluated
+ at runtime.
+ * profile - Name of $imssulc pseudo-variable profile that will store
+ the fetched contacts. It is a static string.
+
+ This function can be used in REQUEST_ROUTE, FAILURE_ROUTE
+
+ Example 1.25. reg_fetch_contacts usage
+...
+reg_fetch_contacts("location", "$ru", "callee");
+reg_fetch_contacts("location", "sip:user at kamailio.org", "caller");
+...
+
+4.9. reg_free_contacts(profile)
+
+ The function frees the contacts from pseudo-variable $ulc(profile).
+ Should be called to release the content of a profile. Anyhow, fetching
+ a new contact addresses set over a profile will release any existing
+ data in that profile.
+
+ Meaning of the parameters is as follows:
+ * profile - Name of $imssulc pseudo-variable profile that stores the
+ contacts. It is a static string.
+
+ This function can be used in REQUEST_ROUTE, FAILURE_ROUTE
+
+ Example 1.26. reg_free_contacts usage
+...
+reg_free_contacts("callee");
+...
+
+4.10. can_subscribe_to_reg(domain)
+
+ This function checks to see that a SUBSCRIBE request is authorised to
+ subscribe to the particular identity. Only 3 entities can subscribe:
+ * The user agent to it's own state
+ * The P-CSCF specified in the path header for that user
+ * Application Server (AS) not yet implemented
+
+ Meaning of the parameters is as follows:
+ * domain - Logical domain within registrar.
+
+ This function can be used in REQUEST_ROUTE
+
+ Example 1.27. can_subscribe_to_reg usage
+...
+if (can_subscribe_to_reg("location")){
+ $var(ret)= subscribe_to_reg("location");
+}
+...
+
+4.11. subscribe_to_reg(domain)
+
+ Save the subscription to the REG event for the UAC or the appropriate
+ P-CSCF (in the path to the UAC).
+
+ Meaning of the parameters is as follows:
+ * domain - Logical domain within registrar.
+
+ This function can be used in REQUEST_ROUTE
+
+ Example 1.28. subscribe_to_reg usage
+...
+if (can_subscribe_to_reg("location")){
+ $var(ret)= subscribe_to_reg("location");
+}
+...
+
+4.12. can_publish_reg(domain)
+
+ This function checks to see that a PUBLISH request is authorised to
+ publish for a particular identity. Only 3 entities can publish:
+ * The user agent to it's own state
+ * The P-CSCF specified in the path header for that user
+ * Application Server (AS) not yet implemented
+
+ Meaning of the parameters is as follows:
+ * domain - Logical domain within registrar.
+
+ This function can be used in REQUEST_ROUTE
+
+ Example 1.29. can_publish_reg usage
+...
+if (can_publish_reg("location")){
+ $var(ret)= publish_reg("location");
+}
+...
+
+4.13. publish_reg(domain)
+
+ Save the publish to the REG event for the UAC or the appropriate P-CSCF
+ (in the path to the UAC).
+
+ Meaning of the parameters is as follows:
+ * domain - Logical domain within registrar.
+
+ This function can be used in REQUEST_ROUTE
+
+ Example 1.30. publish_reg usage
+...
+if (can_publish_reg("location")){
+ $var(ret)= publish_reg("location");
+}
+...
+
+5. RPC Commands
+
+ 5.1. ulpcscf.status
+
+ exported RPC commands.
+
+5.1. ulpcscf.status
+
+ Status of pcscf_usrloc, AORs, max slots, etc.
+
+6. Statistics
+
+ 6.1. registered contacts
+ 6.2. impus
+ 6.3. expired contacts
+
+ Exported statistics are listed in the next sections.
+
+6.1. registered contacts
+
+ Number of AOR contacts in registered state - cannot be reset.
+
+6.2. impus
+
+ Number of IMPUs - cannot be reset.
+
+6.3. expired contacts
+
+ Number of expired contacts - can be reset.
+
+Chapter 2. Frequently Asked Questions
+
+ 2.1. Where can I find more about Kamailio?
+ 2.2. Where can I post a question about this module?
+ 2.3. How can I report a bug?
+
+ 2.1.
+
+ Where can I find more about Kamailio?
+
+ Take a look at http://www.kamailio.org/.
+
+ 2.2.
+
+ Where can I post a question about this module?
+
+ First at all check if your question was already answered on one of our
+ mailing lists:
+ * User Mailing List -
+ http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-users
+ * Developer Mailing List -
+ http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
+
+ E-mails regarding any stable Kamailio release should be sent to
+ <sr-users at lists.sip-router.org> and e-mails regarding development
+ versions should be sent to <sr-dev at lists.sip-router.org>.
+
+ If you want to keep the mail private, send it to
+ <sr-users at lists.sip-router.org>.
+
+ 2.3.
+
+ How can I report a bug?
+
+ Please follow the guidelines provided at:
+ http://sip-router.org/tracker.
diff --git a/modules/ipops/README b/modules/ipops/README
index b213b03..bc48751 100644
--- a/modules/ipops/README
+++ b/modules/ipops/README
@@ -453,10 +453,10 @@ if (srv_query ("_sip._udp.example.com", "udp") > 0) {
$var(cnt) = $srvquery(udp=>count);
$var(i) = 0;
while ($var(i) < $var(cnt)) {
- xlog ("port[$var(i)] $srvquery(udp=>port[$var(i)])\n)";
- xlog ("priority[$var(i)] $srvquery(udp=>priority[$var(i)])\n)";
- xlog ("target[$var(i)] $srvquery(udp=>target[$var(i)])\n)";
- xlog ("weight[$var(i)] $srvquery(udp=>weight[$var(i)])\n)";
+ xlog ("port[$var(i)] $srvquery(udp=>port[$var(i)])\n");
+ xlog ("priority[$var(i)] $srvquery(udp=>priority[$var(i)])\n");
+ xlog ("target[$var(i)] $srvquery(udp=>target[$var(i)])\n");
+ xlog ("weight[$var(i)] $srvquery(udp=>weight[$var(i)])\n");
$var(i) = $var(i) + 1;
}
}
diff --git a/modules/ipops/doc/ipops_admin.xml b/modules/ipops/doc/ipops_admin.xml
index 90c4168..4d77b9e 100644
--- a/modules/ipops/doc/ipops_admin.xml
+++ b/modules/ipops/doc/ipops_admin.xml
@@ -752,10 +752,10 @@ if (srv_query ("_sip._udp.example.com", "udp") > 0) {
$var(cnt) = $srvquery(udp=>count);
$var(i) = 0;
while ($var(i) < $var(cnt)) {
- xlog ("port[$var(i)] $srvquery(udp=>port[$var(i)])\n)";
- xlog ("priority[$var(i)] $srvquery(udp=>priority[$var(i)])\n)";
- xlog ("target[$var(i)] $srvquery(udp=>target[$var(i)])\n)";
- xlog ("weight[$var(i)] $srvquery(udp=>weight[$var(i)])\n)";
+ xlog ("port[$var(i)] $srvquery(udp=>port[$var(i)])\n");
+ xlog ("priority[$var(i)] $srvquery(udp=>priority[$var(i)])\n");
+ xlog ("target[$var(i)] $srvquery(udp=>target[$var(i)])\n");
+ xlog ("weight[$var(i)] $srvquery(udp=>weight[$var(i)])\n");
$var(i) = $var(i) + 1;
}
}
diff --git a/modules/janssonrpc-c/README b/modules/janssonrpc-c/README
index d585e05..53c3ca2 100644
--- a/modules/janssonrpc-c/README
+++ b/modules/janssonrpc-c/README
@@ -308,12 +308,12 @@ E;retry=1");
}
route[RESPONSE] {
- if(jansson_get($var(jsrpc_result), "internal_error", "$var(internal)"))
+ if(jansson_get("internal_error", $var(jsrpc_result), "$var(internal)"))
{
route(INTERNAL);
- } else if(jansson_get($var(jsrpc_result), "error", "$var(error)")) {
+ } else if(jansson_get("error", $var(jsrpc_result), "$var(error)")) {
route(ERROR);
- } else if(jansson_get($var(jsrpc_result), "result", "$var(result)")) {
+ } else if(jansson_get("result", $var(jsrpc_result), "$var(result)")) {
route(RESULT);
}
t_reply("200", "OK");
@@ -326,15 +326,15 @@ route[RESULT] {
route[ERROR] {
xlog("There was an error\n");
- if(jansson_get($var(error), "code", "$var(c)")) {
+ if(jansson_get("code", $var(error), "$var(c)")) {
xlog("code is $var(c)\n");
}
- if(jansson_get($var(error), "message", "$var(r)")) {
+ if(jansson_get("message", $var(error), "$var(r)")) {
xlog("error is $var(r)\n");
}
- if(jansson_get($var(error), "data", "$var(d)")) {
+ if(jansson_get("data", $var(error), "$var(d)")) {
xlog("data is $var(d)\n");
}
}
@@ -342,13 +342,13 @@ route[ERROR] {
route[INTERNAL] {
xlog("There was an internal error\n");
- jansson_get($var(internal), "code", "$var(c)");
+ jansson_get("code", $var(internal), "$var(c)");
xlog("code is $var(c)\n");
- jansson_get($var(internal), "message", "$var(r)");
+ jansson_get("message", $var(internal), "$var(r)");
xlog("error is $var(r)\n");
- if(jansson_get($var(internal), "data", "$var(d)")) {
+ if(jansson_get("data", $var(internal), "$var(d)")) {
xlog("request is $var(d)\n");
}
}
diff --git a/modules/janssonrpc-c/doc/janssonrpc-c_admin.xml b/modules/janssonrpc-c/doc/janssonrpc-c_admin.xml
index 27f0f45..4ae65c0 100644
--- a/modules/janssonrpc-c/doc/janssonrpc-c_admin.xml
+++ b/modules/janssonrpc-c/doc/janssonrpc-c_admin.xml
@@ -356,11 +356,11 @@ route {
}
route[RESPONSE] {
- if(jansson_get($var(jsrpc_result), "internal_error", "$var(internal)")) {
+ if(jansson_get("internal_error", $var(jsrpc_result), "$var(internal)")) {
route(INTERNAL);
- } else if(jansson_get($var(jsrpc_result), "error", "$var(error)")) {
+ } else if(jansson_get("error", $var(jsrpc_result), "$var(error)")) {
route(ERROR);
- } else if(jansson_get($var(jsrpc_result), "result", "$var(result)")) {
+ } else if(jansson_get("result", $var(jsrpc_result), "$var(result)")) {
route(RESULT);
}
t_reply("200", "OK");
@@ -373,15 +373,15 @@ route[RESULT] {
route[ERROR] {
xlog("There was an error\n");
- if(jansson_get($var(error), "code", "$var(c)")) {
+ if(jansson_get("code", $var(error), "$var(c)")) {
xlog("code is $var(c)\n");
}
- if(jansson_get($var(error), "message", "$var(r)")) {
+ if(jansson_get("message", $var(error), "$var(r)")) {
xlog("error is $var(r)\n");
}
- if(jansson_get($var(error), "data", "$var(d)")) {
+ if(jansson_get("data", $var(error), "$var(d)")) {
xlog("data is $var(d)\n");
}
}
@@ -389,13 +389,13 @@ route[ERROR] {
route[INTERNAL] {
xlog("There was an internal error\n");
- jansson_get($var(internal), "code", "$var(c)");
+ jansson_get("code", $var(internal), "$var(c)");
xlog("code is $var(c)\n");
- jansson_get($var(internal), "message", "$var(r)");
+ jansson_get("message", $var(internal), "$var(r)");
xlog("error is $var(r)\n");
- if(jansson_get($var(internal), "data", "$var(d)")) {
+ if(jansson_get("data", $var(internal), "$var(d)")) {
xlog("request is $var(d)\n");
}
}
diff --git a/modules/janssonrpc-c/janssonrpc_connect.c b/modules/janssonrpc-c/janssonrpc_connect.c
index bfe66c9..76378d3 100644
--- a/modules/janssonrpc-c/janssonrpc_connect.c
+++ b/modules/janssonrpc-c/janssonrpc_connect.c
@@ -88,9 +88,13 @@ void force_disconnect(jsonrpc_server_t* server)
/* clean out requests */
jsonrpc_request_t* req = NULL;
+ jsonrpc_request_t* next = NULL;
int key = 0;
for (key=0; key < JSONRPC_DEFAULT_HTABLE_SIZE; key++) {
- for (req = request_table[key]; req != NULL; req = req->next) {
+ for (req = request_table[key]; req != NULL; req = next) {
+ /* fail_request frees req so need to store
+ next_req before call */
+ next = req->next;
if(req->server != NULL && req->server == server) {
fail_request(JRPC_ERR_SERVER_DISCONNECT, req,
"Failing request for server shutdown");
@@ -128,9 +132,10 @@ void server_backoff_cb(int fd, short event, void *arg)
close(fd);
CHECK_AND_FREE_EV(a->ev);
- pkg_free(arg);
wait_server_backoff(timeout, a->server, false);
+
+ pkg_free(arg);
}
void wait_server_backoff(unsigned int timeout /* seconds */,
diff --git a/modules/janssonrpc-c/janssonrpc_io.c b/modules/janssonrpc-c/janssonrpc_io.c
index 0a4ebd6..81ce22a 100644
--- a/modules/janssonrpc-c/janssonrpc_io.c
+++ b/modules/janssonrpc-c/janssonrpc_io.c
@@ -587,9 +587,12 @@ int handle_response(json_t* response)
return_obj = json_object();
json_t* error = json_object_get(response, "error");
+ // if the error value is null, we don't care
+ bool _error = error && (json_typeof(error) != JSON_NULL);
+
json_t* result = json_object_get(response, "result");
- if(error) {
+ if(_error) {
json_object_set(return_obj, "error", error);
}
@@ -597,7 +600,7 @@ int handle_response(json_t* response)
json_object_set(return_obj, "result", result);
}
- if ((!result && !error) || (result && error)) {
+ if ((!result && !_error) || (result && _error)) {
WARN("bad response\n");
internal = internal_error(JRPC_ERR_BAD_RESP, req->payload);
json_object_update(return_obj, internal);
@@ -621,7 +624,7 @@ int handle_response(json_t* response)
goto free_and_end;
}
- if(error) {
+ if(_error) {
// get code from error
json_t* _code = json_object_get(error, "code");
if(_code) {
diff --git a/modules/janssonrpc-c/janssonrpc_request.c b/modules/janssonrpc-c/janssonrpc_request.c
index 39c7f31..f0117d9 100644
--- a/modules/janssonrpc-c/janssonrpc_request.c
+++ b/modules/janssonrpc-c/janssonrpc_request.c
@@ -253,8 +253,6 @@ int schedule_retry(jsonrpc_request_t* req)
new_req->ntries = req->ntries;
- free_request(req);
-
const struct timeval tv = ms_to_tv(time);
new_req->retry_ev = evtimer_new(global_ev_base, retry_cb, (void*)new_req);
@@ -264,6 +262,8 @@ int schedule_retry(jsonrpc_request_t* req)
goto error;
}
+ free_request(req);
+
return 0;
error:
ERR("schedule_retry failed.\n");
diff --git a/modules/janssonrpc-c/janssonrpc_server.c b/modules/janssonrpc-c/janssonrpc_server.c
index 09286bc..8f1fb06 100644
--- a/modules/janssonrpc-c/janssonrpc_server.c
+++ b/modules/janssonrpc-c/janssonrpc_server.c
@@ -591,8 +591,10 @@ void free_server_list(server_list_t* list)
return;
server_list_t* node = NULL;
- for(node=list; node!=NULL; node=node->next)
+ server_list_t* next = NULL;
+ for(node=list; node!=NULL; node=next)
{
+ next = node->next;
pkg_free(node);
}
}
diff --git a/modules/jsonrpc-c/jsonrpc_io.c b/modules/jsonrpc-c/jsonrpc_io.c
index 188d2e6..41429af 100644
--- a/modules/jsonrpc-c/jsonrpc_io.c
+++ b/modules/jsonrpc-c/jsonrpc_io.c
@@ -142,6 +142,11 @@ int (*res_cb)(json_object*, char*, int) = &result_cb;
void cmd_pipe_cb(int fd, short event, void *arg)
{
struct jsonrpc_pipe_cmd *cmd;
+ char *ns = 0;
+ size_t bytes;
+ json_object *payload = NULL;
+ jsonrpc_request_t *req = NULL;
+ json_object *params;
/* struct event *ev = (struct event*)arg; */
if (read(fd, &cmd, sizeof(cmd)) != sizeof(cmd)) {
@@ -149,9 +154,7 @@ void cmd_pipe_cb(int fd, short event, void *arg)
return;
}
- json_object *params = json_tokener_parse(cmd->params);
- json_object *payload = NULL;
- jsonrpc_request_t *req = NULL;
+ params = json_tokener_parse(cmd->params);
if (cmd->notify_only) {
payload = build_jsonrpc_notification(cmd->method, params);
@@ -163,11 +166,10 @@ void cmd_pipe_cb(int fd, short event, void *arg)
if (!payload) {
LM_ERR("Failed to build jsonrpc_request_t (method: %s, params: %s)\n", cmd->method, cmd->params);
- return;
+ goto error;
}
char *json = (char*)json_object_get_string(payload);
- char *ns; size_t bytes;
bytes = netstring_encode_new(&ns, json, (size_t)strlen(json));
struct jsonrpc_server_group *g;
@@ -201,7 +203,7 @@ void cmd_pipe_cb(int fd, short event, void *arg)
if (timerfd == -1) {
LM_ERR("Could not create timerfd.");
- return;
+ goto error;
}
req->timerfd = timerfd;
@@ -215,7 +217,7 @@ void cmd_pipe_cb(int fd, short event, void *arg)
if (timerfd_settime(timerfd, 0, itime, NULL) == -1)
{
LM_ERR("Could not set timer.");
- return;
+ goto error;
}
pkg_free(itime);
struct event *timer_ev = pkg_malloc(sizeof(struct event));
@@ -223,7 +225,7 @@ void cmd_pipe_cb(int fd, short event, void *arg)
event_set(timer_ev, timerfd, EV_READ, timeout_cb, req);
if(event_add(timer_ev, NULL) == -1) {
LM_ERR("event_add failed while setting request timer (%s).", strerror(errno));
- return;
+ goto error;
}
req->timer_ev = timer_ev;
} else if (!sent) {
@@ -237,6 +239,14 @@ void cmd_pipe_cb(int fd, short event, void *arg)
pkg_free(ns);
json_object_put(payload);
+ if (cmd->notify_only) free_pipe_cmd(cmd);
+ return;
+
+error:
+ if(ns) pkg_free(ns);
+ if(payload) json_object_put(payload);
+ if (cmd->notify_only) free_pipe_cmd(cmd);
+ return;
}
void socket_cb(int fd, short event, void *arg)
@@ -338,6 +348,7 @@ int parse_servers(char *_servers, struct jsonrpc_server_group **group_ptr)
struct jsonrpc_server *server = pkg_malloc(sizeof(struct jsonrpc_server));
CHECK_MALLOC(server);
+ memset(server, 0, sizeof(struct jsonrpc_server));
char *h = pkg_malloc(strlen(host)+1);
CHECK_MALLOC(h);
@@ -365,6 +376,7 @@ int parse_servers(char *_servers, struct jsonrpc_server_group **group_ptr)
selected_group = pkg_malloc(sizeof(struct jsonrpc_server_group));
CHECK_MALLOC(selected_group);
+ memset(selected_group, 0, sizeof(struct jsonrpc_server_group));
selected_group->priority = priority;
selected_group->next_server = server;
diff --git a/modules/jsonrpc-s/jsonrpc-s_mod.c b/modules/jsonrpc-s/jsonrpc-s_mod.c
index a5c877b..62f2506 100644
--- a/modules/jsonrpc-s/jsonrpc-s_mod.c
+++ b/modules/jsonrpc-s/jsonrpc-s_mod.c
@@ -1670,7 +1670,7 @@ error:
return 0;
}
-#define JSONRPC_BUF_IN_SIZE 4096
+#define JSONRPC_BUF_IN_SIZE 8192
static void jsonrpc_run_fifo_server(FILE *fifo_stream)
{
FILE *reply_stream;
diff --git a/modules/kex/mi_core.c b/modules/kex/mi_core.c
index 9174809..9a1dcc8 100644
--- a/modules/kex/mi_core.c
+++ b/modules/kex/mi_core.c
@@ -51,7 +51,15 @@
#include "../../cfg/cfg.h"
#include "../../cfg/cfg_ctx.h"
+#ifdef VERSION_NODATE
+#define BUILD_STR __FILE__ " compiled with " COMPILER "\n"
+#else
+#ifdef VERSION_DATE
+#define BUILD_STR __FILE__ " compiled on " VERSION_DATE " with " COMPILER "\n"
+#else
#define BUILD_STR __FILE__ " compiled on "__TIME__ " " __DATE__ " with " COMPILER "\n"
+#endif
+#endif
#define BUILD_STR_LEN (sizeof(BUILD_STR)-1)
#ifndef SVNREVISION
diff --git a/modules/mi_datagram/datagram_fnc.c b/modules/mi_datagram/datagram_fnc.c
index 0309b73..8e2ed71 100644
--- a/modules/mi_datagram/datagram_fnc.c
+++ b/modules/mi_datagram/datagram_fnc.c
@@ -359,6 +359,7 @@ static void datagram_close_async(struct mi_root *mi_rpl,struct mi_handler *hdl,
}
free_mi_tree(mi_rpl);
pkg_free(dtgram.start);
+ if (done) free_async_handler( hdl );
} else if (done) {
mi_send_dgram(reply_sock, MI_COMMAND_FAILED, MI_COMMAND_FAILED_LEN,
(struct sockaddr*)&reply_addr, reply_addr_len, mi_socket_timeout);
@@ -372,6 +373,7 @@ err:
if(dtgram.start)
pkg_free(dtgram.start);
close(reply_sock);
+ if (done) free_async_handler( hdl );
return;
}
diff --git a/modules/mi_rpc/README b/modules/mi_rpc/README
index 9e93dd8..693fb87 100644
--- a/modules/mi_rpc/README
+++ b/modules/mi_rpc/README
@@ -119,7 +119,7 @@ modparam("mi_rpc","rpc_url","tcp:localhost:2046")
Depending on the version (e.g. mi, mi_dg) it formats the output in a
similar way to the corresponding kamailio mi module:
* mi - uses a special, "pretty" format which generates nicer (more
- readable) output when used with sercmd.
+ readable) output when used with kamcmd.
* mi_dg - uses an output format similar to the kamailio mi_datagram
module.
* mi_fifo - uses an output format similar to the kamailio mi_fifo
@@ -135,8 +135,8 @@ modparam("mi_rpc","rpc_url","tcp:localhost:2046")
_parameters_ - the MI command parameters (optional).
- Example using 'sercmd':
-sercmd> mi uptime
+ Example using 'kamcmd':
+kamcmd> mi uptime
Now:: Thu Sep 24 18:17:15 2009
Up since:: Thu Sep 24 17:35:45 2009
Up time:: 2490 [sec]
diff --git a/modules/mi_rpc/doc/mi_rpc_admin.xml b/modules/mi_rpc/doc/mi_rpc_admin.xml
index c51793c..18b4bdc 100644
--- a/modules/mi_rpc/doc/mi_rpc_admin.xml
+++ b/modules/mi_rpc/doc/mi_rpc_admin.xml
@@ -96,7 +96,7 @@ modparam("mi_rpc","rpc_url","tcp:localhost:2046")
<listitem>
<function>mi</function> - uses a special, "pretty" format
which generates nicer (more readable) output when used with
- sercmd.
+ kamcmd.
</listitem>
<listitem>
<function>mi_dg</function> - uses an output format similar to
@@ -125,10 +125,10 @@ modparam("mi_rpc","rpc_url","tcp:localhost:2046")
(optional).
</para>
<para>
- Example using 'sercmd':
+ Example using 'kamcmd':
</para>
<programlisting format="linespecific">
-sercmd> mi uptime
+kamcmd> mi uptime
Now:: Thu Sep 24 18:17:15 2009
Up since:: Thu Sep 24 17:35:45 2009
Up time:: 2490 [sec]
diff --git a/modules/permissions/address.c b/modules/permissions/address.c
index 7ad0fb5..e037dda 100644
--- a/modules/permissions/address.c
+++ b/modules/permissions/address.c
@@ -480,13 +480,21 @@ int allow_address(struct sip_msg* _msg, char* _addr_group, char* _addr_sp,
}
if ( ipa ) {
- if (match_addr_hash_table(*addr_hash_table, addr_group, ipa, port) == 1)
+ if (addr_hash_table
+ && match_addr_hash_table(*addr_hash_table, addr_group,
+ ipa, port) == 1) {
return 1;
- else
- return match_subnet_table(*subnet_table, addr_group, ipa, port);
+ } else {
+ if(subnet_table) {
+ return match_subnet_table(*subnet_table, addr_group, ipa, port);
+ }
+ }
} else {
- return match_domain_name_table(*domain_list_table, addr_group, &ips, port);
+ if(domain_list_table) {
+ return match_domain_name_table(*domain_list_table, addr_group, &ips, port);
+ }
}
+ return -1;
}
@@ -507,14 +515,17 @@ int allow_source_address(struct sip_msg* _msg, char* _addr_group, char* _str2)
LM_DBG("looking for <%u, %x, %u>\n",
addr_group, _msg->rcv.src_ip.u.addr32[0], _msg->rcv.src_port);
- if (match_addr_hash_table(*addr_hash_table, addr_group,
- &_msg->rcv.src_ip,
- _msg->rcv.src_port) == 1)
+ if (addr_hash_table && match_addr_hash_table(*addr_hash_table, addr_group,
+ &_msg->rcv.src_ip, _msg->rcv.src_port) == 1) {
return 1;
- else
- return match_subnet_table(*subnet_table, addr_group,
+ } else {
+ if(subnet_table) {
+ return match_subnet_table(*subnet_table, addr_group,
&_msg->rcv.src_ip,
_msg->rcv.src_port);
+ }
+ }
+ return -1;
}
@@ -525,22 +536,24 @@ int allow_source_address(struct sip_msg* _msg, char* _addr_group, char* _str2)
*/
int allow_source_address_group(struct sip_msg* _msg, char* _str1, char* _str2)
{
- int group;
+ int group = -1;
LM_DBG("looking for <%x, %u> in address table\n",
_msg->rcv.src_ip.u.addr32[0], _msg->rcv.src_port);
- group = find_group_in_addr_hash_table(*addr_hash_table,
- &_msg->rcv.src_ip,
- _msg->rcv.src_port);
- LM_DBG("Found <%d>\n", group);
+ if(addr_hash_table) {
+ group = find_group_in_addr_hash_table(*addr_hash_table,
+ &_msg->rcv.src_ip, _msg->rcv.src_port);
+ LM_DBG("Found <%d>\n", group);
- if (group != -1) return group;
+ if (group != -1) return group;
+ }
LM_DBG("looking for <%x, %u> in subnet table\n",
_msg->rcv.src_ip.u.addr32[0], _msg->rcv.src_port);
- group = find_group_in_subnet_table(*subnet_table,
- &_msg->rcv.src_ip,
- _msg->rcv.src_port);
+ if(subnet_table) {
+ group = find_group_in_subnet_table(*subnet_table,
+ &_msg->rcv.src_ip, _msg->rcv.src_port);
+ }
LM_DBG("Found <%d>\n", group);
return group;
@@ -553,7 +566,7 @@ int allow_source_address_group(struct sip_msg* _msg, char* _str1, char* _str2)
*/
int allow_address_group(struct sip_msg* _msg, char* _addr, char* _port)
{
- int group;
+ int group = -1;
unsigned int port;
str ips;
@@ -575,24 +588,30 @@ int allow_address_group(struct sip_msg* _msg, char* _addr, char* _port)
if ( ipa ) {
LM_DBG("looking for <%.*s, %u> in address table\n",
ips.len, ips.s, port);
- group = find_group_in_addr_hash_table(*addr_hash_table,
- ipa, port);
- LM_DBG("Found address in group <%d>\n", group);
-
- if (group != -1) return group;
+ if(addr_hash_table) {
+ group = find_group_in_addr_hash_table(*addr_hash_table,
+ ipa, port);
+ LM_DBG("Found address in group <%d>\n", group);
- LM_DBG("looking for <%.*s, %u> in subnet table\n",
- ips.len, ips.s, port);
- group = find_group_in_subnet_table(*subnet_table,
- ipa, port);
- LM_DBG("Found a match of subnet in group <%d>\n", group);
+ if (group != -1) return group;
+ }
+ if(subnet_table) {
+ LM_DBG("looking for <%.*s, %u> in subnet table\n",
+ ips.len, ips.s, port);
+ group = find_group_in_subnet_table(*subnet_table,
+ ipa, port);
+ LM_DBG("Found a match of subnet in group <%d>\n", group);
+ }
} else {
LM_DBG("looking for <%.*s, %u> in domain_name table\n",
ips.len, ips.s, port);
- group = find_group_in_domain_name_table(*domain_list_table,
- &ips, port);
- LM_DBG("Found a match of domain_name in group <%d>\n", group);
+ if(domain_list_table) {
+ group = find_group_in_domain_name_table(*domain_list_table,
+ &ips, port);
+ LM_DBG("Found a match of domain_name in group <%d>\n", group);
+ }
}
+ LM_DBG("Found <%d>\n", group);
return group;
}
diff --git a/modules/permissions/mi.c b/modules/permissions/mi.c
index 35f2cca..844a86e 100644
--- a/modules/permissions/mi.c
+++ b/modules/permissions/mi.c
@@ -92,7 +92,7 @@ struct mi_root* mi_trusted_dump(struct mi_root *cmd_tree, void *param)
void rpc_trusted_dump(rpc_t* rpc, void* c) {
if (hash_table==NULL) {
- rpc->fault(c, 500, "Reload failed. No trusted table");
+ rpc->fault(c, 500, "No trusted table");
return;
}
@@ -154,6 +154,10 @@ struct mi_root* mi_address_dump(struct mi_root *cmd_tree, void *param)
*/
void rpc_address_dump(rpc_t* rpc, void* c) {
+ if(addr_hash_table==NULL) {
+ rpc->fault(c, 500, "No address table");
+ return;
+ }
if(addr_hash_table_rpc_print(*addr_hash_table, rpc, c) < 0 ) {
LM_DBG("failed to print a subnet_table dump\n");
}
@@ -185,6 +189,10 @@ struct mi_root* mi_subnet_dump(struct mi_root *cmd_tree, void *param)
* RPC function to dump subnet table
*/
void rpc_subnet_dump(rpc_t* rpc, void* c) {
+ if(subnet_table==NULL) {
+ rpc->fault(c, 500, "No subnet table");
+ return;
+ }
if(subnet_table_rpc_print(*subnet_table, rpc, c) < 0) {
LM_DBG("failed to print a subnet_table dump\n");
}
@@ -217,6 +225,10 @@ struct mi_root* mi_domain_name_dump(struct mi_root *cmd_tree, void *param)
*/
void rpc_domain_name_dump(rpc_t* rpc, void* c) {
+ if(domain_list_table==NULL) {
+ rpc->fault(c, 500, "No domain list table");
+ return;
+ }
if ( domain_name_table_rpc_print(*domain_list_table, rpc, c) < 0 ) {
LM_DBG("failed to print a subnet_table dump\n");
}
diff --git a/modules/pipelimit/README b/modules/pipelimit/README
index 52d844c..797fedd 100644
--- a/modules/pipelimit/README
+++ b/modules/pipelimit/README
@@ -24,6 +24,9 @@ Daniel-Constantin Mierla
1. Admin Guide
1. Overview
+
+ 1.1. Algorithms
+
2. Dependencies
2.1. Kamailio Modules
@@ -77,7 +80,7 @@ Daniel-Constantin Mierla
1.9. Set reply_code parameter at runtime
1.10. Set reply_reason parameter
1.11. Set reply_reason parameter at runtime
- 1.12. rl_check usage
+ 1.12. pl_check usage
1.13. pl_drop usage
Chapter 1. Admin Guide
@@ -85,6 +88,9 @@ Chapter 1. Admin Guide
Table of Contents
1. Overview
+
+ 1.1. Algorithms
+
2. Dependencies
2.1. Kamailio Modules
@@ -127,6 +133,8 @@ Chapter 1. Admin Guide
1. Overview
+ 1.1. Algorithms
+
This module implements traffic limiting for SIP requests.
The module defines in an abstract mode the notion of 'pipe', which can
@@ -138,8 +146,54 @@ Chapter 1. Admin Guide
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.
+
+1.1. Algorithms
+
+ 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.
+
+ Tail Drop Algorithm (TAILDROP)
+
+ 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.
+
+ Random Early Detection Algorithm (RED)
+
+ 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.
+
+ Network Algorithm (NETWORK)
+
+ 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.
+
+ Feedback Algorithm (FEEDBACK)
+
+ 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).
+
+ 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.
2. Dependencies
@@ -298,7 +352,7 @@ kamcmd cfg.set_now_string pipelimit reply_reason "Limiting"
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.
The pipe name can be provided via a pseudo variabile.
@@ -311,13 +365,13 @@ kamcmd cfg.set_now_string pipelimit reply_reason "Limiting"
Meaning of the parameters is as follows:
* name - the string or pseudovariable with the pipe name.
* algorithm - the string or pseudovariable with the algorithm. The
- values can be: taildrop, red, network or feedback - see readme of
+ values can be: TAILDROP, RED, NETWORK, or FEEDBACK - see readme of
ratelimit module for details on each algorithm.
* limit - the integer or pseudovariable with the limit value.
This function can be used from REQUEST_ROUTE.
- Example 1.12. rl_check usage
+ Example 1.12. pl_check usage
...
# perform pipe match for current method
if (!pl_check("one")) {
@@ -354,11 +408,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;
+ }
+ }
+...
4.2. pl_drop([ [min ], max ])
diff --git a/modules/pua/hash.h b/modules/pua/hash.h
index 3da0894..923560c 100644
--- a/modules/pua/hash.h
+++ b/modules/pua/hash.h
@@ -166,7 +166,7 @@ static inline int get_event_flag(str* event)
return CONFERENCE_EVENT;
break;
case 14:
- if (strncmp(event->s, "presence;winfo", 14) == 0)
+ if (strncmp(event->s, "presence.winfo", 14) == 0)
return PWINFO_EVENT;
break;
case 15:
diff --git a/modules/pua_reginfo/usrloc_cb.c b/modules/pua_reginfo/usrloc_cb.c
index 95ec762..7f84788 100644
--- a/modules/pua_reginfo/usrloc_cb.c
+++ b/modules/pua_reginfo/usrloc_cb.c
@@ -224,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];
@@ -251,6 +251,9 @@ 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);
@@ -259,11 +262,10 @@ void reginfo_usrloc_cb(ucontact_t* c, int type, void* param) {
return;
}
- /* 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);
+ /* 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);
return;
}
diff --git a/modules/pv/README b/modules/pv/README
index 9cab590..ae85063 100644
--- a/modules/pv/README
+++ b/modules/pv/README
@@ -45,6 +45,7 @@ Daniel-Constantin Mierla
4.7. sbranch_set_ruri()
4.8. sbranch_append()
4.9. sbranch_reset()
+ 4.10. pv_xavp_print()
5. MI Commands
@@ -70,8 +71,9 @@ Daniel-Constantin Mierla
1.10. sbranch_set_ruri() usage
1.11. sbranch_append() usage
1.12. sbranch_append() usage
- 1.13. shv_set usage
- 1.14. shv_get usage
+ 1.13. pv_xavp_print() usage
+ 1.14. shv_set usage
+ 1.15. shv_get usage
Chapter 1. Admin Guide
@@ -100,6 +102,7 @@ Chapter 1. Admin Guide
4.7. sbranch_set_ruri()
4.8. sbranch_append()
4.9. sbranch_reset()
+ 4.10. pv_xavp_print()
5. MI Commands
@@ -203,6 +206,7 @@ modparam("pv","avp_aliases","email=s:email_addr;tmp=i:100")
4.7. sbranch_set_ruri()
4.8. sbranch_append()
4.9. sbranch_reset()
+ 4.10. pv_xavp_print()
4.1. pv_isset(pvar)
@@ -352,6 +356,17 @@ sbranch_append();
sbranch_reset();
...
+4.10. pv_xavp_print()
+
+ Print all XAVPs to the syslog using INFO log level.
+
+ Function can be used from ANY_ROUTE.
+
+ Example 1.13. pv_xavp_print() usage
+...
+pv_xavp_print();
+...
+
5. MI Commands
5.1. shv_set
@@ -375,7 +390,7 @@ sbranch_reset();
_value_
_empty_line_
- Example 1.13. shv_set usage
+ Example 1.14. shv_set usage
...
$ kamctl fifo shv_set debug int 0
...
@@ -393,7 +408,7 @@ $ kamctl fifo shv_set debug int 0
_name_
_empty_line_
- Example 1.14. shv_get usage
+ Example 1.15. shv_get usage
...
$ kamctl fifo shv_get debug
$ kamctl fifo shv_get
diff --git a/modules/pv/pv_core.c b/modules/pv/pv_core.c
index 745286a..7c3aa92 100644
--- a/modules/pv/pv_core.c
+++ b/modules/pv/pv_core.c
@@ -2808,7 +2808,7 @@ int pv_parse_hdr_name(pv_spec_p sp, str *in)
s.s = p;
s.len = in->len+1;
- if (parse_hname2(s.s, s.s + ((s.len<4)?4:s.len), &hdr)==0)
+ if (parse_hname2_short(s.s, s.s + s.len, &hdr)==0)
{
LM_ERR("error parsing header name [%.*s]\n", s.len, s.s);
goto error;
diff --git a/modules/registrar/README b/modules/registrar/README
index e3f5a7f..8756816 100644
--- a/modules/registrar/README
+++ b/modules/registrar/README
@@ -891,15 +891,16 @@ lookup_branches("location");
4.4. registered(domain [, uri [, match_option [, match_action]]])
- The function returns true if the AOR in the Request-URI is registered,
- false otherwise. The function does not modify the message being
- process, it neither rewrites the Request-URI if a contact is found nor
- append branches.
+ The function returns true if the AOR in the URI is registered, false
+ otherwise. The function does not modify the message being process, it
+ neither rewrites the Request-URI if a contact is found nor append
+ branches. If uri parameter is not provided, then it considered to be
+ the Request-URI for SIP requests and To-URI for SIP replies.
Meaning of the parameters is as follows:
* domain - Name of table that should be used for the lookup.
- * uri (optional) - SIP URI to do be used instead of R-URI. It can be
- a dynamic string with pseudo-variables.
+ * uri (optional) - SIP URI to do be used instead of Request/To-URI.
+ It can be a dynamic string with pseudo-variables.
* match_option (optional) - flag parameter to restrict contact
search. use reg_xavp_cfg to set the values to compare to.
flag values is as follows:
@@ -911,7 +912,7 @@ lookup_branches("location");
flag values is as follows:
+ 1 - set xavp_rcd with value from matched contact
- This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
+ This function can be used from ANY_ROUTE.
Example 1.31. registered usage
...
diff --git a/modules/registrar/doc/registrar_admin.xml b/modules/registrar/doc/registrar_admin.xml
index 672cee8..f1c7063 100644
--- a/modules/registrar/doc/registrar_admin.xml
+++ b/modules/registrar/doc/registrar_admin.xml
@@ -1110,10 +1110,12 @@ lookup_branches("location");
<function moreinfo="none">registered(domain [, uri [, match_option [, match_action]]])</function>
</title>
<para>
- The function returns true if the AOR in the Request-URI is
+ The function returns true if the AOR in the URI is
registered, false otherwise. The function does not modify the
message being process, it neither rewrites the Request-URI if a
- contact is found nor append branches.
+ contact is found nor append branches. If uri parameter is not
+ provided, then it considered to be the Request-URI for SIP requests
+ and To-URI for SIP replies.
</para>
<para>Meaning of the parameters is as follows:</para>
<itemizedlist>
@@ -1126,7 +1128,7 @@ lookup_branches("location");
<listitem>
<para>
<emphasis>uri</emphasis> (optional) - SIP URI to do be used instead
- of R-URI. It can be a dynamic string with pseudo-variables.
+ of Request/To-URI. It can be a dynamic string with pseudo-variables.
</para>
</listitem>
<listitem>
@@ -1160,7 +1162,7 @@ lookup_branches("location");
</listitem>
</itemizedlist>
<para>
- This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
+ This function can be used from ANY_ROUTE.
</para>
<example>
<title><function>registered</function> usage</title>
diff --git a/modules/registrar/lookup.c b/modules/registrar/lookup.c
index efbe39c..6fb170b 100644
--- a/modules/registrar/lookup.c
+++ b/modules/registrar/lookup.c
@@ -36,6 +36,7 @@
#include "../../action.h"
#include "../../mod_fix.h"
#include "../../parser/parse_rr.h"
+#include "../../parser/parse_to.h"
#include "../../forward.h"
#include "../usrloc/usrloc.h"
#include "common.h"
@@ -642,8 +643,16 @@ int registered4(struct sip_msg* _m, udomain_t* _d, str* _uri, int match_flag, in
{
uri = *_uri;
} else {
- if (_m->new_uri.s) uri = _m->new_uri;
- else uri = _m->first_line.u.request.uri;
+ if(IS_SIP_REPLY(_m)) {
+ if (parse_to_header(_m) < 0) {
+ LM_ERR("failed to prepare the message\n");
+ return -1;
+ }
+ uri = get_to(_m)->uri;
+ } else {
+ if (_m->new_uri.s) uri = _m->new_uri;
+ else uri = _m->first_line.u.request.uri;
+ }
}
if (extract_aor(&uri, &aor, NULL) < 0) {
diff --git a/modules/registrar/reg_mod.c b/modules/registrar/reg_mod.c
index d767834..db47824 100644
--- a/modules/registrar/reg_mod.c
+++ b/modules/registrar/reg_mod.c
@@ -41,6 +41,7 @@
#include "../../error.h"
#include "../../socket_info.h"
#include "../../pvar.h"
+#include "../../dset.h"
#include "../../modules/usrloc/usrloc.h"
#include "../../lib/kcore/statistics.h"
#include "../../lib/srutils/sruid.h"
@@ -163,13 +164,13 @@ static cmd_export_t cmds[] = {
{"lookup_to_dset", (cmd_function)w_lookup_to_dset, 1, domain_uri_fixup, 0,
REQUEST_ROUTE | FAILURE_ROUTE },
{"registered", (cmd_function)w_registered, 1, domain_uri_fixup, 0,
- REQUEST_ROUTE | FAILURE_ROUTE },
+ ANY_ROUTE },
{"registered", (cmd_function)w_registered, 2, domain_uri_fixup, 0,
- REQUEST_ROUTE | FAILURE_ROUTE },
+ ANY_ROUTE },
{"registered", (cmd_function)w_registered3, 3, registered_fixup, 0,
- REQUEST_ROUTE | FAILURE_ROUTE },
+ ANY_ROUTE },
{"registered", (cmd_function)w_registered4, 4, registered_fixup, 0,
- REQUEST_ROUTE | FAILURE_ROUTE },
+ ANY_ROUTE },
{"add_sock_hdr", (cmd_function)add_sock_hdr, 1, fixup_str_null, 0,
REQUEST_ROUTE },
{"unregister", (cmd_function)w_unregister, 2, unreg_fixup, 0,
@@ -384,6 +385,8 @@ static int mod_init(void)
sock_flag = (sock_flag!=-1)?(1<<sock_flag):0;
tcp_persistent_flag = (tcp_persistent_flag!=-1)?(1<<tcp_persistent_flag):0;
+ set_aor_case_sensitive(cfg_get(registrar, registrar_cfg, case_sensitive));
+
return 0;
}
diff --git a/modules/registrar/save.c b/modules/registrar/save.c
index ae311e8..1ebb849 100644
--- a/modules/registrar/save.c
+++ b/modules/registrar/save.c
@@ -307,6 +307,20 @@ static inline ucontact_info_t* pack_ci( struct sip_msg* _m, contact_t* _c,
}
ci.server_id = server_id;
+ if(_m->contact) {
+ _c = (((contact_body_t*)_m->contact->parsed)->contacts);
+ if(_c->instance!=NULL && _c->instance->body.len>0) {
+ ci.instance = _c->instance->body;
+ LM_DBG("set instance[%.*s]\n", ci.instance.len, ci.instance.s);
+ }
+ if(_use_regid && _c->instance!=NULL && _c->reg_id!=NULL && _c->reg_id->body.len>0) {
+ if(str2int(&_c->reg_id->body, &ci.reg_id)<0 || ci.reg_id==0)
+ {
+ LM_ERR("invalid reg-id value\n");
+ goto error;
+ }
+ }
+ }
allow_parsed = 0; /* not parsed yet */
received_found = 0; /* not found yet */
diff --git a/modules/rls/subscribe.c b/modules/rls/subscribe.c
index a4735b2..9c24ac7 100644
--- a/modules/rls/subscribe.c
+++ b/modules/rls/subscribe.c
@@ -781,9 +781,9 @@ int rls_handle_subscribe(struct sip_msg* msg, str watcher_user, str watcher_doma
}
}
- if (dbmode != RLS_DB_ONLY)
+ if (get_to(msg)->tag_value.s==NULL || get_to(msg)->tag_value.len==0)
{
- /* sending notify with full state */
+ /* initial subscriber - sending notify with full state */
if(send_full_notify(&subs, service_node, &subs.pres_uri, hash_code)<0)
{
LM_ERR("failed sending full state notify\n");
diff --git a/modules/rr/loose.c b/modules/rr/loose.c
index de06bb3..76204c9 100644
--- a/modules/rr/loose.c
+++ b/modules/rr/loose.c
@@ -757,7 +757,7 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
int status = RR_DRIVEN;
str uri;
struct socket_info *si;
- int uri_is_myself, next_is_strict;
+ int uri_is_myself;
int use_ob = 0;
hdr = _m->route;
@@ -768,11 +768,11 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
routed_msg_id = 0;
if (parse_uri(uri.s, uri.len, &puri) < 0) {
- LM_ERR("failed to parse the first route URI\n");
+ LM_ERR("failed to parse the first route URI (%.*s)\n",
+ uri.len, ZSW(uri.s));
return RR_ERROR;
}
- next_is_strict = is_strict(&puri.params);
routed_params = puri.params;
uri_is_myself = is_myself(&puri);
@@ -815,7 +815,8 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
/* double route may occure due different IP and port, so force as
* send interface the one advertise in second Route */
if (parse_uri(rt->nameaddr.uri.s,rt->nameaddr.uri.len,&puri)<0) {
- LM_ERR("failed to parse the double route URI\n");
+ LM_ERR("failed to parse the double route URI (%.*s)\n",
+ rt->nameaddr.uri.len, ZSW(rt->nameaddr.uri.s));
return RR_ERROR;
}
@@ -852,7 +853,8 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
uri = rt->nameaddr.uri;
if (parse_uri(uri.s, uri.len, &puri) < 0) {
- LM_ERR("failed to parse the first route URI\n");
+ LM_ERR("failed to parse the next route URI (%.*s)\n",
+ uri.len, ZSW(uri.s));
return RR_ERROR;
}
} else {
@@ -867,7 +869,7 @@ static inline int after_loose(struct sip_msg* _m, int preloaded)
}
LM_DBG("URI to be processed: '%.*s'\n", uri.len, ZSW(uri.s));
- if (next_is_strict) {
+ if (is_strict(&puri.params)) {
LM_DBG("Next URI is a strict router\n");
if (handle_sr(_m, hdr, rt) < 0) {
LM_ERR("failed to handle strict router\n");
diff --git a/modules/rtpengine/README b/modules/rtpengine/README
index ae5870f..fe4637b 100644
--- a/modules/rtpengine/README
+++ b/modules/rtpengine/README
@@ -101,7 +101,7 @@ Richard Fuchs
1.6. Set extra_id_pv parameter
1.7. Set setid_avp parameter
1.8. Set force_send_interface parameter
- 1.9. Set write_sdp_avp parameter
+ 1.9. Set write_sdp_pv parameter
1.10. Set rtp_inst_pvar parameter
1.11. set_rtpengine_set usage
1.12. rtpengine_offer usage
@@ -350,9 +350,11 @@ modparam("rtpengine", "force_send_interface", "10.3.7.123")
There is no default value.
- Example 1.9. Set write_sdp_avp parameter
+ Example 1.9. Set write_sdp_pv parameter
...
-modparam("rtpengine", "write_sdp_avp", "$avp(sdp)")
+modparam("rtpengine", "write_sdp_pv", "$avp(sdp)")
+ ... or
+modparam("rtpengine", "write_sdp_pv", "$pv(sdp)")
...
4.10. rtp_inst_pvar (string)
diff --git a/modules/rtpengine/doc/rtpengine_admin.xml b/modules/rtpengine/doc/rtpengine_admin.xml
index 6be5386..5a12f61 100644
--- a/modules/rtpengine/doc/rtpengine_admin.xml
+++ b/modules/rtpengine/doc/rtpengine_admin.xml
@@ -298,10 +298,12 @@ modparam("rtpengine", "force_send_interface", "2001:8d8:1ff:10c0:9a90:96ff:fea8:
There is no default value.
</para>
<example>
- <title>Set <varname>write_sdp_avp</varname> parameter</title>
+ <title>Set <varname>write_sdp_pv</varname> parameter</title>
<programlisting format="linespecific">
...
-modparam("rtpengine", "write_sdp_avp", "$avp(sdp)")
+modparam("rtpengine", "write_sdp_pv", "$avp(sdp)")
+ ... or
+modparam("rtpengine", "write_sdp_pv", "$pv(sdp)")
...
</programlisting>
</example>
diff --git a/modules/sanity/sanity.c b/modules/sanity/sanity.c
index 7e1842e..8140c07 100644
--- a/modules/sanity/sanity.c
+++ b/modules/sanity/sanity.c
@@ -652,19 +652,18 @@ int check_proxy_require(struct sip_msg* _msg) {
int u_len;
#ifdef EXTRA_DEBUG
- DBG("check_proxy_require entered\n");
+ LM_DBG("checking proxy require\n");
#endif
if (parse_headers(_msg, HDR_PROXYREQUIRE_F, 0) != 0) {
- LOG(L_WARN, "sanity_check(): check_proxy_require():"
- " failed to parse proxy require header\n");
+ LM_WARN("failed to parse proxy require header\n");
return SANITY_CHECK_FAILED;
}
if (_msg->proxy_require != NULL) {
- dump_hdr_field(_msg->proxy_require);
+ //dump_hdr_field(_msg->proxy_require);
if (_msg->proxy_require->parsed == NULL &&
parse_proxyrequire(_msg->proxy_require) < 0) {
- LOG(L_WARN, "sanity_check(): check_proxy_require(): parse_proxy_require failed\n");
+ LM_WARN("parse_proxy_require failed\n");
return SANITY_CHECK_FAILED;
}
r_pr = _msg->proxy_require->parsed;
@@ -672,7 +671,7 @@ int check_proxy_require(struct sip_msg* _msg) {
l_pr = proxyrequire_list;
while (l_pr != NULL) {
#ifdef EXTRA_DEBUG
- DBG("check_proxy_require(): comparing r='%.*s' l='%.*s'\n",
+ LM_DBG("comparing r='%.*s' l='%.*s'\n",
r_pr->string.len, r_pr->string.s, l_pr->string.len,
l_pr->string.s);
#endif
@@ -685,14 +684,12 @@ int check_proxy_require(struct sip_msg* _msg) {
l_pr = l_pr->next;
}
if (l_pr == NULL) {
- DBG("sanit_check(): check_proxy_require():"
- " request contains unsupported extension: %.*s\n",
+ LM_DBG("request contains unsupported extension: %.*s\n",
r_pr->string.len, r_pr->string.s);
u_len = UNSUPPORTED_HEADER_LEN + 2 + r_pr->string.len;
u = pkg_malloc(u_len);
if (u == NULL) {
- LOG(L_ERR, "sanity_check(): check_proxy_require():"
- " failed to allocate memory for"
+ LM_ERR("failed to allocate memory for"
" Unsupported header\n");
}
else {
@@ -706,12 +703,11 @@ int check_proxy_require(struct sip_msg* _msg) {
if (_msg->REQ_METHOD != METHOD_ACK) {
if (sanity_reply(_msg, 420, "Bad Extension") < 0) {
- LOG(L_WARN, "sanity_check(): check_proxy_require():"
- " failed to send 420 via sl reply\n");
+ LM_WARN("failed to send 420 via sl reply\n");
}
}
#ifdef EXTRA_DEBUG
- DBG("check_proxy_require failed\n");
+ LM_DBG("checking proxy require failed\n");
#endif
if (u) pkg_free(u);
return SANITY_CHECK_FAILED;
@@ -721,7 +717,7 @@ int check_proxy_require(struct sip_msg* _msg) {
}
}
#ifdef EXTRA_DEBUG
- DBG("check_proxy_require passed\n");
+ LM_DBG("checking proxy require passed\n");
#endif
if (_msg->proxy_require->parsed) {
/* TODO we have to free it here, because it is not automatically
@@ -732,7 +728,7 @@ int check_proxy_require(struct sip_msg* _msg) {
}
#ifdef EXTRA_DEBUG
else {
- DBG("check_proxy_require(): no proxy-require header found\n");
+ LM_DBG("no proxy-require header found\n");
}
#endif
diff --git a/modules/sctp/README b/modules/sctp/README
index 1fb71dc..c8f5ffa 100644
--- a/modules/sctp/README
+++ b/modules/sctp/README
@@ -235,7 +235,7 @@ modparam("sctp", "sctp_send_retries", 1)
better performance, but it will also disable some other features that
depend on it (e.g. sctp_assoc_reuse).
- Can be changed at runtime (sercmd sctp assoc_tracking 0), but changes
+ Can be changed at runtime (kamcmd sctp assoc_tracking 0), but changes
will be allowed only if all the other features that depend on it are
turned off (for example it can be turned off only if first
sctp_assoc_reuse was turned off).
diff --git a/modules/sctp/doc/sctp_admin.xml b/modules/sctp/doc/sctp_admin.xml
index 3ede4ca..2fc495a 100644
--- a/modules/sctp/doc/sctp_admin.xml
+++ b/modules/sctp/doc/sctp_admin.xml
@@ -194,7 +194,7 @@ modparam("sctp", "sctp_send_retries", 1)
features that depend on it (e.g. sctp_assoc_reuse).
</para>
<para>
- Can be changed at runtime (sercmd sctp assoc_tracking 0), but changes
+ Can be changed at runtime (&sercmd; sctp assoc_tracking 0), but changes
will be allowed only if all the other features that depend on it are
turned off (for example it can be turned off only if first
sctp_assoc_reuse was turned off).
diff --git a/modules/siptrace/siptrace.c b/modules/siptrace/siptrace.c
index 07e3a1a..df6ceff 100644
--- a/modules/siptrace/siptrace.c
+++ b/modules/siptrace/siptrace.c
@@ -535,6 +535,11 @@ static int sip_trace_prepare(sip_msg_t *msg)
goto error;
}
+ if(parse_to_header(msg)==-1 || msg->to==NULL || get_to(msg)==NULL) {
+ LM_ERR("cannot parse To header\n");
+ goto error;
+ }
+
if(parse_headers(msg, HDR_CALLID_F, 0)!=0 || msg->callid==NULL
|| msg->callid->body.s==NULL) {
LM_ERR("cannot parse call-id\n");
@@ -757,6 +762,11 @@ static int sip_trace_store(struct _siptrace_data *sto, struct dest_info *dst)
static int sip_trace_store_db(struct _siptrace_data *sto)
{
+ if(db_con==NULL) {
+ LM_DBG("database connection not initialized\n");
+ return -1;
+ }
+
if(trace_to_database_flag==NULL || *trace_to_database_flag==0)
goto done;
diff --git a/modules/sqlops/sql_var.c b/modules/sqlops/sql_var.c
index 940ec5a..9b8721b 100644
--- a/modules/sqlops/sql_var.c
+++ b/modules/sqlops/sql_var.c
@@ -104,7 +104,6 @@ int sql_parse_index(str *in, gparam_t *gp)
if (gp->v.pvs == NULL)
{
LM_ERR("no pkg memory left for pv_spec_t\n");
- pkg_free(gp);
return -1;
}
@@ -112,7 +111,6 @@ int sql_parse_index(str *in, gparam_t *gp)
{
LM_ERR("invalid PV identifier\n");
pkg_free(gp->v.pvs);
- pkg_free(gp);
return -1;
}
} else {
@@ -257,7 +255,9 @@ int pv_parse_dbr_name(pv_spec_p sp, str *in)
if(p>in->s+in->len || *p=='\0' || *p!=']')
goto error_index;
} else {
- LM_ERR("unknow key [%.*s]\n", pvs.len, pvs.s);
+ LM_ERR("unknown key [%.*s]\n", pvs.len, pvs.s);
+ if(spv!=NULL)
+ pkg_free(spv);
return -1;
}
sp->pvp.pvn.u.dname = (void*)spv;
diff --git a/modules/textops/textops.c b/modules/textops/textops.c
index 7c5e2af..9aaada6 100644
--- a/modules/textops/textops.c
+++ b/modules/textops/textops.c
@@ -2226,8 +2226,7 @@ static int hname_fixup(void** param, int param_no)
gp->v.str.s[gp->v.str.len] = ':';
gp->v.str.len++;
- if (parse_hname2(gp->v.str.s, gp->v.str.s
- + ((gp->v.str.len<4)?4:gp->v.str.len), &hdr)==0)
+ if (parse_hname2_short(gp->v.str.s, gp->v.str.s + gp->v.str.len, &hdr)==0)
{
LM_ERR("error parsing header name\n");
pkg_free(gp);
diff --git a/modules/textops/txt_var.c b/modules/textops/txt_var.c
index 0f704e3..41201f7 100644
--- a/modules/textops/txt_var.c
+++ b/modules/textops/txt_var.c
@@ -124,7 +124,7 @@ int tr_txt_eval_re(struct sip_msg *msg, tr_param_t *tp, int subtype,
return 0;
error:
- if (tp->type == TR_PARAM_SPEC) {
+ if (tp->type == TR_PARAM_SPEC && se!=NULL) {
subst_expr_free(se);
}
return -1;
diff --git a/modules/textopsx/textopsx.c b/modules/textopsx/textopsx.c
index 6e21242..b170eb8 100644
--- a/modules/textopsx/textopsx.c
+++ b/modules/textopsx/textopsx.c
@@ -544,7 +544,7 @@ static int fixup_hname_param(char *hname, struct hname_data** h) {
(*h)->hname.len = hname - (*h)->hname.s;
savec = *hname;
*hname = ':';
- parse_hname2((*h)->hname.s, (*h)->hname.s+(*h)->hname.len+3, &hdr);
+ parse_hname2_short((*h)->hname.s, (*h)->hname.s+(*h)->hname.len+1, &hdr);
*hname = savec;
if (hdr.type == HDR_ERROR_T) goto err;
diff --git a/modules/tm/README b/modules/tm/README
index 3e1ebec..0633b86 100644
--- a/modules/tm/README
+++ b/modules/tm/README
@@ -1317,7 +1317,7 @@ modparam("tm", "via1_matching", 1)
Default value is 0 (off).
Can be set at runtime, e.g.:
- $ sercmd cfg.set_now_int tm callid_matching 0
+ $ kamcmd cfg.set_now_int tm callid_matching 0
Example 1.33. Set callid_matching parameter
...
@@ -1634,7 +1634,7 @@ modparam("tm|usrloc", "xavp_contact", "ulattrs")
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
@@ -1662,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
@@ -1688,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
@@ -1737,14 +1737,14 @@ 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
deciding if the transaction is complete. In the referred block, you can
start a new branch which is required for failover of multiple outbound
flows (RFC 5626). Note that the set of commands which are usable within
- a branch_failure route is limited to a subset of the failure_route
+ a branch_failure route is limited to a subset of the failure_rotue
commands including logging, rewriting URI and initiating new branches.
Any other commands may generate errors or result in unpredictable
behavior. Note that whenever failure_route is entered, uri is reset to
@@ -1770,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
@@ -1800,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
@@ -1824,7 +1824,7 @@ 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.
@@ -1840,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.
@@ -1865,7 +1865,7 @@ if (t_newtran()) {
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
@@ -1880,7 +1880,7 @@ if (t_lookup_request()) {
};
...
-5.13. t_retransmit_reply()
+5.13. t_retransmit_reply()
Retransmits a reply sent previously by UAS transaction.
@@ -1889,7 +1889,7 @@ if (t_lookup_request()) {
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).
@@ -1899,7 +1899,7 @@ t_retransmit_reply();
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.
@@ -1913,23 +1913,23 @@ t_release();
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
@@ -1963,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
@@ -1982,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
@@ -2011,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
@@ -2030,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
@@ -2076,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
@@ -2095,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
@@ -2112,7 +2112,7 @@ 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
@@ -2127,7 +2127,7 @@ 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
@@ -2146,7 +2146,7 @@ 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.
@@ -2162,7 +2162,7 @@ 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
@@ -2177,7 +2177,7 @@ 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.
@@ -2191,7 +2191,7 @@ onreply_route[0]{
}
}
-5.32. t_is_canceled()
+5.32. t_is_canceled()
Returns true if the current transaction was canceled.
@@ -2204,7 +2204,7 @@ 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.
@@ -2218,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,
@@ -2243,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
@@ -2275,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.
@@ -2303,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
@@ -2343,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
@@ -2385,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
@@ -2437,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
@@ -2467,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:
@@ -2485,7 +2485,7 @@ if (t_check_status("(487)|(408)")) {
}
...
-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
@@ -2537,7 +2537,7 @@ 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
@@ -2556,7 +2556,7 @@ 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.
@@ -2571,7 +2571,7 @@ 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.
@@ -2583,7 +2583,7 @@ if(!t_relay()) {
}
...
-5.46. t_replicate([params])
+5.46. t_replicate([params])
Replicate the SIP request to a specific address.
@@ -2619,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.
@@ -2652,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
@@ -2661,6 +2661,9 @@ t_relay_to("0x01");
It overrides the e2e_cancel_reason setting (module parameter) for the
current transaction.
+ Note: the function has to be used when processing the INVITE (not when
+ processing the CANCEL).
+
See also: e2e_cancel_reason.
Example 1.87. t_set_no_e2e_cancel_reason usage
@@ -2673,7 +2676,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.
@@ -2692,7 +2695,7 @@ 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
@@ -2705,7 +2708,7 @@ if(!t_is_set("failure_route"))
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
@@ -2808,7 +2811,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.
@@ -2817,7 +2820,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.
@@ -2825,7 +2828,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
@@ -2863,7 +2866,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(),
@@ -2879,7 +2882,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
@@ -2899,7 +2902,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
diff --git a/modules/tm/doc/functions.xml b/modules/tm/doc/functions.xml
index 5146d40..217a5a2 100644
--- a/modules/tm/doc/functions.xml
+++ b/modules/tm/doc/functions.xml
@@ -1665,6 +1665,10 @@ t_relay_to("0x01");
parameter) for the current transaction.
</para>
<para>
+ Note: the function has to be used when processing the INVITE
+ (not when processing the CANCEL).
+ </para>
+ <para>
See also: <varname>e2e_cancel_reason</varname>.
</para>
<example>
diff --git a/modules/tm/doc/params.xml b/modules/tm/doc/params.xml
index 2e0099b..e85ebdc 100644
--- a/modules/tm/doc/params.xml
+++ b/modules/tm/doc/params.xml
@@ -1003,7 +1003,7 @@ modparam("tm", "via1_matching", 1)
<para>
Can be set at runtime, e.g.:
<programlisting>
- $ sercmd cfg.set_now_int tm callid_matching 0
+ $ &sercmd; cfg.set_now_int tm callid_matching 0
</programlisting>
</para>
<example>
diff --git a/modules/tm/t_append_branches.c b/modules/tm/t_append_branches.c
index b276d9e..2c296fb 100644
--- a/modules/tm/t_append_branches.c
+++ b/modules/tm/t_append_branches.c
@@ -106,17 +106,14 @@ int t_append_branches(void) {
set_branch_route(t->on_branch_delayed);
}
- outgoings = t->nr_of_outgoings;
-
- /* not really sure that the following is needed */
+ init_branch_iterator();
- set_branch_iterator(nr_branches-1);
- found = 0;
while((current_uri.s=next_branch( ¤t_uri.len, &q, &dst_uri, &path,
&bflags, &si, &ruid, &instance, &location_ua))) {
LM_DBG("Current uri %.*s\n",current_uri.len, current_uri.s);
- for (i=0; i<nr_branches; i++) {
+ found = 0;
+ for (i=0; i<outgoings; i++) {
if (t->uac[i].ruid.len == ruid.len
&& !memcmp(t->uac[i].ruid.s, ruid.s, ruid.len)) {
LM_DBG("branch already added [%.*s]\n", ruid.len, ruid.s);
@@ -131,8 +128,10 @@ int t_append_branches(void) {
new_branch=add_uac( t, orig_msg, ¤t_uri,
(dst_uri.len) ? (&dst_uri) : ¤t_uri,
&path, 0, si, orig_msg->fwd_send_flags,
- orig_msg->rcv.proto, (dst_uri.len)?-1:UAC_SKIP_BR_DST_F, &instance,
+ PROTO_NONE, (dst_uri.len)?-1:UAC_SKIP_BR_DST_F, &instance,
&ruid, &location_ua);
+
+ LM_DBG("added branch [%.*s] with ruid [%.*s]\n", current_uri.len, current_uri.s, ruid.len, ruid.s);
/* test if cancel was received meanwhile */
if (t->flags & T_CANCELED) goto canceled;
diff --git a/modules/tm/t_reply.c b/modules/tm/t_reply.c
index d14ed1c..0041a4f 100644
--- a/modules/tm/t_reply.c
+++ b/modules/tm/t_reply.c
@@ -982,6 +982,8 @@ int run_failure_handlers(struct cell *t, struct sip_msg *rpl,
* set next failure route, failure_route will not be reentered
* on failure */
t->on_failure=0;
+ /* if continuing on timeout of a suspended transaction, reset the flag */
+ t->flags &= ~T_ASYNC_SUSPENDED;
if (exec_pre_script_cb(&faked_req, FAILURE_CB_TYPE)>0) {
/* run a failure_route action if some was marked */
if (run_top_route(failure_rt.rlist[on_failure], &faked_req, 0)<0)
@@ -1729,6 +1731,7 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
str* to_tag;
str reason;
struct tmcb_params onsend_params;
+ struct ip_addr ip;
/* keep compiler warnings about use of uninit vars silent */
res_len=0;
@@ -1737,7 +1740,6 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
relayed_code=0;
totag_retr=0;
-
/* remember, what was sent upstream to know whether we are
* forwarding a first final reply or not */
@@ -1921,26 +1923,41 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch,
if (reply_status == RPS_COMPLETED) {
start_final_repl_retr(t);
}
- if (likely(uas_rb->dst.send_sock &&
- SEND_PR_BUFFER( uas_rb, buf, res_len ) >= 0)){
- if (unlikely(!totag_retr && has_tran_tmcbs(t, TMCB_RESPONSE_OUT))){
- LOCK_REPLIES( t );
- run_trans_callbacks_with_buf( TMCB_RESPONSE_OUT, uas_rb, t->uas.request,
- relayed_msg, relayed_code);
- UNLOCK_REPLIES( t );
+ if (likely(uas_rb->dst.send_sock)) {
+ if (onsend_route_enabled(SIP_REPLY) && p_msg && (p_msg != FAKED_REPLY)) {
+ if (run_onsend(p_msg, &uas_rb->dst, buf, res_len)==0){
+ su2ip_addr(&ip, &(uas_rb->dst.to));
+ LOG(L_ERR, "forward_reply: reply to %s:%d(%d) dropped"
+ " (onsend_route)\n", ip_addr2a(&ip),
+ su_getport(&(uas_rb->dst.to)), uas_rb->dst.proto);
+ /* workaround for drop - reset send_sock to skip sending out */
+ uas_rb->dst.send_sock = 0;
+ }
}
- if (unlikely(has_tran_tmcbs(t, TMCB_RESPONSE_SENT))){
- INIT_TMCB_ONSEND_PARAMS(onsend_params, t->uas.request,
- relayed_msg, uas_rb, &uas_rb->dst, buf,
- res_len,
- (relayed_msg==FAKED_REPLY)?TMCB_LOCAL_F:0,
- uas_rb->branch, relayed_code);
- LOCK_REPLIES( t );
- run_trans_callbacks_off_params(TMCB_RESPONSE_SENT, t, &onsend_params);
- UNLOCK_REPLIES( t );
+ }
+
+ if (likely(uas_rb->dst.send_sock)) {
+ if (SEND_PR_BUFFER( uas_rb, buf, res_len ) >= 0){
+ if (unlikely(!totag_retr && has_tran_tmcbs(t, TMCB_RESPONSE_OUT))){
+ LOCK_REPLIES( t );
+ run_trans_callbacks_with_buf( TMCB_RESPONSE_OUT, uas_rb, t->uas.request,
+ relayed_msg, relayed_code);
+ UNLOCK_REPLIES( t );
+ }
+ if (unlikely(has_tran_tmcbs(t, TMCB_RESPONSE_SENT))){
+ INIT_TMCB_ONSEND_PARAMS(onsend_params, t->uas.request,
+ relayed_msg, uas_rb, &uas_rb->dst, buf,
+ res_len,
+ (relayed_msg==FAKED_REPLY)?TMCB_LOCAL_F:0,
+ uas_rb->branch, relayed_code);
+ LOCK_REPLIES( t );
+ run_trans_callbacks_off_params(TMCB_RESPONSE_SENT, t, &onsend_params);
+ UNLOCK_REPLIES( t );
+ }
}
- } else if (unlikely(uas_rb->dst.send_sock == 0))
- ERR("no resolved dst to send reply to\n");
+ } else {
+ LM_NOTICE("dst no longer set - skiped sending the reply out\n");
+ }
/* Call put_on_wait() only if we really send out
* the reply. It can happen that the reply has been already sent from
* failure_route or from a callback and the timer has been already
@@ -2050,7 +2067,8 @@ enum rps local_reply( struct cell *t, struct sip_msg *p_msg, int branch,
}
if (local_winner>=0 && winning_code>=200 ) {
- DBG("DEBUG: local transaction completed\n");
+ DBG("DEBUG: local transaction completed %d/%d (totag retr: %d/%d)\n",
+ winning_code, local_winner, totag_retr, t->tmcb_hl.reg_types);
if (!totag_retr) {
if (unlikely(has_tran_tmcbs(t,TMCB_LOCAL_COMPLETED) ))
run_trans_callbacks( TMCB_LOCAL_COMPLETED, t, 0,
@@ -2285,10 +2303,21 @@ int reply_received( struct sip_msg *p_msg )
backup_xavps = xavp_set_list(&t->xavps_list);
#endif
setbflagsval(0, uac->branch_flags);
+ if(msg_status>last_uac_status) {
+ /* current response (msg) status is higher that the last received
+ * on the same branch - set it temporarily so functions in onreply_route
+ * can access it (e.g., avoid sending CANCEL by forcing another t_relply()
+ * in onreply_route when a negative sip response was received) */
+ uac->last_received = msg_status;
+ }
+
/* Pre- and post-script callbacks have already
* been executed by the core. (Miklos)
*/
run_top_route(onreply_rt.rlist[onreply_route], p_msg, &ctx);
+
+ /* restore brach last_received as before executing onreply_route */
+ uac->last_received = last_uac_status;
/* transfer current message context back to t */
if (t->uas.request) t->uas.request->flags=p_msg->flags;
getbflagsval(0, &uac->branch_flags);
diff --git a/modules/tm/t_suspend.c b/modules/tm/t_suspend.c
index 86fb3be..d0d854d 100644
--- a/modules/tm/t_suspend.c
+++ b/modules/tm/t_suspend.c
@@ -74,6 +74,11 @@ int t_suspend(struct sip_msg *msg,
ser_error = E_CANCELED;
return 1;
}
+ if (t->uas.status >= 200) {
+ LM_DBG("trasaction sent out a final response already - %d\n",
+ t->uas.status);
+ return -3;
+ }
if (msg->first_line.type != SIP_REPLY) {
/* send a 100 Trying reply, because the INVITE processing
@@ -106,10 +111,10 @@ int t_suspend(struct sip_msg *msg,
* - failure route to be executed if the branch is not continued
* before timeout */
t->uac[t->async_backup.blind_uac].on_failure = t->on_failure;
+ t->flags |= T_ASYNC_SUSPENDED;
} else {
LM_DBG("this is a suspend on reply - setting msg flag to SUSPEND\n");
msg->msg_flags |= FL_RPL_SUSPENDED;
- t->flags |= T_ASYNC_SUSPENDED;
/* this is a reply suspend find which branch */
if (t_check( msg , &branch )==-1){
@@ -131,6 +136,7 @@ int t_suspend(struct sip_msg *msg,
LM_DBG("saving transaction data\n");
t->uac[branch].reply->flags = msg->flags;
+ t->flags |= T_ASYNC_SUSPENDED;
}
*hash_index = t->hash_index;
@@ -176,7 +182,13 @@ int t_continue(unsigned int hash_index, unsigned int label,
return -1;
}
+ if (!(t->flags & T_ASYNC_SUSPENDED)) {
+ LM_WARN("transaction is not suspended [%u:%u]\n", hash_index, label);
+ return -2;
+ }
+
if (t->flags & T_CANCELED) {
+ t->flags &= ~T_ASYNC_SUSPENDED;
/* The transaction has already been canceled,
* needless to continue */
UNREF(t); /* t_unref would kill the transaction */
@@ -219,6 +231,7 @@ int t_continue(unsigned int hash_index, unsigned int label,
/* Either t_continue() has already been
* called or the branch has already timed out.
* Needless to continue. */
+ t->flags &= ~T_ASYNC_SUSPENDED;
UNLOCK_ASYNC_CONTINUE(t);
UNREF(t); /* t_unref would kill the transaction */
return 1;
@@ -298,7 +311,13 @@ int t_continue(unsigned int hash_index, unsigned int label,
LM_DBG("continuing from a suspended reply"
" - resetting the suspend branch flag\n");
+ if (t->uac[branch].reply) {
t->uac[branch].reply->msg_flags &= ~FL_RPL_SUSPENDED;
+ } else {
+ LM_WARN("no reply in t_continue for branch. not much we can do\n");
+ return 0;
+ }
+
if (t->uas.request) t->uas.request->msg_flags&= ~FL_RPL_SUSPENDED;
faked_env( t, t->uac[branch].reply, 1);
@@ -437,9 +456,14 @@ done:
sip_msg_free(t->uac[branch].reply);
t->uac[branch].reply = 0;
}
+
+ /*This transaction is no longer suspended so unsetting the SUSPEND flag*/
+ t->flags &= ~T_ASYNC_SUSPENDED;
+
return 0;
kill_trans:
+ t->flags &= ~T_ASYNC_SUSPENDED;
/* The script has hopefully set the error code. If not,
* let us reply with a default error. */
if ((kill_transaction_unsafe(t,
diff --git a/modules/tmrec/README b/modules/tmrec/README
index 84b7a56..afee28b 100644
--- a/modules/tmrec/README
+++ b/modules/tmrec/README
@@ -16,7 +16,15 @@ Alex Balashov
<abalashov at evaristesys.com>
+Edited by
+
+Richard Fuchs
+
+ <rfuchs at sipwise.com>
+
Copyright � 2012 asipto.com
+
+ Copyright � 2012 Sipwise GmbH
__________________________________________________________________
Table of Contents
@@ -138,7 +146,11 @@ modparam("tmrec", "separator", ";")
subsequent intervals do not overlap. For non-recurring intervals,
durations of any positive length are permitted. Zero-length
duration means "forever". Negative-length durations are not
- allowed. See RFC 2445 for the format of duration.
+ allowed.
+ See RFC 2445 for the format of duration. In short for common cases
+ when the duration doesn't exeed a data, it must start with PT
+ followed by the value for hours, minutes or seconds - e.g., a
+ duration of 8 hours must be written as PT8H.
* frequency - can be one of the following values: "daily" - specify
repeating periods based on an interval of a day or more; "weekly" -
specify repeating periods based on an interval of a week or more;
@@ -208,7 +220,7 @@ modparam("tmrec", "separator", ";")
Next is an example of evaluating multiple Byxxx parameters.
- startdate="20100101T093000" duration="10H30M" frequency="yearly"
+ startdate="20100101T093000" duration="PT10H30M" frequency="yearly"
interval="4" bymonth="3" byday="SU"
First, the interval="4" would be applied to frequency="yearly" to match
diff --git a/modules/tmrec/doc/tmrec_admin.xml b/modules/tmrec/doc/tmrec_admin.xml
index c70bdb2..b791226 100644
--- a/modules/tmrec/doc/tmrec_admin.xml
+++ b/modules/tmrec/doc/tmrec_admin.xml
@@ -126,9 +126,14 @@ modparam("tmrec", "separator", ";")
For a recurring interval, the <quote>duration</quote> parameter MUST
be small enough such that subsequent intervals do not overlap.
For non-recurring intervals, durations of any positive length are
- permitted. Zero-length duration means <quote>forever</quote>.
- Negative-length durations are not allowed. See RFC 2445 for
- the format of duration.
+ permitted. Zero-length duration means <quote>forever</quote>.
+ Negative-length durations are not allowed.
+ </para>
+ <para>
+ See RFC 2445 for the format of duration. In short for common cases
+ when the duration doesn't exeed a data, it must start with PT
+ followed by the value for hours, minutes or seconds - e.g., a
+ duration of 8 hours must be written as PT8H.
</para>
</listitem>
<listitem>
@@ -253,7 +258,7 @@ modparam("tmrec", "separator", ";")
Next is an example of evaluating multiple Byxxx parameters.
</para>
<para>
- startdate=<quote>20100101T093000</quote> duration=<quote>10H30M</quote>
+ startdate=<quote>20100101T093000</quote> duration=<quote>PT10H30M</quote>
frequency=<quote>yearly</quote> interval=<quote>4</quote>
bymonth=<quote>3</quote> byday=<quote>SU</quote>
</para>
diff --git a/modules/tmx/t_var.c b/modules/tmx/t_var.c
index 0338233..7b61a49 100644
--- a/modules/tmx/t_var.c
+++ b/modules/tmx/t_var.c
@@ -44,8 +44,6 @@ static struct _pv_tmx_data _pv_treq;
static struct _pv_tmx_data _pv_trpl;
static struct _pv_tmx_data _pv_tinv;
-static str _empty_str = {"", 0};
-
void pv_tmx_data_init(void)
{
memset(&_pv_treq, 0, sizeof(struct _pv_tmx_data));
@@ -442,6 +440,7 @@ int pv_get_tm_reply_ruid(struct sip_msg *msg, pv_param_t *param,
pv_value_t *res)
{
struct cell *t;
+ tm_ctx_t *tcx = 0;
int branch;
if(msg==NULL || res==NULL)
@@ -451,7 +450,7 @@ int pv_get_tm_reply_ruid(struct sip_msg *msg, pv_param_t *param,
if (_tmx_tmb.t_check( msg , 0 )==-1) return -1;
if ( (t=_tmx_tmb.t_gett())==0) {
/* no T */
- res->rs = _empty_str;
+ return pv_get_strempty(msg, param, res);
} else {
switch (get_route_type()) {
case FAILURE_ROUTE:
@@ -460,18 +459,27 @@ int pv_get_tm_reply_ruid(struct sip_msg *msg, pv_param_t *param,
if ( (branch=_tmx_tmb.t_get_picked_branch())<0 ) {
LM_CRIT("no picked branch (%d) for a final response"
" in MODE_ONFAILURE\n", branch);
- return -1;
+ return pv_get_strempty(msg, param, res);
}
- res->rs = t->uac[branch].ruid;
+ LM_DBG("reply ruid is [%.*s]\n", t->uac[branch].ruid.len, t->uac[branch].ruid.s);
+ return pv_get_strval(msg, param, res, &t->uac[branch].ruid);
break;
+ case TM_ONREPLY_ROUTE:
+ tcx = _tmx_tmb.tm_ctx_get();
+ if(tcx == NULL) {
+ return pv_get_strempty(msg, param, res);
+ }
+ branch = tcx->branch_index;
+ if(branch<0 || branch>=t->nr_of_outgoings) {
+ return pv_get_strempty(msg, param, res);
+ }
+ LM_DBG("reply ruid is [%.*s]\n", t->uac[branch].ruid.len, t->uac[branch].ruid.s);
+ return pv_get_strval(msg, param, res, &t->uac[branch].ruid);
default:
LM_ERR("unsupported route_type %d\n", get_route_type());
- return -1;
+ return pv_get_strempty(msg, param, res);
}
}
- LM_DBG("reply ruid is [%.*s]\n", res->rs.len, res->rs.s);
- res->flags = PV_VAL_STR;
- return 0;
}
int pv_get_tm_reply_code(struct sip_msg *msg, pv_param_t *param,
@@ -484,6 +492,14 @@ int pv_get_tm_reply_code(struct sip_msg *msg, pv_param_t *param,
if(msg==NULL || res==NULL)
return -1;
+ switch (get_route_type()) {
+ case CORE_ONREPLY_ROUTE:
+ case TM_ONREPLY_ROUTE:
+ /* use the status of the current reply */
+ code = msg->first_line.u.reply.statuscode;
+ goto done;
+ }
+
/* first get the transaction */
if (_tmx_tmb.t_check( msg , 0 )==-1) return -1;
if ( (t=_tmx_tmb.t_gett())==0) {
@@ -496,16 +512,6 @@ int pv_get_tm_reply_code(struct sip_msg *msg, pv_param_t *param,
/* use the status of the last sent reply */
code = t->uas.status;
break;
- case CORE_ONREPLY_ROUTE:
- /* t_check() above has the side effect of setting T and
- REFerencing T => we must unref and unset it for the
- main/core onreply_route. */
- _tmx_tmb.t_unref(msg);
- /* no break */
- case TM_ONREPLY_ROUTE:
- /* use the status of the current reply */
- code = msg->first_line.u.reply.statuscode;
- break;
case FAILURE_ROUTE:
case BRANCH_FAILURE_ROUTE:
/* use the status of the winning reply */
@@ -518,17 +524,16 @@ int pv_get_tm_reply_code(struct sip_msg *msg, pv_param_t *param,
}
break;
default:
- LM_ERR("unsupported route_type %d\n", get_route_type());
+ LM_INFO("unsupported route_type %d - code set to 0\n",
+ get_route_type());
code = 0;
}
}
- LM_DBG("reply code is <%d>\n",code);
-
- res->rs.s = int2str( code, &res->rs.len);
+done:
+ LM_DBG("reply code is <%d>\n", code);
+ return pv_get_sintval(msg, param, res, code);
- res->ri = code;
- res->flags = PV_VAL_STR|PV_VAL_INT|PV_TYPE_INT;
return 0;
}
@@ -546,7 +551,7 @@ int pv_get_tm_reply_reason(struct sip_msg *msg, pv_param_t *param,
if (_tmx_tmb.t_check( msg , 0 )==-1) return -1;
if ( (t=_tmx_tmb.t_gett())==0) {
/* no T */
- res->rs = _empty_str;
+ return pv_get_strempty(msg, param, res);
} else {
switch (get_route_type()) {
case CORE_ONREPLY_ROUTE:
diff --git a/modules/tmx/tmx_mod.c b/modules/tmx/tmx_mod.c
index 28dbcd7..d2d8e60 100644
--- a/modules/tmx/tmx_mod.c
+++ b/modules/tmx/tmx_mod.c
@@ -638,7 +638,7 @@ static int w_t_continue(struct sip_msg* msg, char *idx, char *lbl, char *rtn)
if(_tmx_tmb.t_continue(tindex, tlabel, act)<0)
{
- LM_ERR("resuming the processing of transaction [%u:%u] failed\n",
+ LM_WARN("resuming the processing of transaction [%u:%u] failed\n",
tindex, tlabel);
return -1;
}
diff --git a/modules/tmx/tmx_pretran.c b/modules/tmx/tmx_pretran.c
index 1691432..00f571b 100644
--- a/modules/tmx/tmx_pretran.c
+++ b/modules/tmx/tmx_pretran.c
@@ -210,7 +210,10 @@ int tmx_check_pretran(sip_msg_t *msg)
LM_ERR("failed to parse required headers\n");
return -1;
}
-
+ if(msg->cseq==NULL || msg->cseq->parsed==NULL) {
+ LM_ERR("failed to parse cseq headers\n");
+ return -1;
+ }
if(get_cseq(msg)->method_id==METHOD_ACK
|| get_cseq(msg)->method_id==METHOD_CANCEL) {
LM_DBG("no pre-transaction management for ACK or CANCEL\n");
@@ -224,6 +227,10 @@ int tmx_check_pretran(sip_msg_t *msg)
LM_ERR("failed to get From header\n");
return -1;
}
+ if (msg->callid==NULL || msg->callid->body.s==NULL) {
+ LM_ERR("failed to parse callid headers\n");
+ return -1;
+ }
vbr = msg->via1->branch;
diff --git a/modules/tsilo/ts_append.c b/modules/tsilo/ts_append.c
index b2a9a9a..100fcec 100644
--- a/modules/tsilo/ts_append.c
+++ b/modules/tsilo/ts_append.c
@@ -69,6 +69,7 @@ int ts_append(struct sip_msg* msg, str *ruri, char *table) {
int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table) {
struct cell *t;
struct sip_msg *orig_msg;
+ int ret;
if(_tmb.t_lookup_ident(&t, tindex, tlabel) < 0)
{
@@ -76,12 +77,23 @@ int ts_append_to(struct sip_msg* msg, int tindex, int tlabel, char *table) {
tindex, tlabel);
return -1;
}
+ if (t->flags & T_CANCELED) {
+ LM_DBG("trasaction [%u:%u] was cancelled\n",
+ tindex, tlabel);
+ return -2;
+ }
+ if (t->uas.status >= 200) {
+ LM_DBG("trasaction [%u:%u] sent out a final response already - %d\n",
+ tindex, tlabel, t->uas.status);
+ return -3;
+ }
orig_msg = t->uas.request;
- if (_regapi.lookup_to_dset(orig_msg, table, NULL) != 1) {
- LM_DBG("transaction %u:%u: error updating dset\n", tindex, tlabel);
- return -1;
+ ret = _regapi.lookup_to_dset(orig_msg, table, NULL);
+ if(ret != 1) {
+ LM_DBG("transaction %u:%u: error updating dset (%d)\n", tindex, tlabel, ret);
+ return -4;
}
return _tmb.t_append_branches();
diff --git a/modules/tsilo/ts_handlers.c b/modules/tsilo/ts_handlers.c
index 7cf7970..c04ec36 100644
--- a/modules/tsilo/ts_handlers.c
+++ b/modules/tsilo/ts_handlers.c
@@ -40,14 +40,11 @@ int ts_set_tm_callbacks(struct cell *t, sip_msg_t *req, ts_transaction_t *ts)
if(t==NULL)
return -1;
- if ( (ts_clone=clone_ts_transaction(ts)) < 0 ) {
+ if ( (ts_clone=clone_ts_transaction(ts)) == NULL ) {
LM_ERR("failed to clone transaction\n");
return -1;
}
- if (ts_clone == NULL) {
- LM_ERR("transaction clone null\n");
- }
if ( _tmb.register_tmcb( req, t,TMCB_DESTROY,
ts_onreply, (void*)ts_clone, free_ts_transaction)<0 ) {
LM_ERR("failed to register TMCB for transaction %d:%d\n", t->hash_index, t->label);
@@ -89,7 +86,7 @@ void ts_onreply(struct cell* t, int type, struct tmcb_params *param)
}
ptr = ptr->next;
}
- LM_DBG("transaction %u:%u not found\n",ptr->tindex, ptr->tlabel);
+ LM_DBG("transaction %u:%u not found\n",cb_ptr->tindex, cb_ptr->tlabel);
unlock_entry(_e);
} else {
LM_DBG("called with uknown type %d\n", type);
diff --git a/modules/tsilo/ts_hash.c b/modules/tsilo/ts_hash.c
index cf529ee..7986991 100644
--- a/modules/tsilo/ts_hash.c
+++ b/modules/tsilo/ts_hash.c
@@ -396,8 +396,8 @@ void remove_ts_transaction(ts_transaction_t* ts_t)
if (ts_t->prev)
ts_t->prev->next = ts_t->next;
- if ((ts_t->prev == NULL) && (ts_t->next == NULL))
- ts_t->urecord->transactions = NULL;
+ if (ts_t->urecord->transactions == ts_t)
+ ts_t->urecord->transactions = ts_t->next;
free_ts_transaction((void*)ts_t);
diff --git a/modules/tsilo/ts_store.c b/modules/tsilo/ts_store.c
index 67dc2d6..a05a4ef 100644
--- a/modules/tsilo/ts_store.c
+++ b/modules/tsilo/ts_store.c
@@ -43,21 +43,28 @@ int ts_store(struct sip_msg* msg) {
struct cell *t;
str aor;
struct sip_uri ruri;
+ str suri;
ts_urecord_t* r;
int res;
-
+ if (msg->new_uri.s!=NULL) {
+ /* incoming r-uri was chaged by cfg or other component */
+ suri = msg->new_uri;
+ } else {
+ /* no changes to incoming r-uri */
+ suri = msg->first_line.u.request.uri;
+ }
if (use_domain) {
- aor = msg->first_line.u.request.uri;
+ aor = suri;
}
else {
- if (parse_uri(msg->first_line.u.request.uri.s, msg->first_line.u.request.uri.len, &ruri)!=0)
+ if (parse_uri(suri.s, suri.len, &ruri)!=0)
{
LM_ERR("bad uri [%.*s]\n",
- msg->first_line.u.request.uri.len,
- msg->first_line.u.request.uri.s);
+ suri.len,
+ suri.s);
return -1;
}
aor = ruri.user;
diff --git a/modules/uac/uac_reg.c b/modules/uac/uac_reg.c
index 0cff689..7b7d2de 100644
--- a/modules/uac/uac_reg.c
+++ b/modules/uac/uac_reg.c
@@ -928,8 +928,13 @@ int uac_reg_update(reg_uac_t *reg, time_t tn)
return -1;
if(reg->expires==0)
return 1;
- if(reg->flags&UAC_REG_ONGOING)
- return 2;
+ if(reg->flags&UAC_REG_ONGOING) {
+ if (reg->timer_expires > tn - reg_retry_interval)
+ return 2;
+ LM_DBG("record marked as ongoing registration (%d) - resetting\n",
+ (int)reg->flags);
+ reg->flags &= ~(UAC_REG_ONLINE|UAC_REG_AUTHSENT);
+ }
if(reg->flags&UAC_REG_DISABLED)
return 4;
if(reg->timer_expires > tn + reg_timer_interval + 3)
diff --git a/modules/usrloc/ul_mi.c b/modules/usrloc/ul_mi.c
index 561b387..3e158d6 100644
--- a/modules/usrloc/ul_mi.c
+++ b/modules/usrloc/ul_mi.c
@@ -34,6 +34,7 @@
#include "../../ut.h"
#include "../../qvalue.h"
#include "../../ip_addr.h"
+#include "../../dset.h"
#include "ul_mi.h"
#include "dlist.h"
#include "udomain.h"
@@ -111,7 +112,8 @@ static inline int mi_fix_aor(str *aor)
if (p)
aor->len = p - aor->s;
}
- strlower(aor);
+ if(!get_aor_case_sensitive())
+ strlower(aor);
return 0;
}
diff --git a/modules/usrloc/ul_rpc.c b/modules/usrloc/ul_rpc.c
index c4e234e..e547c21 100644
--- a/modules/usrloc/ul_rpc.c
+++ b/modules/usrloc/ul_rpc.c
@@ -18,6 +18,7 @@
#include "../../ip_addr.h"
#include "../../dprint.h"
+#include "../../dset.h"
#include "../../lib/srutils/sruid.h"
#include "ul_rpc.h"
@@ -321,7 +322,8 @@ static inline int rpc_fix_aor(str *aor)
if (p)
aor->len = p - aor->s;
}
- strlower(aor);
+ if(!get_aor_case_sensitive())
+ strlower(aor);
return 0;
}
diff --git a/modules/utils/functions.c b/modules/utils/functions.c
index d32d970..97d1700 100644
--- a/modules/utils/functions.c
+++ b/modules/utils/functions.c
@@ -2,7 +2,7 @@
* script functions of utils module
*
* Copyright (C) 2008 Juha Heinanen
- * Copyright (C) 2013 Carsten Bock, ng-voice GmbH
+ * Copyright (C) 2013-2015 Carsten Bock, ng-voice GmbH
*
* This file is part of Kamailio, a free SIP server.
*
@@ -54,25 +54,23 @@ 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;
- stream->buf = (char *) pkg_realloc(stream->buf, stream->curr_size +
- (size * nmemb) + 1);
+ char *tmp = (char *) pkg_realloc(stream->buf, stream->curr_size +
+ (size * nmemb));
- if (stream->buf == NULL) {
+ if (tmp == NULL) {
LM_ERR("cannot allocate memory for stream\n");
return CURLE_WRITE_ERROR;
}
+ stream->buf = tmp;
memcpy(&stream->buf[stream->pos], (char *) ptr, (size * nmemb));
- stream->curr_size += ((size * nmemb) + 1);
+ stream->curr_size += (size * nmemb);
stream->pos += (size * nmemb);
- stream->buf[stream->pos + 1] = '\0';
-
return size * nmemb;
}
-
/*
* Performs http_query and saves possible result (first body line of reply)
* to pvar.
diff --git a/parser/case_reas.h b/parser/case_reas.h
index e6b8d97..5df0a9d 100644
--- a/parser/case_reas.h
+++ b/parser/case_reas.h
@@ -49,7 +49,7 @@
#define reas_CASE \
p += 4; \
- val = READ(p); \
+ val = SAFE_READ(p, end - p); \
ON_CASE; \
goto other;
diff --git a/parser/parse_hname2.c b/parser/parse_hname2.c
index c90d3e5..9db38af 100644
--- a/parser/parse_hname2.c
+++ b/parser/parse_hname2.c
@@ -95,11 +95,26 @@ static inline char* skip_ws(char* p, unsigned int size)
/*@} */
+#define SAFE_READ(val, len) \
+((len) == 1 ? READ1(val) : ((len) == 2 ? READ2(val) : ((len) == 3 ? READ3(val) : ((len) > 3 ? READ4(val) : READ0(val)))))
+
#define READ(val) \
-(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24))
+READ4(val)
+
+#define READ4(val) \
+(*((val) + 0) + (*((val) + 1) << 8) + (*((val) + 2) << 16) + (*((val) + 3) << 24))
#define READ3(val) \
-(*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16))
+(*((val) + 0) + (*((val) + 1) << 8) + (*((val) + 2) << 16))
+
+#define READ2(val) \
+(*((val) + 0) + (*((val) + 1) << 8))
+
+#define READ1(val) \
+(*((val) + 0))
+
+#define READ0(val) \
+(0)
#define FIRST_QUATERNIONS \
case _via1_: via1_CASE; \
@@ -242,3 +257,37 @@ char* parse_hname2(char* const begin, const char* const end, struct hdr_field* c
}
}
+/**
+ * parse_hname2_short() - safer version to parse header name stored in short buffers
+ * - parse_hanem2() reads 4 bytes at once, expecting to walk through a buffer
+ * that contains more than the header name (e.g., sip msg buf, full header buf
+ * with name and body)
+ */
+char* parse_hname2_short(char* const begin, const char* const end, struct hdr_field* const hdr)
+{
+#define HBUF_MAX_SIZE 256
+ char hbuf[HBUF_MAX_SIZE];
+ char *p;
+
+ if(end-begin>=HBUF_MAX_SIZE-4) {
+ p = q_memchr(begin, ':', end - begin);
+ if(p && p-4> begin) {
+ /* header name termination char found and enough space in buffer after it */
+ return parse_hname2(begin, end, hdr);
+ }
+ /* not enough space */
+ LM_ERR("not enough space to parse the header name in [%.*s] (%d)\n",
+ (int)(end-begin), begin, (int)(end-begin));
+ return NULL;
+ }
+ /* pad with whitespace - tipycal char after the ':' of the header name */
+ memset(hbuf, ' ', HBUF_MAX_SIZE);
+ memcpy(hbuf, begin, end-begin);
+ p = parse_hname2(hbuf, hbuf + 4 + (end-begin), hdr);
+ if(!p) {
+ LM_ERR("failed to parse the header name in [%.*s] (%d)\n",
+ (int)(end-begin), begin, (int)(end-begin));
+ return NULL;
+ }
+ return begin + (p-hbuf);
+}
diff --git a/parser/parse_hname2.h b/parser/parse_hname2.h
index 6f5b76b..fae4b56 100644
--- a/parser/parse_hname2.h
+++ b/parser/parse_hname2.h
@@ -36,5 +36,6 @@
* @file
*/
char* parse_hname2(char* const begin, const char* const end, struct hdr_field* const hdr);
+char* parse_hname2_short(char* const begin, const char* const end, struct hdr_field* const hdr);
#endif /* PARSE_HNAME2_H */
diff --git a/parser/parse_retry_after.c b/parser/parse_retry_after.c
index a467cf2..59e52d7 100644
--- a/parser/parse_retry_after.c
+++ b/parser/parse_retry_after.c
@@ -72,8 +72,6 @@ found:
/* find the end of header */
for (; t<end; t++){
if (*t=='\n'){
- if (((t+1)<end) && (*(t+1)=='\r'))
- t++;
if (((t+1)<end) && (*(t+1)==' ' || *(t+1)=='\t')){
t++;
continue; /* line folding ... */
diff --git a/pkg/kamailio/centos/6/kamailio.spec b/pkg/kamailio/centos/6/kamailio.spec
index 85acc45..0ae8960 100644
--- a/pkg/kamailio/centos/6/kamailio.spec
+++ b/pkg/kamailio/centos/6/kamailio.spec
@@ -1,5 +1,5 @@
%define name kamailio
-%define ver 4.3.1
+%define ver 4.3.3
%define rel 0.0%{dist}
diff --git a/pkg/kamailio/deb/debian/changelog b/pkg/kamailio/deb/debian/changelog
index 83355a8..cf814c5 100644
--- a/pkg/kamailio/deb/debian/changelog
+++ b/pkg/kamailio/deb/debian/changelog
@@ -1,3 +1,15 @@
+kamailio (4.3.3) unstable; urgency=medium
+
+ * update version to 4.3.3
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Fri, 02 Oct 2015 13:25:18 +0200
+
+kamailio (4.3.2) unstable; urgency=medium
+
+ * update version to 4.3.2
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Thu, 10 Sep 2015 12:15:40 +0200
+
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
diff --git a/pkg/kamailio/deb/jessie/changelog b/pkg/kamailio/deb/jessie/changelog
index 83355a8..cf814c5 100644
--- a/pkg/kamailio/deb/jessie/changelog
+++ b/pkg/kamailio/deb/jessie/changelog
@@ -1,3 +1,15 @@
+kamailio (4.3.3) unstable; urgency=medium
+
+ * update version to 4.3.3
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Fri, 02 Oct 2015 13:25:18 +0200
+
+kamailio (4.3.2) unstable; urgency=medium
+
+ * update version to 4.3.2
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Thu, 10 Sep 2015 12:15:40 +0200
+
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
diff --git a/pkg/kamailio/deb/precise/changelog b/pkg/kamailio/deb/precise/changelog
index 83355a8..cf814c5 100644
--- a/pkg/kamailio/deb/precise/changelog
+++ b/pkg/kamailio/deb/precise/changelog
@@ -1,3 +1,15 @@
+kamailio (4.3.3) unstable; urgency=medium
+
+ * update version to 4.3.3
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Fri, 02 Oct 2015 13:25:18 +0200
+
+kamailio (4.3.2) unstable; urgency=medium
+
+ * update version to 4.3.2
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Thu, 10 Sep 2015 12:15:40 +0200
+
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
diff --git a/pkg/kamailio/deb/squeeze/changelog b/pkg/kamailio/deb/squeeze/changelog
index 83355a8..cf814c5 100644
--- a/pkg/kamailio/deb/squeeze/changelog
+++ b/pkg/kamailio/deb/squeeze/changelog
@@ -1,3 +1,15 @@
+kamailio (4.3.3) unstable; urgency=medium
+
+ * update version to 4.3.3
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Fri, 02 Oct 2015 13:25:18 +0200
+
+kamailio (4.3.2) unstable; urgency=medium
+
+ * update version to 4.3.2
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Thu, 10 Sep 2015 12:15:40 +0200
+
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
diff --git a/pkg/kamailio/deb/trusty/changelog b/pkg/kamailio/deb/trusty/changelog
index 83355a8..cf814c5 100644
--- a/pkg/kamailio/deb/trusty/changelog
+++ b/pkg/kamailio/deb/trusty/changelog
@@ -1,3 +1,15 @@
+kamailio (4.3.3) unstable; urgency=medium
+
+ * update version to 4.3.3
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Fri, 02 Oct 2015 13:25:18 +0200
+
+kamailio (4.3.2) unstable; urgency=medium
+
+ * update version to 4.3.2
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Thu, 10 Sep 2015 12:15:40 +0200
+
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
diff --git a/pkg/kamailio/deb/wheezy/changelog b/pkg/kamailio/deb/wheezy/changelog
index 83355a8..cf814c5 100644
--- a/pkg/kamailio/deb/wheezy/changelog
+++ b/pkg/kamailio/deb/wheezy/changelog
@@ -1,3 +1,15 @@
+kamailio (4.3.3) unstable; urgency=medium
+
+ * update version to 4.3.3
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Fri, 02 Oct 2015 13:25:18 +0200
+
+kamailio (4.3.2) unstable; urgency=medium
+
+ * update version to 4.3.2
+
+ -- Victor Seva <linuxmaniac at torreviejawireless.org> Thu, 10 Sep 2015 12:15:40 +0200
+
kamailio (4.3.1) unstable; urgency=medium
* update version to 4.3.1
diff --git a/pkg/kamailio/fedora/17/kamailio.spec b/pkg/kamailio/fedora/17/kamailio.spec
index a776215..e71b1b1 100644
--- a/pkg/kamailio/fedora/17/kamailio.spec
+++ b/pkg/kamailio/fedora/17/kamailio.spec
@@ -1,5 +1,5 @@
%define name kamailio
-%define ver 4.3.1
+%define ver 4.3.3
%define rel 0%{dist}
diff --git a/pkg/kamailio/rpm/kamailio.spec-4.1 b/pkg/kamailio/rpm/kamailio.spec-4.1
index 1ae56f4..b2bfa21 100644
--- a/pkg/kamailio/rpm/kamailio.spec-4.1
+++ b/pkg/kamailio/rpm/kamailio.spec-4.1
@@ -1,5 +1,5 @@
%define name kamailio
-%define ver 4.3.1
+%define ver 4.3.3
%define rel 0
%define EXCLUDED_MODULES mysql jabber cpl-c avp_radius auth_radius group_radius uri_radius pa postgres osp tlsops unixodbc
diff --git a/pkg/kamailio/rpm/kamailio.spec.CenOS b/pkg/kamailio/rpm/kamailio.spec.CenOS
index 25257e9..ca7017d 100644
--- a/pkg/kamailio/rpm/kamailio.spec.CenOS
+++ b/pkg/kamailio/rpm/kamailio.spec.CenOS
@@ -1,5 +1,5 @@
%define name kamailio
-%define ver 4.3.1
+%define ver 4.3.3
%define rel 0
%define _sharedir %{_prefix}/share
diff --git a/pkg/kamailio/rpm/kamailio.spec.SuSE b/pkg/kamailio/rpm/kamailio.spec.SuSE
index ea3cc52..c181112 100644
--- a/pkg/kamailio/rpm/kamailio.spec.SuSE
+++ b/pkg/kamailio/rpm/kamailio.spec.SuSE
@@ -1,5 +1,5 @@
%define name kamailio
-%define ver 4.3.1
+%define ver 4.3.3
%define rel 0
%define EXCLUDED_MODULES mysql jabber cpl-c auth_radius misc_radius peering postgress pa unixodbc osp tlsops
diff --git a/pvapi.c b/pvapi.c
index d60aebc..c6b9d5b 100644
--- a/pvapi.c
+++ b/pvapi.c
@@ -608,6 +608,21 @@ int pv_get_null(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
/**
*
*/
+int pv_get_strempty(struct sip_msg *msg, pv_param_t *param, pv_value_t *res)
+{
+ if(res==NULL)
+ return -1;
+
+ res->rs = pv_str_empty;
+ res->ri = 0;
+ res->flags = PV_VAL_STR;
+ return 0;
+}
+
+
+/**
+ *
+ */
pv_export_t* pv_lookup_spec_name(str *pvname, pv_spec_p e)
{
pv_item_t *pvi;
diff --git a/pvar.h b/pvar.h
index 3bdfe17..8cc8488 100644
--- a/pvar.h
+++ b/pvar.h
@@ -210,6 +210,7 @@ str* pv_cache_get_name(pv_spec_t *spec);
/*! \brief PV helper functions */
int pv_get_null(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
+int pv_get_strempty(struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
int pv_get_uintval(struct sip_msg *msg, pv_param_t *param,
pv_value_t *res, unsigned int uival);
diff --git a/rvalue.c b/rvalue.c
index 52c12ed..e4524f5 100644
--- a/rvalue.c
+++ b/rvalue.c
@@ -997,16 +997,20 @@ rv_str:
/* if "" => 0 (most likely case) */
if (likely(s->len==0)) *i=0;
else if (unlikely(str2sint(s, i)!=0)){
- /* error converting to int => non numeric => 0 */
- *i=0;
+ /* dec to int failed, try hex to int */
+ if(!(s->len>2 && s->s[0]=='0' && (s->s[1]=='x' || s->s[1]=='X')
+ && (hexstr2int(s->s+2, s->len-2, (unsigned int*)i)==0))) {
+ /* error converting to int => non numeric => 0 */
+ *i=0;
#ifdef RV_STR2INT_VERBOSE_ERR
- WARN("automatic string to int conversion for \"%.*s\" failed\n",
+ WARN("automatic string to int conversion for \"%.*s\" failed\n",
s->len, ZSW(s->s));
- /* return an error code */
+ /* return an error code */
#endif
#ifdef RV_STR2INT_ERR
- ret=-1;
+ ret=-1;
#endif
+ }
}
if (destroy_pval)
pv_value_destroy(&pval);
diff --git a/select_core.c b/select_core.c
index d16f59d..a6e6901 100644
--- a/select_core.c
+++ b/select_core.c
@@ -619,7 +619,7 @@ int select_anyheader(str* res, select_t* s, struct sip_msg* msg)
/* if header name is parseable, parse it and set SEL_PARAM_DIV */
c=s->params[2].v.s.s[s->params[2].v.s.len];
s->params[2].v.s.s[s->params[2].v.s.len]=':';
- if (parse_hname2(s->params[2].v.s.s,s->params[2].v.s.s+(s->params[2].v.s.len<3?4:s->params[2].v.s.len+1),
+ if (parse_hname2_short(s->params[2].v.s.s,s->params[2].v.s.s+(s->params[2].v.s.len<3?4:s->params[2].v.s.len+1),
&hdr)==0) {
LM_ERR("fixup_call:parse error\n");
return -1;
diff --git a/sr_module.c b/sr_module.c
index 216c953..057bf02 100644
--- a/sr_module.c
+++ b/sr_module.c
@@ -459,6 +459,8 @@ int load_module(char* mod_path)
int new_dlflags;
int retries;
int path_type;
+ str expref;
+ char exbuf[64];
#ifndef RTLD_NOW
/* for openbsd */
@@ -611,9 +613,24 @@ reload:
}
}
exp = (union module_exports_u*)dlsym(handle, DLSYM_PREFIX "exports");
- if ( (error =(char*)dlerror())!=0 ){
- LM_ERR("%s\n", error);
- goto error1;
+ if(exp==NULL) {
+ /* 'exports' structure not found, look up for '_modulename_exports' */
+ mdir = strrchr(mod_path, '/');
+ if (!mdir) {
+ expref.s = mod_path;
+ } else {
+ expref.s = mdir+1;
+ }
+ expref.len = strlen(expref.s);
+ if(expref.len>3 && strcmp(expref.s+expref.len-3, ".so")==0)
+ expref.len -= 3;
+ snprintf(exbuf, 62, DLSYM_PREFIX "_%.*s_exports", expref.len, expref.s);
+ exp = (union module_exports_u*)dlsym(handle, exbuf);
+ LM_DBG("looking up exports with name: %s\n", exbuf);
+ if ( (error =(char*)dlerror())!=0 ){
+ LM_ERR("%s\n", error);
+ goto error1;
+ }
}
/* hack to allow for kamailio style dlflags inside exports */
if (*mod_if_ver == 1) {
diff --git a/tcp_main.c b/tcp_main.c
index df778ba..578f7d2 100644
--- a/tcp_main.c
+++ b/tcp_main.c
@@ -4113,6 +4113,7 @@ inline static int handle_tcpconn_ev(struct tcp_connection* tcpconn, short ev,
if (unlikely(io_watch_chg(&io_h, tcpconn->s, POLLOUT, fd_i)==-1)){
LM_ERR("io_watch_chg(2) failed: for %p, fd %d\n",
tcpconn, tcpconn->s);
+ tcpconn->flags&=~F_CONN_WRITE_W;
goto error;
}
}else
diff --git a/utils/kamcmd/kamcmd.c b/utils/kamcmd/kamcmd.c
index 86d8fc4..3381631 100644
--- a/utils/kamcmd/kamcmd.c
+++ b/utils/kamcmd/kamcmd.c
@@ -3,19 +3,19 @@
*
* Copyright (C) 2006 iptelorg GmbH
*
- * This file is part of ser, a free SIP server.
+ * This file is part of kamailio, a free SIP server.
*
- * ser is free software; you can redistribute it and/or modify
+ * kamailio is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version
*
- * For a license to use the ser software under conditions
+ * For a license to use the kamailio software under conditions
* other than those described here, or to purchase support for this
* software, please contact iptel.org by e-mail at the following addresses:
* info at iptel.org
*
- * ser is distributed in the hope that it will be useful,
+ * kamailio is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
@@ -82,12 +82,20 @@
#ifndef UNIX_PATH_MAX
-#define UNIX_PATH_MAX 108
+#define UNIX_PATH_MAX 100
#endif
static char id[]="$Id$";
static char version[]= NAME " " VERSION;
+#ifdef VERSION_NODATE
+static char compiled[] = "";
+#else
+#ifdef VERSION_DATE
+static char compiled[]= VERSION_DATE;
+#else
static char compiled[]= __TIME__ " " __DATE__;
+#endif
+#endif
static char help_msg[]="\
Usage: " NAME " [options][-s address] [ cmd ]\n\
Options:\n\
@@ -111,7 +119,7 @@ arg:\n\
string or number; to force a number to be interpreted as string \n\
prefix it by \"s:\", e.g. s:1\n\
Examples:\n\
- " NAME " -s unixs:/tmp/ser_unix system.listMethods\n\
+ " NAME " -s unixs:/tmp/" NAME "_ctl system.listMethods\n\
" NAME " -f \"pid: %v desc: %v\\n\" -s udp:localhost:2047 core.ps \n\
" NAME " ps # uses default ctl socket \n\
" NAME " # enters interactive mode on the default socket \n\
@@ -884,7 +892,7 @@ static int print_body(struct binrpc_parse_ctx* in_pkt,
read_value:
val.name.s=0;
val.name.len=0;
- p=binrpc_read_record(in_pkt, p, end, &val, &ret);
+ p=binrpc_read_record(in_pkt, p, end, &val, 1, &ret);
if (ret<0){
if (fmt)
putchar('\n');
@@ -894,7 +902,7 @@ read_value:
printf("end of message detected\n");
break;
}
- fprintf(stderr, "ERROR while parsing the record %d,"
+ fprintf(stderr, "ERROR:: while parsing the record %d,"
" @%d: %02x : %s\n", rec,
in_pkt->offset, *p, binrpc_error(ret));
goto error;
@@ -1153,13 +1161,13 @@ static struct binrpc_val* parse_reply_body(int* records,
val.type=BINRPC_T_ALL;
val.name.s=0;
val.name.len=0;
- p=binrpc_read_record(in_pkt, p, end, &val, &ret);
+ p=binrpc_read_record(in_pkt, p, end, &val, 1, &ret);
if (ret<0){
if (ret==E_BINRPC_EOP){
printf("end of message detected\n");
break;
}
- fprintf(stderr, "ERROR while parsing the record %d,"
+ fprintf(stderr, "ERROR: while parsing the record %d,"
" @%d: %02x : %s\n", rec,
in_pkt->offset, *p, binrpc_error(ret));
goto error;
@@ -2247,12 +2255,12 @@ int main(int argc, char** argv)
srand(getpid()+time(0)); /* we don't need very strong random numbers */
if (sock_name==0){
- fprintf(stderr, "ERROR: no ser address specified\n");
+ fprintf(stderr, "ERROR: no server socket address specified\n");
goto error;
}
sock_id=parse_listen_id(sock_name, strlen(sock_name), sock_type);
if (sock_id==0){
- fprintf(stderr, "ERROR: error parsing ser address %s\n", sock_name);
+ fprintf(stderr, "ERROR: error parsing server socket address %s\n", sock_name);
goto error;
}
--
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-voip/kamailio.git
More information about the Pkg-voip-commits
mailing list