From 453a2eb8e37829b489f1e7912fae5d2865ae6ace Mon Sep 17 00:00:00 2001 From: Victor Seva Date: Mon, 5 Oct 2015 16:06:02 +0200 Subject: [PATCH] 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 +- .../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(-) create mode 100644 modules/ims_registrar_scscf/README diff --git a/ChangeLog b/ChangeLog index e9f597b14..6a662d250 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 +Date: Fri Oct 2 14:29:11 2015 +0200 + + Makefile.defs: version set to 4.3.3 + +commit ecf289cfcdb7ee5678d86f03ccf4a5138c102a34 +Author: Daniel-Constantin Mierla +Date: Fri Oct 2 14:27:36 2015 +0200 + + pkg/rpm: updated spec files for v4.3.3 + +commit 3181001ebae49847ed210428946fde96e89e9c4f +Author: Daniel-Constantin Mierla +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 +Date: Fri Oct 2 13:26:39 2015 +0200 + + pkg/kamailio/deb: update version to 4.3.3 + +commit bf0efda9cbd3ab02e1cdefb187ae2ac3089e1b18 +Author: Daniel-Constantin Mierla +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +Date: Thu Oct 1 09:48:26 2015 +0200 + + acc_radius: fixed identation, removed history + + (cherry picked from commit f9a6b7893ad421cb142e03c9c2797773061c8933) + +commit c8d17ba355b3979fc28390f9c93460572ecfeb17 +Author: Yasin +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +Date: Tue Sep 22 14:07:47 2015 +0200 + + Makefile.defs: memory manager set to q_malloc + +commit 2b8dc34378812f9aea187c2cfe27021dd4f7113b +Author: Daniel-Constantin Mierla +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +Date: Thu Sep 10 15:31:26 2015 +0200 + + Makefile.defs: version set to 4.3.2 + +commit 9e7106f55019011defe438fa6fb1f9d0aa6567c0 +Author: Daniel-Constantin Mierla +Date: Thu Sep 10 14:01:11 2015 +0200 + + pkg/rpm: updated spec files for v4.3.2 + +commit 648834a64d63aed64076dacf85ec5af1a5702333 +Author: Daniel-Constantin Mierla +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 +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 +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 +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 +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 +Date: Thu Sep 10 12:50:04 2015 +0100 + + dmq_usrloc: check existence of usrloc domain before continuing. + +commit 24b347a5fca61d13a0765dbf1b3c8207caf3b45d +Author: Charles Chance +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 +Date: Thu Sep 10 12:16:13 2015 +0200 + + pkg/kamailio/deb: update version to 4.3.2 + +commit b0cab1484979a7d975b56bf8dcf0dbc2e3510732 +Author: Federico Cabiddu +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 +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 +Date: Tue Sep 8 15:09:13 2015 +0200 + + modules: refreshed several readme files + +commit c46d065a9ef9f63207811e629120ef5cf8a44dbf +Author: Daniel-Constantin Mierla +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 +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 +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 +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 +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 +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 +Date: Tue Sep 8 15:02:45 2015 +0200 + + auth: fixed improper whitespacing + +commit f02215971667f54c553e10593e370db8feb1aae9 +Author: vance-od +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 + +commit d495aafb98d3560c36b681dae21b671ce8b23e86 +Author: Daniel-Constantin Mierla +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 +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 +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 +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 +Date: Mon Aug 10 15:35:09 2015 +0200 + + rtpengine: regenerate README + +commit df5761a59bc4da1854b081f0e68e98f6392aee5d +Author: Camille Oudot +Date: Mon Aug 10 15:24:27 2015 +0200 + + rtpengine: fix typo in documentation + + (cherry picked from commit e8927be015b4034d252479ba6fede4b749a43eed) + +commit a2b8efe1c24a213ef6c4221a59af544a3873e9d2 +Author: Victor Seva +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 +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 +Date: Wed Jul 29 12:16:40 2015 +0200 + + tm: readme regenerated + +commit 03faa73eff6c341b0f49989a11478ec0b92b611e +Author: Daniel-Constantin Mierla +Date: Wed Jul 29 12:16:23 2015 +0200 + + pv: readme regenerated + +commit 40a66072179da324859864af8caee654e5c143e5 +Author: Daniel-Constantin Mierla +Date: Wed Jul 29 12:15:59 2015 +0200 + + pipelimit: regenerated the readme + +commit 4c7e676cdec3213c27cc689bdb5e6bbb8a9ec1ea +Author: Daniel-Constantin Mierla +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 +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 +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 +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 +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 +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 + + (cherry picked from commit ed894111f6f15170f87336bfa73ec4e8fce1c7d1) + +commit fb2af6107a9c6cd3552fe0a95c699c30e4edad4c +Author: Victor Seva +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 +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 +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 +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 +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 +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 +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 +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 +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 +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 2d287775c..e89b8fc3b 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 11d49a9de..b22535557 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 54ca25e56..347edbef4 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 966bcbfbf..21c1387c2 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 46cc40d56..314b2c571 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 752450f72..603b2023d 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 1190e80b7..7f5f3db1f 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 656b623b3..e67c58924 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 e7323e3d7..fda8f9eaa 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 4a1b0a71d..67f52a780 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 a57f85d91..288382984 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 1ff7f6af9..acb8ce40e 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 fa8cb49e1..cac914fec 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);hashfree_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_usedreal_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;hfree_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 fef53cb6e..75e0cdf2a 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 2c742ee18..a019b0ef4 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 bd3f1cc65..16a97e5fa 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 820f480fd..fbe7dc35c 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. Default value is 0 (no). diff --git a/modules/acc_radius/acc_radius_mod.c b/modules/acc_radius/acc_radius_mod.c index b1843d63a..f9327ad23 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; itarr[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; ivarr[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 308909744..0560a7c26 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 8cd6faceb..be0ee11ee 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 8ed62e62f..240b69300 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 ef541259e..71b990a56 100644 --- a/modules/auth/README +++ b/modules/auth/README @@ -15,46 +15,46 @@ Daniel-Constantin Mierla asipto.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 ec333240a..225dbb350 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")) { -2 (invalid password) - wrong password - -3 (invalid user) - authentication user does - not exist - - -4 (nonce expired) - the nonce has expired @@ -218,10 +214,6 @@ if (!auth_check("$fd", "subscriber", "1")) { -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: @@ -357,6 +349,13 @@ if (!pv_proxy_authenticate("$fd", "$avp(password)", "0")) { 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. diff --git a/modules/auth/nonce.c b/modules/auth/nonce.c index 95b967eaa..d65d9cd45 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 6d582c2b1..86e1cb70f 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 2c7f03e23..21242f4f5 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 7dade3862..af24c7ad2 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 diff --git a/modules/corex/corex_rpc.c b/modules/corex/corex_rpc.c index 77ef0d3ea..f26965d65 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 5b47d883c..4c27ed283 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 b06781bbc..c4b72977a 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 d053c5557..ec98add25 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 9e8d2c462..aed40e785 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->statestate==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 aae6efb8e..75dc86f7a 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 420caea74..656833cdc 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; @@ -749,6 +749,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 b09fe381e..64fb0372c 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 39dc1dff6..9a4708214 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 b4f821ed0..e8c84edd2 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 7491a5fe3..a5f8a2a9b 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 3bd0c245f..40e89d338 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 81f3091cf..1d567a03d 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 a1171f9fc..d9f858f03 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: |||||| ||| @@ -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 cebbe6019..f3cffd9ef 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 forever. - 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. @@ -612,7 +616,7 @@ Here is an example of evaluating multiple Byxxx parameters. - dtstart=19970105T083000 duration=10M + dtstart=19970105T083000 duration=PT10M freq=yearly interval=2 bymonth=1 byday=SU diff --git a/modules/drouting/drouting.c b/modules/drouting/drouting.c index 3c79f2644..989558e37 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 6035ccea9..4d61f8e12 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 159d14eab..b0aa8f5f8 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; ifd) { 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='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 46c4dff4c..ba12f1601 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 fb0b11760..b2817296c 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 4bcc2b1c3..5eeafa361 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 13ec1dd1b..0a31fd731 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 000000000..a3ef80cc3 --- /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@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 + and e-mails regarding development + versions should be sent to . + + If you want to keep the mail private, send it to + . + + 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 b213b036a..bc487511b 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 90c4168b5..4d77b9e64 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 d585e0556..53c3ca20d 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 27f0f45e3..4ae65c0a5 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 bfe66c931..76378d3c0 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 0a4ebd68d..81ce22aa6 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 39c7f3139..f0117d9c9 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 09286bc63..8f1fb067c 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 188d2e6c0..41429af50 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 a5c877b14..62f25064a 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 91748092d..9a1dcc8ca 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 0309b73dd..8e2ed71fc 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 9e93dd842..693fb8790 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 c51793c8a..18b4bdcdc 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") mi - uses a special, "pretty" format which generates nicer (more readable) output when used with - sercmd. + kamcmd. mi_dg - uses an output format similar to @@ -125,10 +125,10 @@ modparam("mi_rpc","rpc_url","tcp:localhost:2046") (optional). - Example using 'sercmd': + Example using 'kamcmd': -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 7ad0fb585..e037dda0f 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 35f2cca5f..844a86ec3 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 52d844c69..797fedd93 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 3da08944a..923560caa 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 95ec7629c..7f84788ac 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 9cab590e3..ae8506335 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 745286a34..7c3aa928a 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 e3f5a7fd4..875681637 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 672cee829..f1c70637c 100644 --- a/modules/registrar/doc/registrar_admin.xml +++ b/modules/registrar/doc/registrar_admin.xml @@ -1110,10 +1110,12 @@ lookup_branches("location"); registered(domain [, uri [, match_option [, match_action]]]) - 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. Meaning of the parameters is as follows: @@ -1126,7 +1128,7 @@ lookup_branches("location"); uri (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. @@ -1160,7 +1162,7 @@ lookup_branches("location"); - This function can be used from REQUEST_ROUTE, FAILURE_ROUTE. + This function can be used from ANY_ROUTE. <function>registered</function> usage diff --git a/modules/registrar/lookup.c b/modules/registrar/lookup.c index efbe39cc7..6fb170b55 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 d767834d9..db478246e 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<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 a4735b272..9c24ac73e 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 de06bb3ab..76204c978 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 ae5870f22..fe4637baf 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 6be5386f3..5a12f61a4 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. - Set <varname>write_sdp_avp</varname> parameter + Set <varname>write_sdp_pv</varname> parameter ... -modparam("rtpengine", "write_sdp_avp", "$avp(sdp)") +modparam("rtpengine", "write_sdp_pv", "$avp(sdp)") + ... or +modparam("rtpengine", "write_sdp_pv", "$pv(sdp)") ... diff --git a/modules/sanity/sanity.c b/modules/sanity/sanity.c index 7e1842ee6..8140c07b2 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 1fb71dc16..c8f5ffa46 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 3ede4ca31..2fc495acb 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). - 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 07e3a1ada..df6ceff76 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 940ec5a79..9b8721b50 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 7c5e2af50..9aaada600 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 0f704e37c..41201f74e 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 6e212426d..b170eb85e 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 3e1ebecfb..0633b8608 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 5146d408b..217a5a2bf 100644 --- a/modules/tm/doc/functions.xml +++ b/modules/tm/doc/functions.xml @@ -1664,6 +1664,10 @@ 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. diff --git a/modules/tm/doc/params.xml b/modules/tm/doc/params.xml index 2e0099b94..e85ebdc5b 100644 --- a/modules/tm/doc/params.xml +++ b/modules/tm/doc/params.xml @@ -1003,7 +1003,7 @@ modparam("tm", "via1_matching", 1) Can be set at runtime, e.g.: - $ sercmd cfg.set_now_int tm callid_matching 0 + $ &sercmd; cfg.set_now_int tm callid_matching 0 diff --git a/modules/tm/t_append_branches.c b/modules/tm/t_append_branches.c index b276d9e91..2c296fb69 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; iuac[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 d14ed1c45..0041a4fc0 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 86fb3be49..d0d854ddd 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 84b7a56c3..afee28b0b 100644 --- a/modules/tmrec/README +++ b/modules/tmrec/README @@ -16,7 +16,15 @@ Alex Balashov +Edited by + +Richard Fuchs + + + 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 c70bdb27a..b791226a7 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 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. See RFC 2445 for - the format of duration. + permitted. Zero-length duration means forever. + Negative-length durations are not 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. @@ -253,7 +258,7 @@ modparam("tmrec", "separator", ";") Next is an example of evaluating multiple Byxxx parameters. - startdate=20100101T093000 duration=10H30M + startdate=20100101T093000 duration=PT10H30M frequency=yearly interval=4 bymonth=3 byday=SU diff --git a/modules/tmx/t_var.c b/modules/tmx/t_var.c index 033823355..7b61a490a 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 28dbcd7f8..d2d8e60ce 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 1691432d1..00f571bb4 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 b2a9a9a80..100fcecb6 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 7cf79701b..c04ec360f 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 cf529eeb7..7986991f3 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 67dc2d68d..a05a4ef8f 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 0cff68946..7b7d2deff 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 561b38760..3e158d67a 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 c4e234ede..e547c2126 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 d32d970ab..97d1700db 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 e6b8d9709..5df0a9d37 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 c90d3e5b6..9db38afbc 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 6f5b76bc1..fae4b56b7 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 a467cf246..59e52d711 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 Fri, 02 Oct 2015 13:25:18 +0200 + +kamailio (4.3.2) unstable; urgency=medium + + * update version to 4.3.2 + + -- Victor Seva 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 83355a8ff..cf814c57a 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 Fri, 02 Oct 2015 13:25:18 +0200 + +kamailio (4.3.2) unstable; urgency=medium + + * update version to 4.3.2 + + -- Victor Seva 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 83355a8ff..cf814c57a 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 Fri, 02 Oct 2015 13:25:18 +0200 + +kamailio (4.3.2) unstable; urgency=medium + + * update version to 4.3.2 + + -- Victor Seva 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 83355a8ff..cf814c57a 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 Fri, 02 Oct 2015 13:25:18 +0200 + +kamailio (4.3.2) unstable; urgency=medium + + * update version to 4.3.2 + + -- Victor Seva 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 83355a8ff..cf814c57a 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 Fri, 02 Oct 2015 13:25:18 +0200 + +kamailio (4.3.2) unstable; urgency=medium + + * update version to 4.3.2 + + -- Victor Seva 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 83355a8ff..cf814c57a 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 Fri, 02 Oct 2015 13:25:18 +0200 + +kamailio (4.3.2) unstable; urgency=medium + + * update version to 4.3.2 + + -- Victor Seva 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 a7762155a..e71b1b1be 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 1ae56f49b..b2bfa21b3 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 25257e956..ca7017d51 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 ea3cc522e..c1811129e 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 d60aebcf3..c6b9d5b43 100644 --- a/pvapi.c +++ b/pvapi.c @@ -605,6 +605,21 @@ int pv_get_null(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) return 0; } +/** + * + */ +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; +} + + /** * */ diff --git a/pvar.h b/pvar.h index 3bdfe17bb..8cc84887a 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 52c12ed99..e4524f598 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 d16f59d89..a6e690199 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 216c953e9..057bf0222 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 df778bac4..578f7d27a 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 86d8fc478..338163123 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@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; }