diff --git a/.mailmap b/.mailmap deleted file mode 100644 index b92f5e5f9..000000000 --- a/.mailmap +++ /dev/null @@ -1,3 +0,0 @@ - -Sipwise Jenkins Builder -Victor Seva diff --git a/ChangeLog b/ChangeLog index a88e55f62..b3472f748 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,2055 @@ +===================== 2021-02-15 Version 5.4.4 Released ===================== + +===================== Changes Since Version 5.4.3 =========================== + +commit b87099f5a26845aaf11d55c8fa56f9a9e4255b8c +Author: Daniel-Constantin Mierla +Date: Mon Feb 15 11:28:16 2021 +0100 + + Makefile.defs: version set to 5.4.4 + +commit 57fb85e2a1dc50618179b79901563bab502169da +Author: Sergey Safarov +Date: Mon Feb 15 10:11:25 2021 +0300 + + pkg/kamailio/obs: added --atexit=no into systemd unit file [skip ci] + + (cherry picked from commit 9a35a5b95e8144dbdb18003f40e49e5b497274f3) + +commit 9cf3a7991919a27410aec6658ec8e77d4e381e01 +Author: Victor Seva +Date: Mon Feb 15 09:32:05 2021 +0100 + + pkg/kamailio/deb: version set 5.4.4 + +commit 864238f68588923ca60758251bd5f5ab3ac838fd +Author: Victor Seva +Date: Thu Feb 11 13:26:49 2021 +0100 + + pkg/kamailio/deb: restore python3 dependency of kamailio package + + (cherry picked from commit ab8e680e0dd3a8078d40b72c50d41db55d442240) + +commit 0f093556d0ad9e8bcf92222ac0cc7c1887ea0527 +Author: Daniel-Constantin Mierla +Date: Mon Feb 15 09:24:57 2021 +0100 + + pkg/kamailio: version set to 5.4.4 for rpm specs and alpine + +commit e8595172d317b03a335bfd7c29fdf09d2e6da8b5 +Author: Daniel-Constantin Mierla +Date: Sat Feb 13 20:59:30 2021 +0100 + + pv: proper transfomation name in the log message + + (cherry picked from commit b4d1def5d8a5ffaddbd87708d8dc99f0f5f8853c) + +commit 807ff5d216ad0dd8a620201b49c125c9c26d3559 +Author: Kamailio Dev +Date: Fri Feb 12 16:16:30 2021 +0100 + + modules: readme files regenerated - modules ... [skip ci] + +commit 0e0d067be489296ccffbc0a44ca37c89f105cece +Author: Daniel-Constantin Mierla +Date: Fri Feb 12 16:14:18 2021 +0100 + + rr: docs - more details for sockname_mode param + + (cherry picked from commit 86a5f81b776eab3e2b9a3a5470094546b94253f7) + +commit 9f7cb97ded57e6980dcb86752484ed8fda519b80 +Author: Daniel-Constantin Mierla +Date: Fri Feb 12 15:26:56 2021 +0100 + + core: define sockname attribute name + + - used in the sockname r-r parameter + + (cherry picked from commit 274d32651d7886b7f424239565a2714e2dd0991d) + +commit 48e84d70e42f17712e4718fc1ae9418dc67b4468 +Author: Daniel-Constantin Mierla +Date: Fri Feb 12 15:27:35 2021 +0100 + + rr: compare sockname parameter name with the attribute name + + (cherry picked from commit 86e8bfdee87558fcee3e5b821b506b934c6b6790) + +commit e0461d1c4026dd2953e4352bea0586419980180b +Author: Daniel-Constantin Mierla +Date: Thu Feb 11 17:32:45 2021 +0100 + + htable: docs - not about use of event_route[htable:mod-init] + + (cherry picked from commit e0dcb1617bedf13cc3fc76cf7f3b5cd516806bc8) + +commit 0f4eecdca36e9fc3311175a354a2404367b1e2fb +Author: Juha Heinanen +Date: Thu Feb 11 17:44:19 2021 +0200 + + Improved README. + + (cherry picked from commit 857e9deb4c2455ee2ea0c05446da54f97e1f0a63) + +commit 73e849cb3e5771402fb1a9249457ae3ce4b60d3b +Author: Juha Heinanen +Date: Thu Feb 11 17:27:44 2021 +0200 + + Fixed typo. + + (cherry picked from commit 2664a51c35a1e8b5adc4c7e6cedde60bc01f0b28) + +commit a61d308c4460afcaab19934ade23a7ee8e8b1b5b +Author: Daniel-Constantin Mierla +Date: Thu Feb 11 16:22:06 2021 +0100 + + rr: docs - added missing end tag for para introduced in previous commit + + (cherry picked from commit f8e60bcba548b25657cc295f8a593adf371f9fda) + +commit 2e6a4024ae35b95d3f4b777ec6eb346ba072f80f +Author: Daniel-Constantin Mierla +Date: Thu Feb 11 16:06:12 2021 +0100 + + rr: docs - note about format of record_route_preset() parameters + + (cherry picked from commit f318fab629c308250531046d453a8ac76f80ca42) + +commit a0e796754a0e51f635d6bf899711294e805bff4c +Author: Daniel-Constantin Mierla +Date: Thu Feb 11 15:59:31 2021 +0100 + + rr: use rr params with record_route_preset() + + - param buffer was checked, but not used + + (cherry picked from commit 76b886da8ddf11a94a62850c19bad8c83bd113fc) + +commit 38dd7fd703f043c51756df936abc56103c891545 +Author: Daniel-Constantin Mierla +Date: Thu Feb 11 10:27:20 2021 +0100 + + core: cfg.lex - do not destroy action if pre-fixup fails + + - params might be in inconsistent state, shutdown is triggered which + cleans the pkg anyhow + - GH #2630 + + (cherry picked from commit dddd530ed9fa7b6ca8b31ff299105a53c39c1a5e) + +commit f1a4f695e530e387e2f14d257263b7c99315b32a +Author: Daniel-Constantin Mierla +Date: Wed Feb 10 17:01:36 2021 +0100 + + core: initialize allocated _ksr_shutdown_phase pointer + + (cherry picked from commit f27c2e06d7467c4c33ff289175862ae7614a3018) + +commit ee6b30c1556d4591ef92f8696e583a94c75e3c93 +Author: Daniel-Constantin Mierla +Date: Wed Feb 10 17:10:25 2021 +0100 + + ctl: fail when requested to process rpc commands in shutdown phase + + (cherry picked from commit 2015cfdfd777085dad98a606fc41946af186db1b) + +commit 57c9794350d36fe1965212bca2bd42f147d100db +Author: Daniel-Constantin Mierla +Date: Mon Aug 10 16:23:11 2020 +0200 + + ctl: skip handling rpc commands if kamilio is in shutdown phase + + - related to #2433 + + (cherry picked from commit 6d928b59a3dbd6eb291da3d3936be6e8f18588af) + +commit 23d24f9db87e5b5d384af70e466df9d23f2bd900 +Author: Daniel-Constantin Mierla +Date: Fri Nov 27 07:49:27 2020 +0100 + + core: test if shm is initialized on early shutdown + + (cherry picked from commit b7d42f248bef70a06d8ae23f4a7652fd3f0e4e61) + +commit 72b88989f359ddd14e83a7b2f8c108753072ae3f +Author: Daniel-Constantin Mierla +Date: Tue Aug 11 16:33:02 2020 +0200 + + core: proper test when initializing _ksr_shutdown_phase shm pointer + + (cherry picked from commit 27b2ddf926240b1dd269eb1d96767d73edf9c6e6) + +commit bc65cba661747c960d6d62807e0bedf755f2f668 +Author: Daniel-Constantin Mierla +Date: Mon Aug 10 16:15:04 2020 +0200 + + core: keep a global flag in shm for shut down phase + + - set when destroy modules is starting + - useful to check from other processes if shut down started + + (cherry picked from commit 6da946e4a3d6d6949dd6babe9cf3919edc0b4519) + +commit a36805a26aa84e865ba18260d94587be44688883 +Author: Daniel-Constantin Mierla +Date: Wed Feb 10 16:35:09 2021 +0100 + + tls: fixed small typo in log message + + (cherry picked from commit 3c1a454a1ac4fe8e668f709d3e278bbce59c51d3) + +commit e4fd58083274a774dae528437a01200a86ad7fa8 +Author: Daniel-Constantin Mierla +Date: Wed Feb 10 08:27:58 2021 +0100 + + cfg.lex: removed yynoreturn attribute for ksr_yy_fatal_error() + + - it is defined only by newer flex version, resulting in compile + failure on older versions (e.g., centos 7) + + (cherry picked from commit f230035d8275cbad8d7515f73ba242f77a7a16db) + +commit bf8ab95cffdb1d2ab98c68ca84ad80626c093085 +Author: Daniel-Constantin Mierla +Date: Tue Feb 9 21:16:52 2021 +0100 + + core: cfg.lex - removed __attribute__((unused)) + + - not supported on some distros + - workaround to avoid unused warning + + (cherry picked from commit 20fdab545a5f5c3ef1b8d8c4c392acaf4f9e8aae) + +commit 58dfc4cb7e1de233dfb2ceed2fb2a17a8511905c +Author: Daniel-Constantin Mierla +Date: Tue Feb 9 14:00:23 2021 +0100 + + core: main - terminate using ksr_exit() instead of return + + (cherry picked from commit d8643cd2caf38aa1efaeff73783920fab1d9bf0d) + +commit cfd9a30e5cad869c7188a524e24d1b6f53664f9f +Author: Daniel-Constantin Mierla +Date: Tue Feb 9 13:27:34 2021 +0100 + + core: cfg.lex - declare auto-generated yy_fatal_error() with unused attribute + + (cherry picked from commit 346d99d1f98178a71d482e5724135f65257427dd) + +commit 1202f7ba0033a83ade2839cab06b2f2d35d63f64 +Author: Daniel-Constantin Mierla +Date: Tue Feb 9 12:57:57 2021 +0100 + + core: cfg.lex - overwrite yy_fatal_error() to use ksr_exit() macro + + (cherry picked from commit 9f326234f40f2c02f4833647112c3a4f4912aa17) + +commit 1c6a04517d924d3f806573529f915a4528afd317 +Author: Daniel-Constantin Mierla +Date: Tue Feb 9 10:50:03 2021 +0100 + + core: more use of ksr_exit() macro to follow --atexit param + + (cherry picked from commit 4f6243e8e6e2012af35aae67da7b93af2127f02c) + +commit 2f912a17d09a6e7aad89b5df4629a360330522d3 +Author: Daniel-Constantin Mierla +Date: Fri Feb 5 09:55:58 2021 +0100 + + keepalive: check if the destinations list is initialized at runtime use + + - do not initialize, because is no longer seen in all processes, + initialization must be done in mod init + + (cherry picked from commit b2b7ec826055fd67ecf5ffb052afa609e0aa9e5b) + +commit e4994b28b2052ff864c16aaa2305d7356ad4d812 +Author: Victor Seva +Date: Wed Feb 3 13:33:32 2021 +0100 + + doc: update manpage for atexit option + + (cherry picked from commit 351efd29d332703e79104a106ade08c9d1df6e20) + +commit 97ba470451ecde8c97531fdce3ddd2ef47955b0e +Author: Daniel-Constantin Mierla +Date: Wed Feb 3 12:49:29 2021 +0100 + + core: replaced --no-atexit with --atexit=val + + - val can be y[es] or 1 to enable execution of atexit callbacks; n[o] or + 0 to disable the execution of atexit callbacks + - default yes + - simplified ksr_exit() macro + + (cherry picked from commit 9b1472275530ed4cc32a65cd247dc9997e8b964b) + +commit c603f69179872775fcf8f35fd0a0d2c7d9e9d2a7 +Author: Victor Seva +Date: Wed Feb 3 09:41:12 2021 +0100 + + doc: update options at manpage + + * put them in order too + + (cherry picked from commit 377bb3bdfd20bedabbe0f92e53bdded44be267e9) + +commit 0dbdf13df804e26337a7b88b16f18c31223bd62e +Author: Daniel-Constantin Mierla +Date: Wed Feb 3 08:29:32 2021 +0100 + + core: use macro for exit variants based on --no-atexit + + (cherry picked from commit 06aec5a81cb22d06ad3bf613a05951f91e7e21bc) + +commit eadd50a92bfe7fb0cdfa90276cdb5df0e85a942e +Author: Daniel-Constantin Mierla +Date: Tue Feb 2 21:36:57 2021 +0100 + + core: take in consideration --no-atexit for daemonize() + + (cherry picked from commit 7ab2e85437482b4dba86937a29da025503450014) + +commit 91ae11588b6d038b97e803f4afaf44dffe561322 +Author: Daniel-Constantin Mierla +Date: Mon Feb 1 23:39:40 2021 +0100 + + core: added --no-atexit cli parameter + + - skip atexit callbacks execution from external libraries which may access + destroyed shm memory causing crash on shutdown + + (cherry picked from commit 9f12d314268d1d2cd990cb3c5556f79343869e47) + +commit be0e0fc4da2a6a901cacda9b3574147639b9f9ea +Author: tsearle +Date: Wed Dec 16 21:47:11 2020 +0100 + + modules/siptrace: fix regression preventing variables to be used (#2588) + + * modules/siptrace: fix regression preventing variables to be used + + Commit fa7eb2a switched the 2 parameter version of sip_trace from + using the builtin fixup_spve_spve to the custom fixup method to + using the custom fixup_siptrace. As it is a custom fixup method, + the corresponding free method can not be auto-detected causing the + config parser to require the parameters to be a constant. This + patch adds a free method, allowing variables to be once again passed + as the 2nd parameter of this method (as well as fixing a memory leak + for the 3rd parameter). + + * change free for parameter 3 + + Co-authored-by: Torrey Searle + (cherry picked from commit 7c98d547996637a7bf1c7025c93142f574fe3ac9) + +commit f9f33d37f80003836cf87338a4dd96b1b4614c22 +Author: Daniel-Constantin Mierla +Date: Thu Feb 11 09:14:06 2021 +0100 + + app_python3: handle deprecated PyEval_InitThreads() + + - https://docs.python.org/3/c-api/init.html#c.PyEval_InitThreads + - GH #2626 + + (cherry picked from commit ca37f9247ecb6754fbdbd210fc59158bf0f32def) + +commit a7170a4fa6f4b0498fb192291842eb497f6f9507 +Author: Kamailio Dev +Date: Tue Feb 9 10:16:59 2021 +0100 + + modules: readme files regenerated - modules ... [skip ci] + +commit 95e7399481e61ec54bb226c122c5617f03553b5d +Author: Wolfgang Kampichler +Date: Wed Jan 27 19:53:24 2021 +0100 + + http_client: http_client_request to include default clientcert, clientkey,... + + - the lost module uses http_client API functions and in the course of NG112 + client certificates are used for authentication when querying LIS or ECRF, + the fix allows these to be read out via http_client module parameters. + + (cherry picked from commit 7d5868ab1242eb8166e6af1bb8a21b39001df663) + +commit 73826e75b6699f3bd1bfb27eabf9582cbf09c19f +Author: Daniel-Constantin Mierla +Date: Sat Feb 6 16:06:47 2021 +0100 + + siptrace: docs - fixed small typo + + (cherry picked from commit 7d846f928b75a3bc1b8e8c1a70e39bfede939c15) + +commit ee7838842a175ffb4898dade606377c91cc8ecb8 +Author: dvillaume +Date: Wed Feb 3 10:19:46 2021 +0100 + + rtpengine : add node fallback if node out of port + + When rtpengine answers with error-reason 'Ran out of ports' adopt the same behavor that when node answers 'Parallel session limit reached' + + (cherry picked from commit 853068a26c34deff86e17b63f49abea2c8f4403c) + +commit 3027f8b9daed5ca4f36d0779cd6f79e596bf42e1 +Author: Daniel-Constantin Mierla +Date: Thu Feb 4 14:01:52 2021 +0100 + + kamctl: added srv debug subcommand + + - control server debug level via rpc + + (cherry picked from commit 6b5aa70f09e294338a65a0bf2fcae8b92fdc6fae) + +commit a2e0e4912b5a81a88cccd2fb58652be5662ef4f0 +Author: Henning Westerholt +Date: Tue Feb 2 18:42:35 2021 +0000 + + xhttp: do not call memset on a null-pointer, related to GH #2619 + + (cherry picked from commit 2db8884945844e5040dfed2b24fe84de097c0b2b) + +commit 989baffd9cbb934c8d0fd42dc9ef08db36c33f11 +Author: Daniel-Constantin Mierla +Date: Wed Jan 27 14:10:34 2021 +0100 + + tm: prper timer cleanup of responses for rpc tm.t_uac_wait_block + + (cherry picked from commit 5a6a679985fecfc168b9b26f0be3c0e64e641e64) + +commit 0ab7142d8f60d04c386674263f35f87ac602bebe +Author: Daniel-Constantin Mierla +Date: Tue Jan 26 11:52:36 2021 +0100 + + core: ut.h - add inline to static function to avoid warning from including files + + - for shm_str_dup_block() + + (cherry picked from commit 34301ea16812eccbb914ea14cafb0140ac9bba61) + +commit 33da663ec8d730fa570018bbdb7239e595b4838d +Author: Marat Gareev +Date: Mon Jan 25 18:40:47 2021 +0300 + + dispatcher: Log dest sets after variable update + + (cherry picked from commit f4b8bede6a247415eda84a7db9569747905f9fa0) + +commit 0ff67c573f3bb59dc7872a48310c28d2d08734e1 +Author: Daniel-Constantin Mierla +Date: Mon Jan 25 12:42:36 2021 +0100 + + tm: docs for reply_relay_mode parameter + + (cherry picked from commit 00b1aba770c26f75c31cf2a28e7ca425f18788dc) + +commit be9081621e71965f90be490cdaa01f31dd02d842 +Author: Daniel-Constantin Mierla +Date: Mon Jan 25 12:34:33 2021 +0100 + + tm: new parameter reply_relay_mode + + - control the behaviour introduced by 18410da0 + - if set to 0, the behaviour is like before the commit referenced above, + tm is attemptime to send suspended 200ok after another final response + that was forwarded while 200ok was suspended + - default is 1 (behave as the patch changed the forwarding policy, not + to overwrite the response buffer) + + (cherry picked from commit 90dfc421dab438a8ef62cc8f68b2c1f7fb50b0dc) + +commit 31f8466f1d493db8baaa215d34d4ed4545d4ff79 +Author: Theo +Date: Fri Apr 17 08:53:00 2020 +0000 + + tm: 200 OK not processed correctly by Proxy after final non-2xx + + Description: + Problem: + Forwarding of 200 OK while sent 488 waits for ACK, destroys the UAS send buffer + Scenario: + During suspension of 200 OK by ims_qos module function Rx_AAR() at terminating PCSCF, + The PCRF sends an AA Answer with result code DIAMETER_TOO_BUSY (3004), which triggers + the PCSCF to send a 488 ‘Sorry no QoS available’ to the originating side (ims_dialog + module function dlg_terminate()). + Afterwards neither the 200 OK nor the ACK(488) is processed correctly by the PCSCF. + Solution: + The UAS send buffer should not be overwritten during processing of 200 OK, + because non-2xx is needed to associate the ACK message in a correct way. + 200 OK must be forwarded statelessly. + Side-Effect (potentially breaks existing function): + Some callbacks cannot be called for the 200 OK, to avoid messing the stored 488. + (cherry picked from commit 18410da04c7f7bbc9628820427fedb92cf893526) + +commit b0e29edea36778be91acfe1907a94a5d1134a5ca +Author: Nicolas C +Date: Fri Jan 22 15:16:56 2021 +0100 + + core: fix to xavp_rm_internal (#2604) + + This fixes the following issue: + https://github.com/kamailio/kamailio/issues/2604 + + Description of the issue: + + When called to remove a specific index from a given xavp, function xavp_rm_by_index removes the index (as expected) but also all others before it. + + E.g : + If called with idx = 1, it removes indexes 0 and 1. + Likewise if invoked with idx = 2 => the first 3 elements are removed. + + This bug is located in function xavp_rm_internal. An assignment was missing when looping over the xavp list. + Same for xavi_rm_internal. + + (cherry picked from commit 12414972ad0c28ac50ece3c14f98134c3f06c522) + +commit b6ab0ba329f11e7baabe194994c095b4cb225af4 +Author: Daniel-Constantin Mierla +Date: Thu Jan 21 14:05:50 2021 +0100 + + kamctl: removed condition on CTLENGINETYPE + + - done again inside ctl_cmd_run + + (cherry picked from commit 4a4f0475716cbf824b2ab9684457e21f6732aa74) + +commit b8a7d2bfd1118d556c9e46dcab97fbcb45fa6187 +Author: Daniel-Constantin Mierla +Date: Thu Jan 21 10:00:46 2021 +0100 + + kamctl: use param evaluation mode for cisco restart command + + (cherry picked from commit 359050f9be40002aec1d3894dc43a2a8762ce8cc) + +commit 4b606ec029703420a74f4246a7bcdb06a9d67635 +Author: Daniel-Constantin Mierla +Date: Wed Jan 20 08:54:49 2021 +0100 + + kamctl: use tm.t_uac_wait_block rpc for ping command + + (cherry picked from commit 47a98532af5512a4597bbf9ad3834c62dd633256) + +commit 254790bdb27e081765958a8b099921219c0f6e41 +Author: Daniel-Constantin Mierla +Date: Wed Jan 20 08:54:21 2021 +0100 + + tm: docs for rpc t_uac_wait_block + + (cherry picked from commit 89eea7edb8832124dc325d8303b23ea5f36c88f4) + +commit ff34dc44bba76c6ee2828a03655e03087f5a5db6 +Author: Daniel-Constantin Mierla +Date: Wed Jan 20 08:11:45 2021 +0100 + + tm: implemented t_uac_wait_block rpc command + + - it blocks while waiting for the reply to return the code and reason + text + + (cherry picked from commit dc5a548a9e6327674615aa7ddc8708e0ba5252aa) + +commit c3f12eb469995a03166bf801bc4a391095202452 +Author: Daniel-Constantin Mierla +Date: Tue Jan 19 21:00:54 2021 +0100 + + core: utils - functions to shm-duplicate str in a block + + (cherry picked from commit 6684b57641396ba494716e7f63a0f15afc1d8637) + +commit 6769d44cfab686824a6b077bc8cbb4a347fd3356 +Author: Daniel-Constantin Mierla +Date: Tue Jan 19 07:49:24 2021 +0100 + + kamctl: use tm.t_uac_wait for ping command + + (cherry picked from commit 20d075a17189961baf63ac000e4417d7f04d8a08) + +commit 9b5eade1faa8deeb3fcc8f9cb010f803c17ee309 +Author: Daniel-Constantin Mierla +Date: Mon Jan 18 10:19:05 2021 +0100 + + kamctl: option for rpc command to replace tokens in parameters + + - supported now: replace '=CRLF=' with '\r\n' + - fix 'kamctl ping' command by replacing '=CRLF=' with '\r\n' + in multi-headers parameter + + (cherry picked from commit 1c66f6a1a5d04c33f1912609a36729b06b6eebd7) + +commit 784ad65fe5abde677f5155e3d7ff0bfbd04286bf +Author: Daniel-Constantin Mierla +Date: Tue Jan 12 10:05:32 2021 +0100 + + misc/examples/kemi: use local variable instead of many function calls for js + + (cherry picked from commit b4f439301c2dffbfc6a389354e840142fc3b965b) + +commit e085bdb9a35f7a5b4624b7afdef96ca2fd3ba6fe +Author: Daniel-Constantin Mierla +Date: Tue Jan 12 09:52:31 2021 +0100 + + misc/examples/kemi: use kx functions instead of pv + + (cherry picked from commit 6e541feb9184e193f9c486c8f97d73360c69250d) + +commit df7ca5dce4c41ad6f05064fe2940943685a98f61 +Author: Daniel-Constantin Mierla +Date: Tue Jan 12 08:52:00 2021 +0100 + + app_jsdt: duktape interpreter upgraded to v2.6.0 + + (cherry picked from commit 2590165e278efb947edb9cb5a75104f2f760c4c2) + +commit 23000a3ab3d88419d4f0ac797aae201a22f0e1fb +Author: Paul Komkoff +Date: Mon Jan 4 18:18:01 2021 +0400 + + core: fix unused argument in socket_info.c:get_flags + + get_flags has an argument - family - which is supposed to be used + in netlink message, otherwise why would we need it? + + (cherry picked from commit 42f7702430c312b2c9caea8f617af4e3719ef12f) + +commit 252b0dd2d778c15ac6e96c7c415296619df3dc3e +Author: Paul Komkoff +Date: Mon Jan 4 18:13:28 2021 +0400 + + core: work around interface enum buffer overrun + + When a system has too many interfaces and too many addresses, + 8 kilobytes isn't enough to fit all of the netlink responses. + As the result, kamailio gets stuck in a loop where it tries + to do a 0-length recv. + + Increase the buffer to 32K. It's a miniscule amount for modern + times anyway. Also, add diagnostics to make further troubleshooting + easier. + + Proper fix would be to switch to libnl here, which would make a + good weekend project. + + (cherry picked from commit d2fd204b0ae35512a04702e480bb0d16878e98be) + +commit f64d41efc8bf08daa8f4a36cb81d4620bea2b367 +Author: Dennis +Date: Mon Jan 4 18:35:44 2021 +0300 + + rtpengine: fixing wrong parsing the pair of IPv6 addr:port (#2592) + + - fixing wrong parsing the pair of IPv6 addr:port in rtpengine module, when loading node information from database. + + (cherry picked from commit 13d786e33d6f04a718af40ba345cf0827f752c2f) + +commit d0af9aa7f46c90461288ef5241dba9c081fd40e4 +Author: Daniel-Constantin Mierla +Date: Thu Dec 24 10:09:02 2020 +0100 + + secsipid: docs - details of the acronyms + + (cherry picked from commit c1e06e029b192a4db45841fa78e9bcfee91f125d) + +commit 0b98ddb1ea04603851ce581a69111581a1d30a67 +Author: Daniel-Constantin Mierla +Date: Tue Dec 22 20:33:27 2020 +0100 + + core: info message made dbg when adding a subst expression + + (cherry picked from commit 80b3d5d036da493316a93594c770df1ef8218e5e) + +commit ff5283b156f6aa934bd5f621537427d9f2b31b1d +Author: Daniel-Constantin Mierla +Date: Sat Dec 19 15:34:05 2020 +0100 + + core: kemi - KSR.is_method_in() uses E/e to match PRACK + + (cherry picked from commit b04111b583b454b12ea0c6a265a14858c195b213) + +commit d992a7cf2d42e9c4efcb2153091f4410090e4be6 +Author: Daniel-Constantin Mierla +Date: Fri Dec 18 08:18:51 2020 +0100 + + http_client: docs - section title to get proper entry in toc + + - bits of whitespacing fixing + + (cherry picked from commit fadc0fc499fb57a763aa71a76b24cff152bbd927) + +commit 82ca29e2c51667bbfb8962006c8b4a93ed2160ee +Author: balajeesv +Date: Fri Dec 11 21:31:27 2020 +0530 + + evapi: export async_multicast() to kemi + + (cherry picked from commit ccaba976cd1c599ba64067df0896fdd4888af00f) + +commit 9a793eeeb6c39b11b9125ca8455c2d5d2b0d415d +Author: Daniel-Constantin Mierla +Date: Wed Dec 16 08:29:41 2020 +0100 + + xhttp: clang format code + + (cherry picked from commit d620aab9d2bc16e7785d5be0ddecd016329055de) + +commit 218350f089be9c3b5505079079df63d25dd74cc4 +Author: Daniel-Constantin Mierla +Date: Mon Feb 8 11:54:32 2021 +0100 + + siputils: free params for contact param decode and remove + + (cherry picked from commit d6504e28f7fef8d48480861ea12e9bd457288661) + +commit dbe358d2d0df1ea2d8441b39ae460966e5edb164 +Author: Sergey Safarov +Date: Mon Feb 1 11:55:24 2021 +0300 + + pkg/docker: updated submodule [skip ci] + +commit a96451324076e0043fe25407c5dd6a42d5ff9f69 +Author: Kamailio Dev +Date: Mon Jan 25 14:46:38 2021 +0100 + + modules: readme files regenerated - modules ... [skip ci] + +commit 4e2c049d27594c30069d1e29caca4f4521d6fe43 +Author: Richard Fuchs +Date: Mon Jan 25 08:37:26 2021 -0500 + + tmrec: fix typos in docs + + (cherry picked from commit 8be74b2fe0f59a9cef472b781feeae4cf3357bea) + +commit 06bd17a8387008a3c7b797bd820a687ece5e3627 +Author: Daniel-Constantin Mierla +Date: Fri Jan 8 08:21:55 2021 +0100 + + secsipid: include secsipid.h from standard path + + (cherry picked from commit c1a3443b09cee8a923f8801f8f3034f078034bf5) + +commit b7cff8de3b3d26b1120678fac331ca52424e6c01 +Author: Daniel-Constantin Mierla +Date: Thu Jan 7 17:34:36 2021 +0100 + + secsipid: Makefile - detect of pkg-config knows about libsecsipid + + (cherry picked from commit 664542adf42a4d829ddf9b9e482aba81f30883d8) + +commit b0a629ef9b366f4946dd1e73ce4aed2e028c119b +Author: Victor Seva +Date: Thu Jan 7 11:14:53 2021 +0100 + + secsipid: use pkg-config when available + + (cherry picked from commit 231a6eceeb67318cf4708a765b47df6c336350da) + +commit 573dd7e63ac3d2629367f72c967ec7fbd4edfcf1 +Author: Henning Westerholt +Date: Wed Nov 25 15:28:40 2020 +0000 + + tls: log version, gh #2561 + + (cherry picked from commit c9f0adddde8321bfaf368691fea74079e40bd789) + +commit 88d1eb7a79acd6afecb3d6760889433f69646b5b +Author: Daniel-Constantin Mierla +Date: Thu Dec 17 14:54:04 2020 +0100 + + dialog: handle CANCEL requests for CSeq updates + + (cherry picked from commit fd35a1a4eee2c50a3b7bf4ee6b1f6f20f4fa7d62) + +commit d9df74d43d736dd330f4f9aa364a9f0560717e1a +Author: Daniel-Constantin Mierla +Date: Wed Dec 16 20:54:57 2020 +0100 + + http_client: do not set empty headers and body + + (cherry picked from commit ce58411c462231d6ea1fc3b4acbf50520c2962ce) + + +===================== 2020-12-14 Version 5.4.3 Released ===================== + +===================== Changes Since Version 5.4.2 =========================== + +commit 32a19315eb946f939ca9cd8c50aae98b78adcfa1 +Author: Victor Seva +Date: Mon Dec 14 09:44:34 2020 +0100 + + pkg/kamailio/deb: version set 5.4.3 + +commit fc592bd1c4f0f0d400c8c50fbc7583157d7f4956 +Author: Daniel-Constantin Mierla +Date: Mon Dec 14 09:25:07 2020 +0100 + + Makefile.defs: version set to 5.4.3 + +commit b1b2067d360be72d536b7372c5bafd918bb57593 +Author: Daniel-Constantin Mierla +Date: Mon Dec 14 08:56:22 2020 +0100 + + pkg: version set to 5.4.3 for rpms and apline + +commit 0dffe40c25f59ba796edab7653633fe6c0773dc8 +Author: Kamailio Dev +Date: Fri Dec 11 21:01:26 2020 +0100 + + modules: readme files regenerated - modules ... [skip ci] + +commit 24666d2223c8e718ed9abe949a74d4339ae6c87e +Author: Daniel-Constantin Mierla +Date: Thu Dec 10 16:25:49 2020 +0100 + + dispacher: docs - more details about weight and rweight attributes + + - cross reference sections that have info about weight and rweight + attributes + + (cherry picked from commit db55715003cd9af5ef3d32b51b5246643eea10d1) + +commit 834bca2dab19fd1a63386e28955428c93da3c2ca +Author: Daniel-Constantin Mierla +Date: Tue Dec 8 13:07:44 2020 +0100 + + core: tcp - log connection state and flags on debug message + + (cherry picked from commit 41040a0420ee48f51901bf32e29526c8948ecea0) + +commit bec3650b51342a9b093ca92134c3b22f4ee22637 +Author: Daniel-Constantin Mierla +Date: Tue Dec 8 12:50:56 2020 +0100 + + core: tcp - debug messages merged, print bytes read and flags + + (cherry picked from commit efb9c5f83b37c316b848ae7b6dc829e2f8ca6275) + +commit bded4ca0918a4a48e7d1001bc924b31924ac8ea4 +Author: Daniel-Constantin Mierla +Date: Thu Dec 3 14:07:34 2020 +0100 + + pv: use static buffer for ctime_r() output and check its return + + - fixed $TF output, regression introduced when switching to thread safe + time function + + (cherry picked from commit 02fc919e4f177cc3ab9c5d53eb9ea2019c572bd9) + +commit cb6d5b577aa9eb3d60cb71a60133dd4a8777b69d +Author: Sergey Safarov +Date: Wed Dec 2 20:56:57 2020 +0300 + + lost: trimed spaces before reolving locationURI value + + fixes GH2569 (#2569). Allow parse exmaples from RFC7840 + + (cherry picked from commit f9d424ac426dc0547c7233902dfa44ad1287e077) + +commit f72f1effb079f66714f4399b12eaba077fc2b773 +Author: Patrick Wakano +Date: Wed Dec 2 13:58:18 2020 +0100 + + dialog: access dialog table entry by reference for dmq_send_all_dlgs + + - avoid race conditions to get and release the lock when entry structure + is copied in local variable + - GH #2570, GH #2547 + + (cherry picked from commit 4183b860e8af6d65074ab98a996c187211aebc7f) + +commit 7ef04a11c4b92a49dcf94dade5bb0a8c65880a43 +Author: Daniel-Constantin Mierla +Date: Wed Dec 2 09:45:48 2020 +0100 + + auth_diameter: init variable and check before freeing + + (cherry picked from commit 04dc5d6c66c85d0d411aa23b27bc6be00258eff6) + +commit e7f616df3f68bd7c53150ad20a8ec5a42b8daede +Author: Sergey Safarov +Date: Sun Nov 29 22:54:24 2020 +0300 + + lost: removed extra `"` symbol in example + + (cherry picked from commit 124499c12db185d85805e5c71d5cc4222e608b68) + +commit 4b5f58be3101c4efe745f37e286bf84b6ffd694f +Author: Sergey Safarov +Date: Sun Nov 29 22:44:33 2020 +0300 + + lost: fixed typo + + (cherry picked from commit 87f363f7fa0bf8f1897a3d6de13a09d6ec3812b9) + +commit 7c7fc27eb10372fda305a65c2dacea679a57efde +Author: Daniel-Constantin Mierla +Date: Thu Nov 26 13:54:42 2020 +0100 + + core: check if the tcp clone rcv buffer is set when applying changes + + (cherry picked from commit aa13720e5d78dde5ae5235c13399848cb8f5a0cc) + +commit 5c6ddfea8845cd2d76bd15ec5511d156ef2ba3c3 +Author: Daniel-Constantin Mierla +Date: Wed Nov 25 18:09:51 2020 +0100 + + dispatcher: removed unnecessary return + + (cherry picked from commit 721d533317c735d7ddbd16ad94684b483468c010) + +commit d610f27185eafe275e98c567f1c1781eb0325961 +Author: Aleksandar Yosifov +Date: Thu Nov 19 15:39:13 2020 +0200 + + smsops: fix len calc for a concatenated sms + + - fixed the calculation for concatenated SMSs + based on TS 23.040, Sec. 9.2.3.16 + + (cherry picked from commit d90f29b3b03386add989aebe3865bdc78dff8fbe) + +commit 0744976d1ab80caf09f80b7594d2c76de3437d9c +Author: Daniel-Constantin Mierla +Date: Mon Nov 23 13:48:01 2020 +0100 + + misc/examples/kemi: fixed function name to get From-URI + + (cherry picked from commit 6035c30aea72d06bf08883677d45f4eb0019f189) + +commit fba5f6172932c7925dce1ee49fbfeb4e6cceb6fc +Author: Daniel-Constantin Mierla +Date: Mon Nov 23 10:10:55 2020 +0100 + + etc/kamailio.cfg: split to filter on both friendly and scanner + + - some scanning scripts use a different format for the user agent + + (cherry picked from commit 454c4653409a69ef115de5ee748524d36e147246) + +commit c5793f508aa115146e10c2f32691a29a16dc98ce +Author: Daniel-Constantin Mierla +Date: Mon Nov 23 10:09:33 2020 +0100 + + misc/examples/kemi: filter on user agent matching friendly, scanner and sipvicious + + (cherry picked from commit e15c90d31fd0444f41cb862408f77399123c0191) + +commit 66f5cc9d021eca4a9acfbca935e991c2c6caed3f +Author: Daniel-Constantin Mierla +Date: Fri Nov 20 08:02:37 2020 +0100 + + misc/examples: note that sr is exported by app_lua_sr + + - hint for lua syntax check + + (cherry picked from commit 889431746d24c73eeff73705fab36a0e154116a9) + +commit 4851f0318bf049ccef93390f6ac0fdfa8a38c0b7 +Author: Daniel-Constantin Mierla +Date: Thu Nov 19 17:06:06 2020 +0100 + + tm: proper fill of From/To URI/tag values using parsed structure in t_uac_send() + + (cherry picked from commit aa6e9963b2725c1b6b7e5ff995a77c222d95fa3c) + +commit f8885c990642d4f2bebe47ea7d1f6ce8673c29f6 +Author: Daniel-Constantin Mierla +Date: Thu Dec 3 13:15:52 2020 +0100 + + tm: check end of header name in lw parser + + - proper identification of header type, prior could mistakenly set the + type by matching the prefix of long header name + - GH #2572 + + (cherry picked from commit c0f5382bfbd2022896a9b206967977f827517700) + +commit b9846143c171d731e94d7f0d450b40f66f2ac2c6 +Author: Victor Seva +Date: Fri Dec 4 10:23:04 2020 +0100 + + cfgt: log info when node is created and saved + + (cherry picked from commit a2eff905626c6428539d3d848e7968f5dd0f2108) + +commit 4fdc21a826533f1b889ee6e8302fe112859bf0fd +Author: Sergey Safarov +Date: Tue Dec 1 18:00:39 2020 +0300 + + pkg/kamailio/obs: updated tmpfiles + + fixed removing of kamailio_ctl and other files + +commit 49d833852bdcdc7c37ebd8d8d4e8cfb5ef149613 +Author: Daniel-Constantin Mierla +Date: Tue Dec 1 09:40:56 2020 +0100 + + dlgs: fixed return value for dlgs_tags_count() + + (cherry picked from commit 057383f0b780b8317831f72c7c9f64786cc5a25e) + +commit 3c8d3df471c92068144f84f2f02b9e79c8c723d2 +Author: Daniel-Constantin Mierla +Date: Mon Nov 30 14:07:21 2020 +0100 + + dlgs: fix counting dialogs function + + - count the dialog in initial state + - GH #2568 + + (cherry picked from commit 6376e24960878ca510ab6f1ce0594a351debc409) + +commit d0da78960e61aca42e75ba346b76616b59a16e86 +Author: Kamailio Dev +Date: Fri Nov 27 19:16:29 2020 +0100 + + modules: readme files regenerated - modules ... [skip ci] + +commit 89b66e50b93465c120e818dabd4c94f9443bd686 +Author: Henning Westerholt +Date: Fri Nov 27 18:05:35 2020 +0000 + + Revert "rtpengine: add CRC32 hash algo (#2558)" + + This reverts commit bc1cf60f970c572ecaddf1ea154834d0e41d292e. + +commit 18edda18229ee6e75370a078a5deb8f980274e52 +Author: Kamailio Dev +Date: Thu Nov 26 08:16:39 2020 +0100 + + modules: readme files regenerated - modules ... [skip ci] + +commit bc1cf60f970c572ecaddf1ea154834d0e41d292e +Author: Stefan Mititelu +Date: Wed Nov 25 19:20:52 2020 +0200 + + rtpengine: add CRC32 hash algo (#2558) + + (cherry picked from commit 10349080490faabffaf1ab7cc5d591678b8c94dd) + +commit 2d733ec7c9e26ad79d9d8503db0d342217febd30 +Author: Daniel-Constantin Mierla +Date: Wed Nov 18 14:14:48 2020 +0100 + + tm: print ruri mode in debug message from t load contacts + + (cherry picked from commit 3214ecd8ee82d1b69cde57d96dddefe1301c190c) + +commit f61d7a1b6b45bbed29bf4bc6c8a69fd52700ca41 +Author: Daniel-Constantin Mierla +Date: Wed Nov 18 14:04:15 2020 +0100 + + tm: use q field comparison in while for standard t contacts load + + - fix ordering change to standar mode introduced with proportional mode + - GH #2449 + + (cherry picked from commit 59f6ddbe902d61bc682dd12fc6330df656468b1b) + +commit d9a1a5cf667e7d093cc077fc51297825565c79d1 +Author: Daniel-Constantin Mierla +Date: Tue Nov 17 12:55:17 2020 +0100 + + drouting: give portparameter set to 0 to sip_resolvehost() + + - enable doing SRV query, GH #2553 + + (cherry picked from commit 18f59c10582845da5eea280990daf19c804978fb) + +commit c9ab7671bffdee3c775f6eb13cbd2363b6f5ecf3 +Author: Daniel-Constantin Mierla +Date: Mon Nov 16 10:06:20 2020 +0100 + + jsonrpcs: exported dispatch() function to kemi + + (cherry picked from commit 08a9ed3d136c861f990e4f63c2c0544e08d9078d) + +commit bec6cdf10dfbf9f32fce041987a3468b8a675a22 +Author: Aleksandar Yosifov +Date: Mon Nov 9 14:37:26 2020 +0200 + + core: added missing field in sip_msg_update_buffer + + - added a missing field in sip_msg_update_buffer() + when restoring message fiedls: msg->pid. + + (cherry picked from commit 57be5c1f33344275c15777a7927d9c48df4a69ba) + +commit f6747a1fe4af59062733090ee0081d1bf15669c3 +Author: Daniel-Constantin Mierla +Date: Mon Nov 9 13:10:43 2020 +0100 + + sctp: memcpy field data to avoid unaligned access warning + + - GH #2543 + + (cherry picked from commit 4bb099b046939b85e1827b804167a51ef4bc00c4) + +commit f3a872e9e8f780a23f7e3426ce4152a3a26cc448 +Author: Daniel-Constantin Mierla +Date: Mon Nov 9 12:31:24 2020 +0100 + + http_async_client: include poll.h instead sys/poll.h + + - according to POSIX specs + - GH #2543 + + (cherry picked from commit 8f30c75cff7787a39f7c934e00e933b1beb43c20) + +commit b72ab5e554d230b36a7c6dbc79b8e86b5d0c70e2 +Author: Daniel-Constantin Mierla +Date: Mon Nov 9 12:13:51 2020 +0100 + + core: init origproto to fix compiler warning + + - GH #2543 + + (cherry picked from commit ef3233d14080936486d09edbe9598d7d92bd2f33) + +commit 88f43b97768676fd2b84c3e855ec5ae441b826cd +Author: Daniel-Constantin Mierla +Date: Wed Nov 4 11:15:10 2020 +0100 + + dialog: skip doing cseq update processing for non-sip requests + + (cherry picked from commit 960b60ede8543f38b61ad2769e81e11d5a777df8) + +commit 82e00ce32c9a232be1dbd2e0a0e6e6c349e054b0 +Author: Daniel-Constantin Mierla +Date: Tue Nov 3 12:49:33 2020 +0100 + + exec: debug message when command returns non-zero + + (cherry picked from commit e9eee1ead964992a2d81014709755bbfd1e995c9) + +commit 17cb589ce5ac07dbb12f1b99f17258f313adf783 +Author: Daniel-Constantin Mierla +Date: Tue Nov 3 11:38:56 2020 +0100 + + dialog: small formatting changes + + (cherry picked from commit a3443211515068bb12ecbd53541785a5ebf1cb6c) + +commit 4b5f5636143037ff6620b88e03e57c05a91eabc4 +Author: Henning Westerholt +Date: Mon Nov 9 12:52:07 2020 +0000 + + crypto: properly initialize key and iv to 0, add comment regarding the size of IV + + - properly initialize key and iv to 0, otherwise invalid data might be printed + - the initialization vector for AES will be always AES blocksize, e.g. 128 bits + + (cherry picked from commit e9624bc4823cfba0bd9536a70b9eeadecb2a537e) + +commit 5c26e09f8c5be8c3de66958207701cdd7a8dce62 +Author: Sergey Safarov +Date: Mon Nov 9 00:19:44 2020 +0300 + + pkg/kamailio/alpine: packaged app_lua_sr module + + (cherry picked from commit 6782b2c1789f162b405ec0b9894f61075a4307f9) + +commit 345376cb49a5464ebb65f940e97262e010dc24ae +Author: Guillem Jover +Date: Thu Nov 5 18:34:43 2020 +0100 + + sl: Fix 3xx stats RPC marshalling + + The struct_add() method was getting 4 values but only 3 "d". + + (cherry picked from commit ac55cc5ce5fcbb50d3a2a6b228585dce8fc1150d) + +commit a97206031ff0c28f791a5789f6dfc37707a4b59d +Author: Julien Chavanton +Date: Thu Nov 5 07:09:38 2020 -0800 + + core: DNS stop resolving NAPTR for IP addresses (#2541) + + + (cherry picked from commit 37f06f031c4ce93bcf4494744282c17f7a2d157c) + +commit 5bd72f2758b2059759ce152e6d97b6a1955bc5bc +Author: Daniel-Constantin Mierla +Date: Wed Nov 4 08:09:39 2020 +0100 + + dialog: proper to-tag check for initial requests to skip cseq updates + + (cherry picked from commit 81d3e7a43a249dfc9eaa075c698e1eb3237a517e) + +commit e27c128abebcb06d1383a909ecfd21bcb4ca8026 +Author: Henning Westerholt +Date: Mon Nov 2 09:27:41 2020 +0000 + + dialog: small spelling fix in debug log message + + (cherry picked from commit 1640569d02420e0c0d0232fc825354d1f09784c8) + +commit a309a0ee48278923871197391a30d485f0513a4f +Author: Daniel-Constantin Mierla +Date: Mon Nov 2 09:04:46 2020 +0100 + + dialog: skip non-INVITE initial request for cseq update processing + + (cherry picked from commit a973882b064c758972ce40e9ac3a83440c613be1) + +commit bb016b3ac30bbd3c09c5ee8c10331c836231ed3d +Author: Daniel-Constantin Mierla +Date: Wed Oct 28 10:32:50 2020 +0100 + + dialog: update internal_get_dlg() after 0bde3ca changes + + - keep also direction value for no-totag dialog + - reference and unlock only when returning, related to #2494 + + (cherry picked from commit 98436c73e8519e96e3d167b7610cbb58b9939885) + +commit f76216bb1fab2dd39413915bc2db88d9c588a56e +Author: Henning Westerholt +Date: Fri Sep 11 10:51:23 2020 +0000 + + pkg: add CAP_CHOWN capability to Kamailio systemd service files to allow chown (#2391) + + - add CAP_CHOWN capability to Kamailio systemd service files to allow chown + - needed e.g. for user and group setting from jsonrpcs and ctl modules + - related to github issue #2391 + + (cherry picked from commit 8b72f462deb4b66fb55f754abc93bf7295278afa) + +commit 62dff5b8b157236cae7defe64291a6e4a8ae27b5 +Author: Kamailio Dev +Date: Wed Oct 28 20:16:28 2020 +0100 + + modules: readme files regenerated - modules ... [skip ci] + +commit 3deaec5ec6eda850e4b5c53e860d91460c317837 +Author: Henning Westerholt +Date: Wed Oct 28 19:02:33 2020 +0000 + + uac: extend docs for uac_auth() example, only t_relay() on success + + - extend docs for uac_auth() example, only t_relay() on success + - otherwise you will get a 'no branches for forwarding' error from tm + + (cherry picked from commit 668402e77c19ba4b5b8fc5b6c869ffbf34ea622d) + +commit 035e22e9d75949d066129b4056271ff772653500 +Author: Henning Westerholt +Date: Wed Oct 28 18:08:59 2020 +0000 + + uac: do not silently fail on realm lookup error, at least log with INFO + + (cherry picked from commit b6c10c8181d670a81a7d1216c7e6ec81c0963e9c) + +commit 4f00ba425051718ecbf426591fdb14268ae92d94 +Author: Paris Stamatopoulos +Date: Fri Oct 23 23:57:49 2020 +0300 + + auth_radius, misc_radius: Adds VENDOR() definition if the freeradius-client.h does not contain one already. + + (cherry picked from commit 9978e00405cac89cc65d2d8a863128dd2814d7fd) + + +===================== 2020-10-27 Version 5.4.2 Released ===================== + +===================== Changes Since Version 5.4.1 =========================== + +commit 44e95a7723aa71612050ad321a282c2bad04f2ea +Author: Daniel-Constantin Mierla +Date: Tue Oct 27 12:06:12 2020 +0100 + + Makefile.defs: version set to 5.4.2 + +commit c4186b78463899b044dd18dfca6f023b763ea502 +Author: Victor Seva +Date: Tue Oct 27 11:45:17 2020 +0100 + + pkg/kamailio/deb: version set 5.4.2 + +commit 6114e2fc8bc00cc8875720322fbacd35312628c3 +Author: Daniel-Constantin Mierla +Date: Tue Oct 27 09:55:02 2020 +0100 + + pkg: version set to 5.4 for rpm and alpine specs + +commit c8d42b328302e18c7b915b3760c5089910a1ad49 +Author: Daniel-Constantin Mierla +Date: Tue Oct 27 09:34:18 2020 +0100 + + xcap_server: shorten a bit the search range for xcaps_xpath_hack() + + - match on the buffer len min size, xmlns is expected to have a value, + plus the ending of the xml tag + + (cherry picked from commit 3be41802c7c670cce0d3e08462e23ca3f3fbe2d4) + +commit b51ea9f361a81fe8117dcef51902e975f7a662d0 +Author: Daniel-Constantin Mierla +Date: Mon Oct 26 14:02:48 2020 +0100 + + usrloc: safety check on len for user in db keepalive routine + + (cherry picked from commit a1620fa1b4587239835db6ed5765ce04f927172d) + +commit e3cda7fa4e873c110ee2641f6200fad52222586a +Author: Daniel-Constantin Mierla +Date: Mon Oct 26 13:36:36 2020 +0100 + + core: parser rr - clean partially cloned fields in case of error + + (cherry picked from commit e4f6c660bd75cdb9ff0855fcb511673cc8ec00c4) + +commit bd2204b7151261981bc6872928b7434e2ac7df2e +Author: Daniel-Constantin Mierla +Date: Mon Oct 26 13:06:53 2020 +0100 + + regex: use var to store strlen() values + + - avoid doing it again in a few cases + + (cherry picked from commit 5d490d616132067a5e914302a24b964b73b229a2) + +commit 900a05c4ba32513ebb61428ef53a4d1705f58443 +Author: Kamailio Dev +Date: Mon Oct 26 11:16:32 2020 +0100 + + modules: readme files regenerated - modules ... [skip ci] + +commit 7cd88cf05f25a5a5883d936285ac51f82911e9af +Author: Daniel-Constantin Mierla +Date: Mon Oct 26 10:53:24 2020 +0100 + + textops: docs - some enhancements to basic header operations functions + + (cherry picked from commit 374f0f05bdf27ddaf5d8652560738fbfb886c43c) + +commit 82ff4f40455a910ef42dd3692af5c1c9dfb8d4c1 +Author: Daniel-Constantin Mierla +Date: Mon Oct 26 09:17:02 2020 +0100 + + pv_headers: free hash entry in case of error + + (cherry picked from commit 46c7a8c0bf2b4d5c00e22a751f95f13263686445) + +commit aa0573d2afa3c1a0afa76b8fd1e0de952c487a01 +Author: Daniel-Constantin Mierla +Date: Mon Oct 26 08:15:10 2020 +0100 + + alias_db: clang format the code + + (cherry picked from commit 3dca5cd2c7f018189b6784a7e87807df1de7589e) + +commit 5114cc77cb61744843ed8b535d9804fcdf61e635 +Author: Daniel-Constantin Mierla +Date: Mon Oct 26 07:52:49 2020 +0100 + + alias_db: removed history from top comments + + - missing copyright header + + (cherry picked from commit 7ae0caaffd3d6e523fd32501401213521a1881e5) + +commit 83005d4fafd5d055e4125a83c24d1c6cd0eed058 +Author: Daniel-Constantin Mierla +Date: Mon Oct 26 07:42:10 2020 +0100 + + alias_db: set ending zero in a single place + + (cherry picked from commit dc1bb5b1861de279b450ab550888dd748b77463f) + +commit dfa7bf13fb0e5513cd3b1558765ba32e9300a120 +Author: Julien Chavanton +Date: Sun Oct 25 18:54:33 2020 +0000 + + rtp_media_server: state transition improvement + + - fix disconnection while in bridge, to keep thing simple for now the + second leg is automaticaly disconnected. + + (cherry picked from commit e419bad759dc817ba673563ec4e79681f685dc28) + +commit 407586bec91fac11311809d2693e521ad82394dc +Author: Julien Chavanton +Date: Fri Oct 23 20:21:45 2020 +0000 + + rtp_media_server: fix dialog_list_mutex + + issue 2522 + + (cherry picked from commit 750cb7fc131afa254952536bdb200d55e2cc8955) + +commit a5ee9476c8f403c42a6bc80d2228b49a39a0ca5b +Author: Julien Chavanton +Date: Fri Oct 23 19:37:35 2020 +0000 + + rtp_media_server: fix issue 2524 + + - fix completion without failure route + - rms_bridge automaticaly append missing ';' is not present + + (cherry picked from commit 2ea4f685ea8b7dbca13b4fd521441088f8318d1f) + +commit dc2336f541eb27d0a034f4c72a26c40270cfea70 +Author: Alex Hermann +Date: Mon Nov 13 16:48:30 2017 +0100 + + tmx: Allow $T_branch(flags) in onreply_route + + (cherry picked from commit d161d4523fc6b0619defe918bc204cc7a9cae073) + +commit e93717fe95f39c5832e4bc380fe4a1d24a4e977b +Author: Kamailio Dev +Date: Fri Oct 23 11:17:14 2020 +0200 + + modules: readme files regenerated - modules ... [skip ci] + +commit cbd9c3d2851ece3c8f08b0664b72fca18f6f4f77 +Author: Alex Hermann +Date: Mon Nov 13 15:50:20 2017 +0100 + + tm: Fix faked_reply_prio by passing correct reply to get_prio + + Instead of passing the to be evaluated reply as the "best" reply, pass the + actual "best" reply. + + (cherry picked from commit 5731cc0911ff65bf7efd433a83a25ffbf6073d10) + +commit 48df37a27ae2e42498d1cb44bec8604827a5ed55 +Author: Alex Hermann +Date: Fri Oct 23 10:32:02 2020 +0200 + + janssonrpcc: cleanups (#2512) + + * janssonrpcc: Remove unused variable and redundant assignment + + * janssonrpc: No need for copying options + + The address stay valid until free_params is called. And before that + happens, mod_jsonrpc_request() makes its own copy. + + (cherry picked from commit 61771b0595c126d884e8c1eb392a54b5786a8fa8) + +commit eae86ff8bf327b6ed0bcb83ee25c663cb97a02fc +Author: Stefan Mititelu +Date: Thu Oct 22 16:54:01 2020 +0300 + + textops: fix append_hf function + + Before: append_hf adds header after first header occurance + + After: append_hf adds header after last header occurance + (cherry picked from commit 4adea97a4f8a9b35273d4d28b0518964abb7f0d8) + +commit 071fe9366b3cc14f0cce1aa0373d20a0242182cb +Author: Kristian F. Høgh +Date: Wed Oct 21 11:21:43 2020 +0200 + + utils/pdbt: Relax permissions when creating files + + (cherry picked from commit bb42ee28fc115e1e3373962c02162c9a8e6d41fc) + +commit 39895a53b7df804573746585b5d0dd9d4a56f209 +Author: Daniel-Constantin Mierla +Date: Wed Oct 21 08:29:21 2020 +0200 + + rtp_media_server: use directly gen_lock_t instead of ser_lock_t which is tm typedef + + (cherry picked from commit 3a162187580880fa7210bd376621f57576e9d209) + +commit 9f2f517ffbc616d14567fcb9948147dae6507da0 +Author: Daniel-Constantin Mierla +Date: Wed Oct 21 08:24:53 2020 +0200 + + rtp_media_server: declare variables in .c files + + - extern in .h files, GH #2522 + + (cherry picked from commit 128ba4fe95f3c27474c9f839d34f8fb1fd75e064) + +commit 0752f63d41a5c02bc1a5612a22797f186e291119 +Author: Alex Hermann +Date: Tue Oct 20 14:58:28 2020 +0200 + + core: Document that a str can be zero-terminated + + But by default it isn't. + + The functions shm_str_dup() and pkg_str_dup() will always create a + zero-terminated copy + + (cherry picked from commit fcdfaf98acf8a66e84b9dccc767fb52c0cf0d460) + +commit 4e50930695e288b0285370cc7fd26801cbf751de +Author: Alex Hermann +Date: Tue Oct 20 10:13:29 2020 +0200 + + core: Zero terminate str copies made with (pkg|shm)_str_dup() + + As discussed in #2512, zero-terminating all copies is preferred as most str + usage is already with zero-terminated str.s. + + (cherry picked from commit 0ea69b16db298842f58a6fcaaab2c0ee1a137b94) + +commit f050ce2dc5f27a08bf5c5364e4002b646802eb81 +Author: Juha Heinanen +Date: Tue Oct 20 11:04:58 2020 +0300 + + registrar: added note about branch flags in save()/lookup() doc + + (cherry picked from commit f2996bf733a0b5e00fe124440353b9a69a3532a2) + +commit 12ebd41d0dae516f39933eeabcda1919cb10b71e +Author: Daniel-Constantin Mierla +Date: Mon Oct 19 11:01:12 2020 +0200 + + permissions: exported allow_trusted() to kemi + + - related to #2509 + + (cherry picked from commit 843b22b4efb0d343f13230d6e90d2484f370dbdb) + +commit 550840b4b9ce8df9acdf875f907ce86533fea43e +Author: Daniel-Constantin Mierla +Date: Mon Oct 19 10:09:59 2020 +0200 + + pipelimit: use unsigned to compute size and for iterator + + (cherry picked from commit 23818fb34d09a487654ea89c9f29b880c0c75197) + +commit 41b6be639eb56dbb9732e1961b75654a73ee2fa6 +Author: Emmanuel Schmidbauer +Date: Fri Oct 16 07:22:33 2020 -0400 + + nsq: remove unused defs.h file + + (cherry picked from commit 79db27575a48c5451b547ece68b5849456e245f9) + +commit e93b62f2f9a27943d68b1e2a8b2529f37a419292 +Author: Daniel-Constantin Mierla +Date: Fri Oct 16 08:49:12 2020 +0200 + + secsipid: docs - small typo + + (cherry picked from commit f74f1df842815e8a42d1b4f71b6f98287a625d41) + +commit d43872c11edacf972c2ae72c746517dcf56e2777 +Author: Kamailio Dev +Date: Fri Oct 16 14:16:41 2020 +0200 + + modules: readme files regenerated - modules ... [skip ci] + +commit ef7a0789a52a9b741ce679145f8fadb5c6b97755 +Author: Bastian Triller +Date: Fri Oct 16 12:41:00 2020 +0200 + + nathelper: docs - fixed typos + +commit b8576f0f34d373173ff223f00c6b6b2ce8daa85a +Author: Bastian Triller +Date: Fri Oct 16 12:32:45 2020 +0200 + + uac: docs - fix missing uac.reg_remove method + +commit 80c834d1eea1e1917f185d9d1110c7d07bb27bd6 +Author: Bastian Triller +Date: Fri Oct 16 12:36:13 2020 +0200 + + core: fix typo in comment + +commit a505f5eb2bb60f935d3ecc55b0dfa1b410c1bb58 +Author: Kamailio Dev +Date: Mon Oct 12 10:31:20 2020 +0200 + + modules: readme files regenerated - modules ... [skip ci] + +commit eec7d2613489613725b8979ce3d00d6616bb80c8 +Author: Daniel-Constantin Mierla +Date: Tue Oct 6 12:59:50 2020 +0200 + + rtpproxy: renamed extract_mediaip() to rp_extract_mediaip() + + - extract_mediaip() is also in core sdp parser + + (cherry picked from commit 8d0044770e94eaf7099eabbb55abe177e52e5373) + +commit a989f384b5cb95e096e89899c57d8f11283b12cb +Author: Daniel-Constantin Mierla +Date: Tue Oct 6 11:56:45 2020 +0200 + + nathelper: renamed extract_mediaip() to nh_extract_mediaip() + + - extract_mediaip() is also in core sdp parser + + (cherry picked from commit b0f239a2c16b71b8b7e7b325ea121ffc48afa78e) + +commit d5393ffd76cc37e98365d7b945454e0215d9f82f +Author: Arsen Semenov +Date: Tue Oct 6 11:40:27 2020 +0500 + + nathelper: docs - updated notes for fix_nated_sdp. few typos fixed [skip ci] + + (cherry picked from commit 64579fee33d0a82a583b75184f78fcb7c9df2d82) + +commit fd4dd36319599867e590098d86dc37186595cfad +Author: Arsen Semenov +Date: Mon Oct 5 13:52:45 2020 +0500 + + nathelper: fix_nated_sdp added support for a=rtcp param RFC3605 + + - GH #2459 + + (cherry picked from commit 088738ce16e73339e4c1b78c11f6ad6f8f3394cf) + +commit 755867b920e4e0d17a4bdf447a0d59a06875f8e1 +Author: Daniel-Constantin Mierla +Date: Fri Oct 2 21:37:15 2020 +0200 + + phonenum: note about the role of country code name for phonenum_match_cn() + + (cherry picked from commit dfd6c3966ed70d111a9196076bc29767c395d814) + +commit 75cb64a768d187baf5730067503a708959284827 +Author: Daniel-Constantin Mierla +Date: Thu Sep 24 10:04:08 2020 +0200 + + core: dns cache - removed disabled code between #if 0 ... #endif + + (cherry picked from commit 298aeb7f93bfa75ec78bc941f2c76167525b2e61) + +commit 1d8f45e88a8bc79646a330f5531c6b767e547754 +Author: Daniel-Constantin Mierla +Date: Thu Sep 17 14:21:30 2020 +0200 + + tmx: safety check of expected route blocks for using $T_*() variables + + - related to GH #2479 + + (cherry picked from commit 2e7710e292a649c6c57e46d5994d3b2cf3815865) + +commit 4c234562bf0265f2a221231e7f3d72648166995f +Author: Daniel-Constantin Mierla +Date: Thu Sep 17 12:55:10 2020 +0200 + + lib/srdb1: db_use_table() more suggestive error messages + + (cherry picked from commit 57d33a2d76219ae3d1eb503044dadaeddc7e06fd) + +commit 26fb90fd6ffdb239fa6c2779f281fae78f90c5ef +Author: Daniel-Constantin Mierla +Date: Tue Sep 15 07:33:00 2020 +0200 + + topos: docs - more details about what SIP traffic is handled + + (cherry picked from commit 878971f2c0bc32233b6f18728f9b88537b3d19e8) + +commit 23bdd1f6f2581d745f20c66ca9a93e4dad55ffec +Author: Daniel-Constantin Mierla +Date: Wed Sep 9 13:01:36 2020 +0200 + + msrp: proper parsing ipv6 host part in uri + + - enclose ipv6 address in square brackets for msrp pv + - related to #2472 + + (cherry picked from commit 1cda029885dd89e2ec46fe28a0d6f656aad19e7a) + +commit f57c900b438f3233fa1e9a9d3ca8cd383a30baa6 +Author: Daniel-Constantin Mierla +Date: Fri Oct 9 22:15:12 2020 +0200 + + tm: do not add duplicate headers in local requests + + (cherry picked from commit ada3701d22b1fd579f06b4f54fa695fa988e685f) + +commit 6e2bdf1056e3a31f1ca1f485473fcd26f9ccf044 +Author: Daniel-Constantin Mierla +Date: Fri Oct 9 21:59:49 2020 +0200 + + core: parser - print lenghts in to header parsing debug message + + (cherry picked from commit 2648eb330b133a20f1398d59a28c53532106cad3) + +commit 7adf410af754f1bb737edca6f427ef02d3441cda +Author: Daniel-Constantin Mierla +Date: Fri Oct 9 21:55:45 2020 +0200 + + sanity: extended check 4 (required headers) for uniqueness + + - Call-ID, CSeq, From and To have to be only once + + (cherry picked from commit a9ede56b35990fcc9164af0775f503e49e33377e) + +commit f4d5b1b86a821ed7e5168b15765bb40e83b3ec21 +Author: Daniel-Constantin Mierla +Date: Fri Oct 9 09:25:41 2020 +0200 + + usrloc: send keepalive over ws and wss connections + + (cherry picked from commit 5dda7f336121b6068fd306340cb90a7d7e76c708) + +commit 83f242845a8b2759d8eec0559154cfd62cf89278 +Author: Daniel-Constantin Mierla +Date: Fri Oct 9 07:52:29 2020 +0200 + + core: tcp - helper function to send data over ws/wss connection + + (cherry picked from commit 5e107824d684cdf30514b033e7f600862123ece5) + +commit 73476522301b6de65b8873e4ab04041315e93a82 +Author: Daniel-Constantin Mierla +Date: Mon Oct 5 11:53:01 2020 +0200 + + dialog: do unlock after saving updated dialog details + + - lock()/unlock() for dialog slots are reentrant + + (cherry picked from commit e4cf6739e62c2ac1e5364315aaed1a7b73919253) + +commit a24dc3a4e64671d3428c629b2d12a0d6ca1a93ca +Author: Henning Westerholt +Date: Sat Oct 3 16:58:53 2020 +0000 + + dialog: fix error in dlg.list_match for callid parameter (reported from Ilie Soltanici) + + (cherry picked from commit 360e012d9d93c80b62b6e75bfac6e3340407ee98) + +commit 76a0d84a02062f340bf6415db5270dbfce31136a +Author: Daniel-Constantin Mierla +Date: Wed Sep 30 12:34:40 2020 +0200 + + rr: reset param buffer for r-r advertised address + + - GH #2486 + + (cherry picked from commit 8dfc0f6ef0ddc4bf2d73d21124caa289d4b8ce07) + +commit 0b923cabb82870e5376f79682b90b65e71050249 +Author: Kamailio Dev +Date: Fri Oct 2 16:01:38 2020 +0200 + + modules: readme files regenerated - modules ... [skip ci] + +commit bcd8f50929ac25d4eabe7b5886d22dd61c4872e7 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:51:16 2020 -0600 + + Fix typo on main README.md: Consecutives 'the' + +commit 27f28271981e46ea9abec97392ab3232264c742f +Author: Jorge Vallecillo +Date: Thu Oct 1 20:50:41 2020 -0600 + + Fix typo on xmpp module: Consecutives 'the' + +commit 0eec5a2c839d9a1de6a152f733fe69e3353d1d22 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:50:02 2020 -0600 + + Fix typo on websocket module: Consecutives 'the' + +commit 2b4f7960ae740175fa4bd37fc2d93868fc52ac95 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:46:20 2020 -0600 + + Fix typo on tm module: Consecutives 'the' + +commit 3910066feabbfbe2f2f653b9b4af5d7d14285911 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:45:44 2020 -0600 + + Fix typo on sca module NOTES + +commit 13e6f48fe794455b673e73181397d6d6f8d355c6 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:44:27 2020 -0600 + + Fix typo on ims_qos module: Consecutives 'the' + +commit d26bf214e7050c051fa6db9477fd7650ad873509 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:43:44 2020 -0600 + + Fix typo on drouting module: Consecutives 'the' + +commit a8f66e8d3104ac35bb99023777a5363d700b3855 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:42:54 2020 -0600 + + Fix typo on db_mongodb module: Consecutives 'the' + +commit fe70897c15c8236fc226d2a05822f98e385ea083 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:41:54 2020 -0600 + + Fix typo on cplc module: Consecutives 'the' + +commit 54926260bcb0ef9c487ed66990f945fbe1cb1b13 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:40:13 2020 -0600 + + Fix typo on counters module: Consecutives 'the' + +commit 02f470f64d57d27b3035b9f8884d539916a8ca02 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:39:26 2020 -0600 + + Fix typo on carrierroute module: Consecutives 'the' + +commit ab5a57b1291316b4be57ade1219200db8222ac87 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:31:12 2020 -0600 + + Fix typo on avp module: Consecutives 'the' + +commit 408efc005320d055c16cce9a518954692eb75187 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:30:12 2020 -0600 + + Fix typo on app_jsdt module: Consecutives 'the' + +commit 5aff688af40e87c32e43c7c6d5abca60fbb22595 +Author: Jorge Vallecillo +Date: Thu Oct 1 20:29:03 2020 -0600 + + Fix typo on srdb1 lib: Consecutive 'the' + +commit 8006da08a44d15c37b07e20ea95e03b07ae1e66a +Author: Daniel-Constantin Mierla +Date: Thu Oct 1 10:04:50 2020 +0200 + + topos: update to-tag and rr on reply even to-tag is already set + + - GH #2489 + + (cherry picked from commit acd7f6f1703d12aa8f2dce87e1b8e4b74d6b4d96) + +commit 0bde3ca506467008cf3d8345afa731617b095c8c +Author: Julien Chavanton +Date: Mon Sep 28 09:13:16 2020 -0700 + + dialog: dlg_cell, always check for a to-tag match + +commit aed88c64710493452ee3ea8468c80c3c01287111 +Author: Daniel-Constantin Mierla +Date: Tue Sep 29 07:25:46 2020 +0200 + + pv: use the corresponding functions for parsing names of xavu and xavi + + (cherry picked from commit aa8589ba66f984e93438a91a7fe8b26bd9d5b62e) + +commit a6cb7427ea8d98ba10d51e1fde3648bb1aca53b6 +Author: Daniel-Constantin Mierla +Date: Fri Sep 25 09:38:39 2020 +0200 + + usrloc: set last keepalive value to current time on new records + + - do not rely on last modified value, can be loaded from db and be too + old + + (cherry picked from commit 60f04b6d6f51b55294d22722df3f351a76cbfb9b) + +commit 7f14deb8704697ebe1e073c8db30a5569bab6985 +Author: Daniel-Constantin Mierla +Date: Wed Sep 23 17:31:04 2020 +0200 + + usrloc: do keepalive mode checks before expire processing + + (cherry picked from commit e67b588434a08c828548c79b6cc5f4c2a7240dc9) + +commit f14111e9ba0139e79a2bf7b7c0c5bc98c47cf220 +Author: Daniel-Constantin Mierla +Date: Wed Sep 23 17:00:29 2020 +0200 + + usrloc: do keepalive-based contact expire on internal callback + + - the one used by nathelper is not triggered automatically + + (cherry picked from commit 5c1e07dc2efc46fe078263c76ce0388f09949539) + +commit 4669e8f295eefca64af61e168e5e79f540df89c8 +Author: Daniel-Constantin Mierla +Date: Tue Sep 22 19:00:25 2020 +0200 + + imc: jump over printing error log messages when list commands are ok + + - reported by GH #2481 + + (cherry picked from commit 92cfb5e8d291706889c926892397e663e2d93b05) + +commit 463498565029aced931b44fd686f5c9d15b49341 +Author: Victor Seva +Date: Wed Sep 23 09:01:43 2020 +0200 + + ndb_redis: set message level to debug on exec + + * logging error makes no sense here since there's going + to be a reconnection afterwards + + > ERROR: ndb_redis [redis_client.c:903]: redisc_exec_argv(): Redis error: Server closed the connection + + (cherry picked from commit a9c331d70dbed6827874aa99296203ac5a9d5c7b) + +commit 609685c91d92337a1d0832d709ebff437fb193ef +Author: Kamailio Dev +Date: Tue Sep 22 19:46:21 2020 +0200 + + modules: readme files regenerated - modules ... [skip ci] + +commit 79ec049ba50c0c48c02748c2679c07f4da2a766e +Author: Daniel-Constantin Mierla +Date: Fri Sep 11 22:06:45 2020 +0200 + + usrloc: docs for ka_timeout module parameter + + (cherry picked from commit 2e9d4e2dc45bf5baab1bff9c13fc841b66793cb4) + +commit f5eb642c9bc9012debd2009ad03f2598d0c7c354 +Author: Daniel-Constantin Mierla +Date: Fri Sep 11 22:00:38 2020 +0200 + + usrloc: export modparam to set keepalive timeout + + - variable was not exported by the module for internal keepalive + mechanism + + (cherry picked from commit 9331044bf517be120dea59414402415090b63007) + +commit 5cbec397d4dbe338400aefacddcce69dd0547f39 +Author: Kamailio Dev +Date: Tue Sep 15 18:01:22 2020 +0200 + + modules: readme files regenerated - modules ... [skip ci] + +commit acce084fcab7249d52862bef0f4c32ed488222bc +Author: whosgonna +Date: Tue Sep 15 10:29:08 2020 -0500 + + registrar: Update documentation + + - Replace all occurences of "HF" with "header field" + - Replace all occurences of "HFs" with "header fields" + + (cherry picked from commit d936c6276b6d8e45efd87a4fc25a55b9c3ab1fce) + +commit 76864d4508ff4e1d9d909480663819db272aae48 +Author: whosgonna +Date: Tue Sep 15 10:32:07 2020 -0500 + + registrar: Update documentation + + - Fix double negative "without no DB operation". Changed to + "with no DB operation". + + (cherry picked from commit be0382fa11920de972ddbcdbe17c3ff583da87e4) + +commit 99b2a0c066bcc35425b3a2bc73158711bba70b70 +Author: Daniel-Constantin Mierla +Date: Wed Sep 9 15:32:33 2020 +0200 + + core: more comments about data lump structure fields and options + + (cherry picked from commit b13431b6fc7eec20096c5be46c8ce2e43931c45f) + +commit 2ca2232b3cac72f7c03b37ef9db5a198462e6dfa +Author: Daniel-Constantin Mierla +Date: Wed Sep 9 15:33:18 2020 +0200 + + core: skip abort() in free_lump() for LUMPFLAG_DUPED + + - the LUMPFLAG_DUPED is set when duplicating lumps list for branch route + execution, but some functions such as set_body() may want to clean them + - report and minimal reproducing config by Henning Westerholt + + (cherry picked from commit 57ee97f52dd90c86743b6fd6dd682285ef994e80) + +commit 4e0f9f8869aaf364011413417ff6c95c032af16d +Author: Federico Cabiddu +Date: Tue Sep 8 15:04:04 2020 +0200 + + httpa_asyc_client: set curl memory callbacks in module initialization + +commit c7a07121012b23299331b22426852d9af534582f +Author: Daniel-Constantin Mierla +Date: Tue Sep 8 13:08:01 2020 +0200 + + core: events - return once SREV_SIP_REPLY_OUT callbacks are executed + + (cherry picked from commit 1910432ce3af56af1e6d4c4c124c2af2925c5b9a) + +commit 1a49cc015609c8701057d5a9cf50f68db61870c1 +Author: Daniel-Constantin Mierla +Date: Mon Sep 7 19:35:04 2020 +0200 + + uac: restore first display name then uri with dialog callback + + - same as for rr callback, otherwise the new header can be malformed: + the case of initial INVITE with From URI having no angle brackets and goes + out with display name and angle brackets, the ACK for 200ok results with + From broken when forwarded + + (cherry picked from commit efa6c6a9bf13c430d5be5146168d1ded4c39dba7) + +commit e1d4ddcb6c517f8fc3d688728f4d1310c5149352 +Author: Victor Seva +Date: Fri Sep 4 11:19:33 2020 +0200 + + pv_headers: fix $x_hdr index on get + + * previously we where not supporting pseudo-variables as index + + (cherry picked from commit 492c99e8065baa510f55154593122e33d3a61d73) + +commit ad14b61155686aead27e7ac5f3fb6b1aa90b6840 +Author: Daniel-Constantin Mierla +Date: Fri Sep 4 10:22:52 2020 +0200 + + pv: handle s.prefixes for empty values + + - avoid crash due to invalid length of result, GH #2467 + + (cherry picked from commit e74b06c32bc2b090937350858f655af4ab89ff63) + +commit 0f6dea703bd8a4cb5e450eddd046bce2b254e84d +Author: Victor Seva +Date: Wed Sep 2 13:12:25 2020 +0200 + + Revert "tls: support compilation without deprecated OpenSSL APIs" + + This reverts commit 10af8efa9061c2f52ee1db51c4cf665073c20dcc. + +commit e7cf0625893125bb45029f6e055ec7910f70d88f +Author: Victor Seva +Date: Wed Sep 2 13:12:06 2020 +0200 + + Revert "tls: added define condition on version functions" + + This reverts commit 67979e07b63b574687b1924c38fabd724d0ad876. + +commit abebfbed313aaf052f4383ecf03607f17549c63c +Author: Victor Seva +Date: Wed Sep 2 13:11:51 2020 +0200 + + Revert "tls: proper ifdef on libssl version for tls_init_locks()" + + This reverts commit e9baba91c6c7e3d1817e8a07bbabbce3a8efbe79. + +commit acebbeef29d538c245e58738574bb5432c4170f6 +Author: Daniel-Constantin Mierla +Date: Wed Sep 2 13:11:40 2020 +0200 + + kamctl: regenerated dbtext version table records + + - GH #2463 + + (cherry picked from commit 65f5d0ed0fb88f5312ac53f2faaa66a2098ce0d8) + +commit b43f98af239b8459bb8872464c954ba25ce3dbf5 +Author: Daniel-Constantin Mierla +Date: Wed Sep 2 13:11:18 2020 +0200 + + doc/stylesheets: set 0 for id column in dbtext version table records + + (cherry picked from commit fcd3f257c12d2e17fa92007f9d149e4ee27ec994) + + ===================== 2020-09-01 Version 5.4.1 Released ===================== ===================== Changes Since Version 5.4.0 =========================== diff --git a/README.md b/README.md index 800503077..85a4b7078 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ Kamailio development was started back in 2001 by [Fraunhofer Fokus](https://www. Fraunhofer Fokus is no longer actively involved in the evolution of the project. Kamailio is now developed and managed by its world wide community. Fokus still uses Kamailio in its research projects (such as OpenIMSCore) and it is hosting events related to the project, such as developer meetings or the Kamailio World Conference. -For more information about Kamailio, see the the [website of the project](https://www.kamailio.org), where you can find pointers to documentation, the project wiki and much more. +For more information about Kamailio, see the [website of the project](https://www.kamailio.org), where you can find pointers to documentation, the project wiki and much more. ## Contributions diff --git a/doc/man/kamailio.8 b/doc/man/kamailio.8 index b0196b30f..a97b43f3c 100644 --- a/doc/man/kamailio.8 +++ b/doc/man/kamailio.8 @@ -1,5 +1,5 @@ .\" -.TH kamailio 8 06.12.2016 kamailio "Kamailio SIP Server" +.TH kamailio 8 03.02.2021 kamailio "Kamailio SIP Server" .\" Process with .\" groff -man -Tascii kamailio.8 .\" @@ -8,39 +8,39 @@ kamailio \- a very fast and configurable SIP server .SH SYNOPSIS .B kamailio [ -.B \-hcrRvdDEVTI +.B \-hfcmMdVIhEeblLnvKrRDTNWwtugPGSQOaAxXY ] [ -.BI \-f " config\-file" +.BI \-a " auto\-aliases\-mode" ] [ -.BI \-l " address" +.BI \-A " pre\-processor\-define" ] [ -.BI \-n " processes\-no" +.BI \-b " max_rcv_buf_size" ] [ -.BI \-N " tcp processes\-no" +.BI \-f " config\-file" ] [ -.BI \-b " max_rcv_buf_size" +.BI \-g " gid" ] [ -.BI \-m " shared_mem_size" +.BI \-G " pgid\-file" ] [ -.BI \-M " private_mem_size" +.BI \-l " address" ] [ -.BI \-w " working\-dir" +.BI \-L " modules\-dir" ] [ -.BI \-t " chroot\-dir" +.BI \-M " private_mem_size" ] [ -.BI \-u " uid" +.BI \-m " shared_mem_size" ] [ -.BI \-g " gid" +.BI \-n " processes\-no" ] [ -.BI \-P " pid\-file" +.BI \-N " tcp processes\-no" ] [ -.BI \-G " pgid\-file" +.BI \-P " pid\-file" ] [ -.BI \-L " modules\-dir" +.BI \-t " chroot\-dir" ] [ -.BI \-a " auto\-aliases\-mode" +.BI \-u " uid" ] [ -.BI \-A " pre\-processor\-define" +.BI \-w " working\-dir" ] .SH DESCRIPTION @@ -49,28 +49,41 @@ is a very fast and configurable SIP (RFC3261) server. .SH OPTIONS .TP 12 -.B \-h -Displays a short usage description, including all available options. +.B .TP -.BI \-c -Checks the config file and displays the aliases and listen interface list. +.BI \-a " auto\-aliases\-mode" +Enable auto-aliases with 'yes' or 'on', disable with 'no' or 'off .TP -.BI \-r -Uses dns to check if it is necessary to add a "received=" field to a via. +.BI \-\-alias\fR=\fIval +Add an alias, the value has to be '[proto:]hostname[:port]' +(like for 'alias' global parameter) .TP -.BI \-R -Same as -.B \-r -but uses reverse dns. +.BI \-\-atexit\fR=\fIval +Control atexit callbacks execution from external libraries +which may access destroyed shm memory causing crash on shutdown. +Can be y[es] or 1 to enable atexit callbacks, n[o] or 0 to disable, +default is yes. .TP -.BI \-K -Turns on via host checking when forwarding replies. +.BI \-A " pre\-processor\-define" +Add config pre-processor define (e.g., -A WITH_AUTH, -A N=1, -A X='"Y"') +.TP +.BI \-b " max_rcv_buf_size" +Maximum receive buffer size which will not be exceeded by the auto-probing procedure even if the OS allows. +.TP +.BI \-c +Checks the config file and displays the aliases and listen interface list. +.TP +.BI \-\-cfg\-print +Print configuration file evaluating includes and ifdefs .TP .BI \-d Turns on debugging, multiple .B \-d increase the debug level. .TP +.BI \-\-debug\fR=\fIval +Debugging level value +.TP .BI \-D Control how daemonize is done: .br @@ -83,18 +96,12 @@ Control how daemonize is done: .B \-DDD - daemonize (default) .TP +.BI \-e +Log messages printed in terminal colors (requires -E) +.TP .BI \-E Sends all the log messages to stderr. .TP -.BI \-T -Disables TCP support. -.TP -.BI \-V -Displays the version number. -.TP -.BI \-I -Displays details of internal constants and attributes. -.TP .BI \-f " config\-file" Reads the configuration from .B " config\-file" @@ -102,6 +109,25 @@ Reads the configuration from .I /etc/kamailio/kamailio.cfg ). .TP +.BI \-g " gid" +Changes the group id under which +.B kamailio +runs. +.TP +.BI \-G " pgid\-file" +Creates a file containing the pgid of the main +.B kamailio +process. +.TP +.B \-h \-\-help +Displays a short usage description, including all available options. +.TP +.BI \-I +Displays details of internal constants and attributes. +.TP +.BI \-K +Turns on via host checking when forwarding replies. +.TP .BI \-l " address" Listens on the specified address/interface. Multiple .B \-l @@ -111,6 +137,27 @@ address = host|ip_address|interface_name. Example: -l localhost, -l udp:127.0.0.1:5080, -l eth0:5062. The default behaviour is to listen on all the ipv4 interfaces. .TP +.BI \-\-loadmodule\fR=\fIname +load the module specified by name +.TP +.BI \-\-log\-engine\fR=\fIname +log engine name and data +.TP +.BI \-L " modules\-dir" +Specifies the directory where to look for +.B kamailio +modules (default: /usr/lib/kamailio/modules or /usr/lib64/kamailio/modules) +.TP +.BI \-m " shared_mem_size" +Size of the shared memory which will be allocated (in Megabytes). +.TP +.BI \-\-modparam\fR=\fImodname:paramname:type:value +set the module parameter type has to be 's' for string value and 'i' for int value, +example: --modparam=corex:alias_subdomains:s:" NAME ".org +.TP +.BI \-M " private_mem_size" +Size of the private memory which will be allocated per process (in Megabytes). +.TP .BI \-n " processes\-no" Specifies the number of children processes forked per interface (default 8). .TP @@ -119,56 +166,83 @@ Specifies the number of children processes forked to handle tcp incoming connect .BI \-n ). .TP -.BI \-b " max_rcv_buf_size" -Maximum receive buffer size which will not be exceeded by the auto-probing procedure even if the OS allows. -.TP -.BI \-m " shared_mem_size" -Size of the shared memory which will be allocated (in Megabytes). +.BI \-P " pid\-file" +Creates a file containing the pid of the main +.B kamailio +process. .TP -.BI \-M " private_mem_size" -Size of the private memory which will be allocated per process (in Megabytes). +.BI \-O " optimization\-level" +Script optimization level (debugging option). .TP -.BI \-w " working\-dir" -Specifies the working directory. In the very improbable event that +.BI \-P " pid\-file" +Creates a file containing the pid of the main .B kamailio -will crash, the core file will be generated here. +process. +.TP +.BI \-Q +Number of sctp child processes (default: equal to +.BI \-n +). +.TP +.BI \-r +Uses dns to check if it is necessary to add a "received=" field to a via. +.TP +.BI \-R +Same as +.B \-r +but uses reverse dns (to use both: +.BI \-rR +). +.TP +.BI \-\-server\-id\fR=\fInum +Set the value for server_id +.TP +.BI \-\-subst\fR=\fIexp +Set a subst preprocessor directive +.TP +.BI \-\-substdef\fR=\fIexp +Set a substdef preprocessor directive +.TP +.BI \-\-substdefs\fR=\fIexp +Set a substdefs preprocessor directive. +.TP +.BI \-S +Disables SCTP support. .TP .BI \-t " chroot\-dir" Forces .B kamailio to chroot after reading the config file. .TP +.BI \-T +Disables TCP support. +.TP .BI \-u " uid" Changes the user id under which .B kamailio runs. .TP -.BI \-g " gid" -Changes the group id under which -.B kamailio -runs. +.BI "\-v \-V \-\-version" +Displays the version number. .TP -.BI \-P " pid\-file" -Creates a file containing the pid of the main -.B kamailio -process. +.BI \-x " name" +Specify internal manager for shared memory (shm) can be: fm, qm or tlsf .TP -.BI \-G " pgid\-file" -Creates a file containing the pgid of the main -.B kamailio -process. +.BI \-X " name" +Specify internal manager for private memory (pkg) if omitted, the one for shm is used .TP -.BI \-L " modules\-dir" -Specifies the directory where to look for + .BI \-Y " dir" + Runtime dir path +.TP +.BI \-w " working\-dir" +Specifies the working directory. In the very improbable event that .B kamailio -modules (default: /usr/lib/kamailio/modules or /usr/lib64/kamailio/modules) +will crash, the core file will be generated here. .TP -.BI \-a " auto\-aliases\-mode" -Enable auto-aliases with 'yes' or 'on', disable with 'no' or 'off +.BI \-W " type" +poll method (depending on support in OS, it can be: poll, +epoll_lt, epoll_et, sigio_rt, select, kqueue, /dev/poll). .TP -.BI \-A " pre\-processor\-define" -Add config pre-processor define (e.g., -A WITH_AUTH, -A N=1, -A X='"Y"') - .SH FILES .PD 0 .B /usr/sbin/kamailio diff --git a/doc/stylesheets/dbschema_k/xsl/dbtext.xsl b/doc/stylesheets/dbschema_k/xsl/dbtext.xsl index 8bb059914..29c4b4da7 100644 --- a/doc/stylesheets/dbschema_k/xsl/dbtext.xsl +++ b/doc/stylesheets/dbschema_k/xsl/dbtext.xsl @@ -53,6 +53,7 @@ + 0: diff --git a/etc/kamailio.cfg b/etc/kamailio.cfg index fed81be1d..f8cd34e33 100644 --- a/etc/kamailio.cfg +++ b/etc/kamailio.cfg @@ -615,7 +615,7 @@ route[REQINIT] { } } #!endif - if($ua =~ "friendly-scanner|sipcli|sipvicious|VaxSIPUserAgent") { + if($ua =~ "friendly|scanner|sipcli|sipvicious|VaxSIPUserAgent") { # silent drop for scanners - uncomment next line if want to reply # sl_send_reply("200", "OK"); exit; diff --git a/misc/examples/kemi/kamailio-basic-kemi-jsdt.js b/misc/examples/kemi/kamailio-basic-kemi-jsdt.js index 7cc880f29..9949739d9 100644 --- a/misc/examples/kemi/kamailio-basic-kemi-jsdt.js +++ b/misc/examples/kemi/kamailio-basic-kemi-jsdt.js @@ -116,24 +116,26 @@ function ksr_route_relay() function ksr_route_reqinit() { if (!KSR.is_myself_srcip()) { - if (!KSR.pv.is_null("$sht(ipban=>$si)")) { + var srcip = KSR.kx.get_srcip(); + if (KSR.htable.sht_match_name("ipban", "eq", srcip) > 0) { // ip is already blocked - KSR.dbg("request from blocked IP - " + KSR.pv.get("$rm") - + " from " + KSR.pv.get("$fu") + " (IP:" - + KSR.pv.get("$si") + ":" + KSR.pv.get("$sp") + ")\n"); + KSR.dbg("request from blocked IP - " + KSR.kx.get_method() + + " from " + KSR.kx.get_furi() + " (IP:" + + srcip + ":" + KSR.kx.get_srcport() + ")\n"); KSR.x.exit(); } if (KSR.pike.pike_check_req()<0) { - KSR.err("ALERT: pike blocking " + KSR.pv.get("$rm") - + " from " + KSR.pv.get("$fu") + " (IP:" - + KSR.pv.get("$si") + ":" + KSR.pv.get("$sp") + ")\n"); - KSR.pv.seti("$sht(ipban=>$si)", 1); + KSR.err("ALERT: pike blocking " + KSR.kx.get_method() + + " from " + KSR.kx.get_furi() + " (IP:" + + srcip + ":" + KSR.kx.get_srcport() + ")\n"); + KSR.htable.sht_seti("ipban", srcip, 1); KSR.x.exit(); } } if (KSR.corex.has_user_agent()>0) { - var UA = KSR.pv.gete("$ua"); - if (UA.indexOf("friendly-scanner")>=0 || UA.indexOf("sipcli")>=0) { + var UA = KSR.kx.gete_ua(); + if (UA.indexOf("friendly")>=0 || UA.indexOf("scanner")>=0 + || UA.indexOf("sipcli")>=0 || UA.indexOf("sipvicious")>=0) { KSR.sl.sl_send_reply(200, "OK"); KSR.x.exit(); } @@ -153,7 +155,7 @@ function ksr_route_reqinit() if (KSR.sanity.sanity_check(1511, 7)<0) { KSR.err("Malformed SIP message from " - + KSR.pv.get("$si") + ":" + KSR.pv.get("$sp") + "\n"); + + KSR.kx.get_srcip() + ":" + KSR.kx.get_srcport() + "\n"); KSR.x.exit(); } } @@ -237,7 +239,7 @@ function ksr_route_location() } -// IP authorization and user uthentication +// IP authorization and user authentication function ksr_route_auth() { if (!KSR.is_REGISTER()) { @@ -249,8 +251,8 @@ function ksr_route_auth() if (KSR.is_REGISTER() || KSR.is_myself_furi()) { // authenticate requests - if (KSR.auth_db.auth_check(KSR.pv.get("$fd"), "subscriber", 1)<0) { - KSR.auth.auth_challenge(KSR.pv.get("$fd"), 0); + if (KSR.auth_db.auth_check(KSR.kx.gete_fhost(), "subscriber", 1)<0) { + KSR.auth.auth_challenge(KSR.kx.gete_fhost(), 0); KSR.x.exit(); } // user authenticated - remove auth header @@ -339,8 +341,8 @@ function ksr_route_sipout() // equivalent of branch_route[...]{} function ksr_branch_manage() { - KSR.dbg("new branch [" + KSR.pv.get("$T_branch_idx") - + "] to " + KSR.pv.get("$ru") + "\n"); + KSR.dbg("new branch [" + KSR.tm.t_get_branch_index() + + "] to " + KSR.kx.get_ruri() + "\n"); ksr_route_natmanage(); return; } @@ -350,7 +352,7 @@ function ksr_branch_manage() function ksr_onreply_manage() { KSR.dbg("incoming reply\n"); - var scode = KSR.pv.get("$rs"); + var scode = KSR.kx.gets_status(); if (scode>100 && scode<=299) { ksr_route_natmanage(); } diff --git a/misc/examples/kemi/kamailio-basic-kemi-lua.lua b/misc/examples/kemi/kamailio-basic-kemi-lua.lua index a89652996..bddabbaa8 100644 --- a/misc/examples/kemi/kamailio-basic-kemi-lua.lua +++ b/misc/examples/kemi/kamailio-basic-kemi-lua.lua @@ -1,7 +1,7 @@ -- Kamailio - equivalent of routing blocks in Lua -- --- KSR - the new dynamic object exporting Kamailio functions (kemi) --- sr - the old static object exporting Kamailio functions +-- KSR - the object exporting Kamailio KEMI functions (app_lua module) +-- sr - the old object exporting Kamailio functions (app_lua_sr module) -- -- Relevant remarks: @@ -11,6 +11,9 @@ -- * KSR.drop() is only marking the SIP message for drop, but doesn't stop -- the execution of the script. Use KSR.x.exit() after it or KSR.x.drop() -- +-- Hints: +-- * Lua syntax check: luac -p /path/to/script.lua +-- -- debug callback function to print details of execution trace --[[ @@ -160,21 +163,21 @@ function ksr_route_reqinit() if KSR.htable.sht_match_name("ipban", "eq", srcip) > 0 then -- ip is already blocked KSR.dbg("request from blocked IP - " .. KSR.kx.get_method() - .. " from " .. KSR.kx.gete_furi() .. " (IP:" + .. " from " .. KSR.kx.get_furi() .. " (IP:" .. srcip .. ":" .. KSR.kx.get_srcport() .. ")\n"); KSR.x.exit(); end if KSR.pike.pike_check_req() < 0 then KSR.err("ALERT: pike blocking " .. KSR.kx.get_method() - .. " from " .. KSR.kx.gete_furi() .. " (IP:" + .. " from " .. KSR.kx.get_furi() .. " (IP:" .. srcip .. ":" .. KSR.kx.get_srcport() .. ")\n"); KSR.htable.sht_seti("ipban", srcip, 1); KSR.x.exit(); end end local ua = KSR.kx.gete_ua(); - if string.find(ua, "friendly-scanner") - or string.find(ua, "sipcli") then + if string.find(ua, "friendly") or string.find(ua, "scanner") + or string.find(ua, "sipcli") or string.find(ua, "sipvicious") then KSR.sl.sl_send_reply(200, "OK"); KSR.x.exit(); end diff --git a/misc/examples/kemi/kamailio-basic-kemi-python.py b/misc/examples/kemi/kamailio-basic-kemi-python.py index f73abfedc..601daa368 100644 --- a/misc/examples/kemi/kamailio-basic-kemi-python.py +++ b/misc/examples/kemi/kamailio-basic-kemi-python.py @@ -157,8 +157,8 @@ class kamailio: if KSR.corex.has_user_agent() > 0 : ua = KSR.pv.gete("$ua") - if (ua.find("friendly-scanner")!=-1 - or ua.find("sipcli")!=-1) : + if (ua.find("friendly")!=-1 or ua.find("scanner")!=-1 + or ua.find("sipcli")!=-1 or ua.find("sipvicious")!=-1) : KSR.sl.sl_send_reply(200, "Processed") return -255 diff --git a/misc/examples/kemi/kamailio-basic-kemi-ruby.rb b/misc/examples/kemi/kamailio-basic-kemi-ruby.rb index 11f96b460..2a3a9eca4 100644 --- a/misc/examples/kemi/kamailio-basic-kemi-ruby.rb +++ b/misc/examples/kemi/kamailio-basic-kemi-ruby.rb @@ -41,7 +41,7 @@ def ksr_request_route() # Auth ksr_route_auth() - + # Record routing for dialog forming requests (in case they are routed) KSR::HDR.remove("Route") if KSR.is_method_in("IS") then @@ -65,7 +65,8 @@ end def ksr_route_reqinit() if KSR::COREX.has_user_agent() > 0 then ua = KSR::PV.gete("$ua"); - if ua.include? 'friendly-scanner' or ua.include? 'sipcli' then + if ua.include? 'friendly' or ua.include? 'scanner' + or ua.include? 'sipcli' or ua.include? 'sipvicious' then KSR::SL.sl_send_reply(200, "OK"); exit end diff --git a/misc/examples/kemi/kamailio-basic-kemi-sqlang.sq b/misc/examples/kemi/kamailio-basic-kemi-sqlang.sq index 4926ec831..38672aa81 100644 --- a/misc/examples/kemi/kamailio-basic-kemi-sqlang.sq +++ b/misc/examples/kemi/kamailio-basic-kemi-sqlang.sq @@ -137,7 +137,8 @@ function ksr_route_reqinit() if (KSR.corex.has_user_agent()>0) { local UA = KSR.pv.get("$ua"); // if (sipscanregex.match(UA)) { - if (UA.find("friendly-scanner")!=null || UA.find("sipcli")!=null) { + if (UA.find("friendly")!=null || UA.find("scanner")!=null + || UA.find("sipcli")!=null || UA.find("sipvicious")!=null) { KSR.sl.sl_send_reply(200, "OK"); KSR.x.exit(); } diff --git a/pkg/kamailio/alpine/APKBUILD b/pkg/kamailio/alpine/APKBUILD index d243876d8..913168c65 100644 --- a/pkg/kamailio/alpine/APKBUILD +++ b/pkg/kamailio/alpine/APKBUILD @@ -4,7 +4,7 @@ # Maintainer: Nathan Angelacos pkgname=kamailio -pkgver=5.4.1 +pkgver=5.4.4 pkgrel=0 # If building from a git snapshot, specify the gitcommit @@ -157,7 +157,7 @@ _mod_list_presence="presence presence_conference presence_dialoginfo \ rls xcap_client xcap_server" # - modules depending on lua library -_mod_list_lua="app_lua" +_mod_list_lua="app_lua app_lua_sr" # - modules depending on perl library _mod_list_perl="app_perl db_perlvdb" diff --git a/pkg/kamailio/deb/bionic/changelog b/pkg/kamailio/deb/bionic/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/bionic/changelog +++ b/pkg/kamailio/deb/bionic/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/bionic/kamailio.service b/pkg/kamailio/deb/bionic/kamailio.service index a411114db..91f804dbb 100644 --- a/pkg/kamailio/deb/bionic/kamailio.service +++ b/pkg/kamailio/deb/bionic/kamailio.service @@ -20,6 +20,8 @@ Restart=on-failure # /run/kamailio in tmpfs RuntimeDirectory=kamailio RuntimeDirectoryMode=0770 +# necessary for chown of control files e.g. for jsonrpcs and ctl modules +AmbientCapabilities=CAP_CHOWN [Install] WantedBy=multi-user.target diff --git a/pkg/kamailio/deb/buster/changelog b/pkg/kamailio/deb/buster/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/buster/changelog +++ b/pkg/kamailio/deb/buster/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/buster/kamailio.service b/pkg/kamailio/deb/buster/kamailio.service index a411114db..91f804dbb 100644 --- a/pkg/kamailio/deb/buster/kamailio.service +++ b/pkg/kamailio/deb/buster/kamailio.service @@ -20,6 +20,8 @@ Restart=on-failure # /run/kamailio in tmpfs RuntimeDirectory=kamailio RuntimeDirectoryMode=0770 +# necessary for chown of control files e.g. for jsonrpcs and ctl modules +AmbientCapabilities=CAP_CHOWN [Install] WantedBy=multi-user.target diff --git a/pkg/kamailio/deb/debian/backports/precise b/pkg/kamailio/deb/debian/backports/precise index 13743a3f2..78e0d2cfd 100755 --- a/pkg/kamailio/deb/debian/backports/precise +++ b/pkg/kamailio/deb/debian/backports/precise @@ -90,7 +90,12 @@ sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ ruby/' ${DIST}/rules # no python3 for app_python3 sed -i -e '/python3-dev/d' -e '/^Package: kamailio-python3-modules/,/^$/d' \ - -e '/python3/d' ${DIST}/control + ${DIST}/control +# this removes python3 from Package: kamalio +sed -i -e '/python3/d' ${DIST}/control +# add that again +sed -i '/lsb-base,/a \ python3,' ${DIST}/control + sed -i -e 's/ python3[ ,$]*/ /' ${DIST}/rules sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ python3/' ${DIST}/rules diff --git a/pkg/kamailio/deb/debian/backports/wheezy b/pkg/kamailio/deb/debian/backports/wheezy index e8052665b..87f95168a 100755 --- a/pkg/kamailio/deb/debian/backports/wheezy +++ b/pkg/kamailio/deb/debian/backports/wheezy @@ -90,7 +90,12 @@ sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ ruby/' ${DIST}/rules # no python3 for app_python3 sed -i -e '/python3-dev/d' -e '/^Package: kamailio-python3-modules/,/^$/d' \ - -e '/python3/d' ${DIST}/control + ${DIST}/control +# this removes python3 from Package: kamalio +sed -i -e '/python3/d' ${DIST}/control +# add that again +sed -i '/lsb-base,/a \ python3,' ${DIST}/control + sed -i -e 's/ python3[ ,$]*/ /' ${DIST}/rules sed -i -e '/^EXTRA_EXCLUDED_MODULES=/s/$/ python3/' ${DIST}/rules diff --git a/pkg/kamailio/deb/debian/changelog b/pkg/kamailio/deb/debian/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/debian/changelog +++ b/pkg/kamailio/deb/debian/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/debian/kamailio.service b/pkg/kamailio/deb/debian/kamailio.service index a411114db..91f804dbb 100644 --- a/pkg/kamailio/deb/debian/kamailio.service +++ b/pkg/kamailio/deb/debian/kamailio.service @@ -20,6 +20,8 @@ Restart=on-failure # /run/kamailio in tmpfs RuntimeDirectory=kamailio RuntimeDirectoryMode=0770 +# necessary for chown of control files e.g. for jsonrpcs and ctl modules +AmbientCapabilities=CAP_CHOWN [Install] WantedBy=multi-user.target diff --git a/pkg/kamailio/deb/focal/changelog b/pkg/kamailio/deb/focal/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/focal/changelog +++ b/pkg/kamailio/deb/focal/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/focal/kamailio.service b/pkg/kamailio/deb/focal/kamailio.service index a411114db..91f804dbb 100644 --- a/pkg/kamailio/deb/focal/kamailio.service +++ b/pkg/kamailio/deb/focal/kamailio.service @@ -20,6 +20,8 @@ Restart=on-failure # /run/kamailio in tmpfs RuntimeDirectory=kamailio RuntimeDirectoryMode=0770 +# necessary for chown of control files e.g. for jsonrpcs and ctl modules +AmbientCapabilities=CAP_CHOWN [Install] WantedBy=multi-user.target diff --git a/pkg/kamailio/deb/jessie/changelog b/pkg/kamailio/deb/jessie/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/jessie/changelog +++ b/pkg/kamailio/deb/jessie/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/jessie/kamailio.service b/pkg/kamailio/deb/jessie/kamailio.service index a411114db..91f804dbb 100644 --- a/pkg/kamailio/deb/jessie/kamailio.service +++ b/pkg/kamailio/deb/jessie/kamailio.service @@ -20,6 +20,8 @@ Restart=on-failure # /run/kamailio in tmpfs RuntimeDirectory=kamailio RuntimeDirectoryMode=0770 +# necessary for chown of control files e.g. for jsonrpcs and ctl modules +AmbientCapabilities=CAP_CHOWN [Install] WantedBy=multi-user.target diff --git a/pkg/kamailio/deb/precise/changelog b/pkg/kamailio/deb/precise/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/precise/changelog +++ b/pkg/kamailio/deb/precise/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/precise/control b/pkg/kamailio/deb/precise/control index fec8c7598..89da6133a 100644 --- a/pkg/kamailio/deb/precise/control +++ b/pkg/kamailio/deb/precise/control @@ -62,6 +62,7 @@ Depends: adduser, lsb-base, python, + python3, ${misc:Depends}, ${shlibs:Depends}, Replaces: diff --git a/pkg/kamailio/deb/sid/changelog b/pkg/kamailio/deb/sid/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/sid/changelog +++ b/pkg/kamailio/deb/sid/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/sid/kamailio.service b/pkg/kamailio/deb/sid/kamailio.service index a411114db..91f804dbb 100644 --- a/pkg/kamailio/deb/sid/kamailio.service +++ b/pkg/kamailio/deb/sid/kamailio.service @@ -20,6 +20,8 @@ Restart=on-failure # /run/kamailio in tmpfs RuntimeDirectory=kamailio RuntimeDirectoryMode=0770 +# necessary for chown of control files e.g. for jsonrpcs and ctl modules +AmbientCapabilities=CAP_CHOWN [Install] WantedBy=multi-user.target diff --git a/pkg/kamailio/deb/stretch/changelog b/pkg/kamailio/deb/stretch/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/stretch/changelog +++ b/pkg/kamailio/deb/stretch/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/stretch/kamailio.service b/pkg/kamailio/deb/stretch/kamailio.service index a411114db..91f804dbb 100644 --- a/pkg/kamailio/deb/stretch/kamailio.service +++ b/pkg/kamailio/deb/stretch/kamailio.service @@ -20,6 +20,8 @@ Restart=on-failure # /run/kamailio in tmpfs RuntimeDirectory=kamailio RuntimeDirectoryMode=0770 +# necessary for chown of control files e.g. for jsonrpcs and ctl modules +AmbientCapabilities=CAP_CHOWN [Install] WantedBy=multi-user.target diff --git a/pkg/kamailio/deb/trusty/changelog b/pkg/kamailio/deb/trusty/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/trusty/changelog +++ b/pkg/kamailio/deb/trusty/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/wheezy/changelog b/pkg/kamailio/deb/wheezy/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/wheezy/changelog +++ b/pkg/kamailio/deb/wheezy/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/wheezy/control b/pkg/kamailio/deb/wheezy/control index fec8c7598..89da6133a 100644 --- a/pkg/kamailio/deb/wheezy/control +++ b/pkg/kamailio/deb/wheezy/control @@ -62,6 +62,7 @@ Depends: adduser, lsb-base, python, + python3, ${misc:Depends}, ${shlibs:Depends}, Replaces: diff --git a/pkg/kamailio/deb/xenial/changelog b/pkg/kamailio/deb/xenial/changelog index 92700e56f..9572ba8c3 100644 --- a/pkg/kamailio/deb/xenial/changelog +++ b/pkg/kamailio/deb/xenial/changelog @@ -1,3 +1,21 @@ +kamailio (5.4.4) unstable; urgency=medium + + * version set 5.4.4 + + -- Victor Seva Mon, 15 Feb 2021 09:31:26 +0100 + +kamailio (5.4.3) unstable; urgency=medium + + * version set 5.4.3 + + -- Victor Seva Mon, 14 Dec 2020 09:44:12 +0100 + +kamailio (5.4.2) unstable; urgency=medium + + * version set 5.4.2 + + -- Victor Seva Tue, 27 Oct 2020 11:44:52 +0100 + kamailio (5.4.1) unstable; urgency=medium * version set 5.4.1 diff --git a/pkg/kamailio/deb/xenial/kamailio.service b/pkg/kamailio/deb/xenial/kamailio.service index a411114db..91f804dbb 100644 --- a/pkg/kamailio/deb/xenial/kamailio.service +++ b/pkg/kamailio/deb/xenial/kamailio.service @@ -20,6 +20,8 @@ Restart=on-failure # /run/kamailio in tmpfs RuntimeDirectory=kamailio RuntimeDirectoryMode=0770 +# necessary for chown of control files e.g. for jsonrpcs and ctl modules +AmbientCapabilities=CAP_CHOWN [Install] WantedBy=multi-user.target diff --git a/pkg/kamailio/obs/kamailio.service b/pkg/kamailio/obs/kamailio.service index b1305fa37..4d6e008d3 100644 --- a/pkg/kamailio/obs/kamailio.service +++ b/pkg/kamailio/obs/kamailio.service @@ -13,6 +13,8 @@ Environment='PKG_MEMORY=4' EnvironmentFile=-/etc/sysconfig/kamailio ExecStart=/usr/sbin/kamailio -DD -P /run/kamailio/kamailio.pid -f $CFGFILE -m $SHM_MEMORY -M $PKG_MEMORY Restart=on-failure +# necessary for chown of control files e.g. for jsonrpcs and ctl modules +AmbientCapabilities=CAP_CHOWN [Install] WantedBy=multi-user.target diff --git a/pkg/kamailio/obs/kamailio.spec b/pkg/kamailio/obs/kamailio.spec index 42a9c88db..0bd9c0238 100644 --- a/pkg/kamailio/obs/kamailio.spec +++ b/pkg/kamailio/obs/kamailio.spec @@ -1,5 +1,5 @@ %define name kamailio -%define ver 5.4.1 +%define ver 5.4.4 %define rel dev1.0%{dist} %if 0%{?fedora} @@ -1119,6 +1119,12 @@ UUID module for Kamailio. sed -i -e 's/python3/python2/' utils/kamctl/dbtextdb/dbtextdb.py %endif +# on latest dist need to add --atexit=no for Kamailio options. More details GH #2616 +%if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} == 8 +sed -i -e 's|/usr/sbin/kamailio|/usr/sbin/kamailio --atexit=no|' pkg/kamailio/obs/kamailio.service +%endif + + %build ln -s ../obs pkg/kamailio/%{dist_name}/%{dist_version} %if 0%{?fedora} || 0%{?suse_version} || 0%{?rhel} == 8 diff --git a/pkg/kamailio/obs/kamailio.tmpfiles b/pkg/kamailio/obs/kamailio.tmpfiles index dd2c42484..78cf6289e 100644 --- a/pkg/kamailio/obs/kamailio.tmpfiles +++ b/pkg/kamailio/obs/kamailio.tmpfiles @@ -1 +1,6 @@ -D /run/kamailio 0700 kamailio kamailio - +x /run/kamailio/kamailio_ctl +x /run/kamailio/kamailio.pid +x /run/kamailio/kamailio_rpc.fifo +x /run/kamailio/kamailio_rpc.sock +d /run/kamailio 0700 kamailio kamailio 7d + diff --git a/src/Makefile.defs b/src/Makefile.defs index 05e47cdfa..c51796568 100644 --- a/src/Makefile.defs +++ b/src/Makefile.defs @@ -106,7 +106,7 @@ INSTALL_FLAVOUR=$(FLAVOUR) # version number VERSION = 5 PATCHLEVEL = 4 -SUBLEVEL = 1 +SUBLEVEL = 4 EXTRAVERSION = # memory manager switcher diff --git a/src/core/autover.h b/src/core/autover.h index bcc897e30..df9cbb77c 100644 --- a/src/core/autover.h +++ b/src/core/autover.h @@ -2,6 +2,6 @@ * DO NOT EDIT IT */ -#define REPO_VER "09fd6a" -#define REPO_HASH "09fd6a" +#define REPO_VER "e16352" +#define REPO_HASH "e16352" #define REPO_STATE "" diff --git a/src/core/cfg.lex b/src/core/cfg.lex index 00f70ea82..73be332a2 100644 --- a/src/core/cfg.lex +++ b/src/core/cfg.lex @@ -39,8 +39,12 @@ #include "select.h" #include "cfg.tab.h" #include "sr_compat.h" + #include "daemonize.h" #include "ppcfg.h" + static void ksr_yy_fatal_error(const char* msg); + #define YY_FATAL_ERROR(msg) ksr_yy_fatal_error(msg); + /* states */ #define INITIAL_S 0 #define COMMENT_S 1 @@ -1271,7 +1275,7 @@ IMPORTFILE "import_file" LM_CRIT( "error at %s line %d: '-' not allowed\n", (finame)?finame:"cfg", line); - exit(-1); + ksr_exit(-1); } {ID} { count(); if (pp_define(yyleng, yytext)) return 1; @@ -1304,7 +1308,7 @@ IMPORTFILE "import_file" LM_CRIT( "error at %s line %d: '-' not allowed\n", (finame)?finame:"cfg", line); - exit(-1); + ksr_exit(-1); } {ID} { count(); pp_ifdef_var(yyleng, yytext); @@ -1351,7 +1355,7 @@ IMPORTFILE "import_file" if(sr_push_yy_state(s_buf.s, 0)<0) { LOG(L_CRIT, "error at %s line %d\n", (finame)?finame:"cfg", line); - exit(-1); + ksr_exit(-1); } memset(&s_buf, 0, sizeof(s_buf)); BEGIN(INITIAL); @@ -1365,7 +1369,7 @@ IMPORTFILE "import_file" if(sr_push_yy_state(s_buf.s, 1)<0) { LM_CRIT("error at %s line %d\n", (finame)?finame:"cfg", line); - exit(-1); + ksr_exit(-1); } memset(&s_buf, 0, sizeof(s_buf)); BEGIN(INITIAL); @@ -1459,7 +1463,7 @@ static char* addstr(struct str_buf* dst_b, char* src, int len) return dst_b->s; error: PKG_MEM_CRITICAL; - exit(-1); + ksr_exit(-1); } @@ -1970,3 +1974,12 @@ static void pp_endif() pp_update_state(); } +static void ksr_yy_fatal_error(const char* msg) +{ + if(ksr_atexit_mode==1) { + yy_fatal_error(msg); + } + + fprintf( stderr, "%s\n", msg ); + _exit( YY_EXIT_FAILURE ); +} diff --git a/src/core/cfg.y b/src/core/cfg.y index 7219cf48c..17ff6d354 100644 --- a/src/core/cfg.y +++ b/src/core/cfg.y @@ -69,6 +69,7 @@ #include "ppcfg.h" #include "pvapi.h" #include "config.h" +#include "daemonize.h" #include "cfg_core.h" #include "cfg/cfg.h" #ifdef CORE_TLS @@ -3436,7 +3437,7 @@ cmd: if (mod_func_action != NULL) { LM_ERR("function used inside params of another function: %s\n", $1); yyerror("use of function execution inside params not allowed\n"); - exit(-1); + ksr_exit(-1); } mod_func_action = mk_action(MODULE0_T, 2, MODEXP_ST, NULL, NUMBER_ST, 0); } LPAREN func_params RPAREN { @@ -3456,7 +3457,7 @@ cmd: }else{ if (mod_func_action && mod_f_params_pre_fixup(mod_func_action)<0) { /* error messages are printed inside the function */ - free_mod_func_action(mod_func_action); + /* free_mod_func_action(mod_func_action); */ mod_func_action = 0; YYERROR; } diff --git a/src/core/config.h b/src/core/config.h index e35fd6dab..06fe5cbb7 100644 --- a/src/core/config.h +++ b/src/core/config.h @@ -111,7 +111,10 @@ #define COMP_PARAM ";comp=" #define COMP_PARAM_LEN (sizeof(COMP_PARAM)-1) -#define SOCKNAME_PARAM ";sn=" +#define SOCKNAME_ATTR "sn" +#define SOCKNAME_ATTR_LEN (sizeof(SOCKNAME_ATTR)-1) + +#define SOCKNAME_PARAM ";" SOCKNAME_ATTR "=" #define SOCKNAME_PARAM_LEN (sizeof(SOCKNAME_PARAM)-1) #define SIGCOMP_NAME "sigcomp" diff --git a/src/core/daemonize.c b/src/core/daemonize.c index d6692523c..3982c4cdc 100644 --- a/src/core/daemonize.c +++ b/src/core/daemonize.c @@ -297,14 +297,14 @@ int daemonize(char* name, int status_wait) goto error; }else if (pid!=0){ if (status_wait) { - if (daemon_status_wait(&pipe_status) == 0) - exit((int)pipe_status); - else{ + if (daemon_status_wait(&pipe_status) == 0) { + ksr_exit((int)pipe_status); + } else { LM_ERR("Main process exited before writing to pipe\n"); - exit(-1); + ksr_exit(-1); } } - exit(0); + ksr_exit(0); } if (status_wait) daemon_status_no_wait(); /* clean unused read fd */ @@ -320,7 +320,7 @@ int daemonize(char* name, int status_wait) goto error; }else if (pid!=0){ /*parent process => exit */ - exit(0); + ksr_exit(0); } } diff --git a/src/core/daemonize.h b/src/core/daemonize.h index a8ee113a7..2461f97bb 100644 --- a/src/core/daemonize.h +++ b/src/core/daemonize.h @@ -41,6 +41,16 @@ int daemon_status_send(char status); void daemon_status_no_wait(void); void daemon_status_on_fork_cleanup(void); +extern int ksr_atexit_mode; + +#define ksr_exit(excode) do { \ + if(ksr_atexit_mode==1) { \ + exit(excode); \ + } else { \ + _exit(excode); \ + } \ + } while(0) + #endif /*_daemonize_h */ /* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/src/core/data_lump.c b/src/core/data_lump.c index 765dd5f98..a9a488019 100644 --- a/src/core/data_lump.c +++ b/src/core/data_lump.c @@ -456,14 +456,17 @@ struct lump* anchor_lump2(struct sip_msg* msg, int offset, int len, } +/** + * free lump content + */ void free_lump(struct lump* lmp) { - if (lmp && (lmp->op==LUMP_ADD)){ - if (lmp->u.value){ - if (lmp->flags &(LUMPFLAG_DUPED|LUMPFLAG_SHMEM)){ + if (lmp && (lmp->op==LUMP_ADD)) { + if (lmp->u.value) { + if (lmp->flags & LUMPFLAG_SHMEM) { LM_CRIT("non free-able lump: %p flags=%x\n", lmp, lmp->flags); abort(); - }else{ + } else if(!(lmp->flags & LUMPFLAG_DUPED)) { pkg_free(lmp->u.value); lmp->u.value=0; lmp->len=0; diff --git a/src/core/dns_cache.c b/src/core/dns_cache.c index c8567813e..05dc3f98b 100644 --- a/src/core/dns_cache.c +++ b/src/core/dns_cache.c @@ -2488,37 +2488,6 @@ struct hostent* dns_resolvehost(char* name) } - - -#if 0 -/* resolves a host name trying NAPTR, SRV, A & AAAA lookups, for details - * see dns_sip_resolve() - * FIXME: this version will return only the first ip - * returns: hostent struct & *port filled with the port from the SRV record; - * 0 on error - */ -struct hostent* dns_sip_resolvehost(str* name, unsigned short* port, - char* proto) -{ - struct dns_srv_handle h; - struct ip_addr ip; - int ret; - - if ((cfg_get(core, core_cfg, use_dns_cache==0)) || (dns_hash==0)){ - /* not init or off => use normal, non-cached version */ - return _sip_resolvehost(name, port, proto); - } - dns_srv_handle_init(&h); - ret=dns_sip_resolve(&h, name, &ip, port, proto, dns_flags); - dns_srv_handle_put(&h); - if (ret>=0) - return ip_addr2he(name, &ip); - return 0; -} -#endif - - - /* resolves a host name trying SRV lookup if *port==0 or normal A/AAAA lookup * if *port!=0. * when performing SRV lookup (*port==0) it will use proto to look for @@ -3292,6 +3261,7 @@ inline static int dns_naptr_sip_resolve(struct dns_srv_handle* h, str* name, ret=-E_DNS_NO_NAPTR; if(proto) origproto=*proto; + else origproto = PROTO_NONE; if (dns_hash==0){ /* not init => use normal, non-cached version */ LM_WARN("called before dns cache initialization\n"); h->srv=h->a=0; @@ -3323,6 +3293,9 @@ inline static int dns_naptr_sip_resolve(struct dns_srv_handle* h, str* name, } try_lookup_naptr = 1; } + /* check if it's an ip address, dns_srv_sip_resolve will return the right failure */ + if (str2ip(name) || str2ip6(name)) + goto naptr_not_found; /* do naptr lookup */ if ((e=dns_get_entry(name, T_NAPTR))==0) goto naptr_not_found; diff --git a/src/core/events.c b/src/core/events.c index 91df67399..d48d7a781 100644 --- a/src/core/events.c +++ b/src/core/events.c @@ -334,6 +334,7 @@ int sr_event_exec(int type, sr_event_param_t *evp) && _sr_events_list.sip_reply_out[i]; i++) { ret |= _sr_events_list.sip_reply_out[i](evp); } + return ret; } else return 1; default: return -1; diff --git a/src/core/kemi.c b/src/core/kemi.c index 6ca519e80..2ea6f4daa 100644 --- a/src/core/kemi.c +++ b/src/core/kemi.c @@ -851,6 +851,12 @@ static int sr_kemi_core_is_method_in(sip_msg_t *msg, str *vmethod) return SR_KEMI_TRUE; } break; + case 'E': + case 'e': + if(imethod==METHOD_PRACK) { + return SR_KEMI_TRUE; + } + break; case 'P': case 'p': if(imethod==METHOD_PUBLISH) { diff --git a/src/core/lump_struct.h b/src/core/lump_struct.h index 2ee5d092f..32e6532ad 100644 --- a/src/core/lump_struct.h +++ b/src/core/lump_struct.h @@ -16,8 +16,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ /*! @@ -35,20 +35,21 @@ enum lump_op { LUMP_NOP=0, LUMP_DEL, LUMP_ADD, LUMP_ADD_SUBST, LUMP_ADD_OPT }; -enum lump_subst{ SUBST_NOP=0, /* do nothing */ - SUBST_RCV_IP, SUBST_SND_IP, /* add ip address */ - SUBST_RCV_PORT, SUBST_SND_PORT, /* add port no */ - SUBST_RCV_PROTO, SUBST_SND_PROTO, /* add protocol(udp,tcp,tls)*/ - SUBST_RCV_ALL, SUBST_SND_ALL, /* ip:port;transport=proto */ - SUBST_RCV_ALL_EX, SUBST_SND_ALL_EX /* ip:port;transport=proto;sn=xyz */ - }; + +enum lump_subst{ SUBST_NOP=0, /* do nothing */ + SUBST_RCV_IP, SUBST_SND_IP, /* add ip address */ + SUBST_RCV_PORT, SUBST_SND_PORT, /* add port no */ + SUBST_RCV_PROTO, SUBST_SND_PROTO, /* add protocol(udp,tcp,tls)*/ + SUBST_RCV_ALL, SUBST_SND_ALL, /* ip:port;transport=proto */ + SUBST_RCV_ALL_EX, SUBST_SND_ALL_EX /* ip:port;transport=proto;sn=xyz */ + }; /* Where: - SND = sending, e.g the src ip of the outgoing message - RCV = received e.g the dst ip of the original incoming msg, - or the ip of the ser socket on which the msg was received - For SUBST_{RCV,SND}_ALL, :port is added only if port!=5060 - and transport=proto only if proto!=udp - */ + * SND = sending, e.g the src ip of the outgoing message + * RCV = received e.g the dst ip of the original incoming msg, + * or the ip of the ser socket on which the msg was received + * For SUBST_{RCV,SND}_ALL, :port is added only if port!=5060 + * and transport=proto only if proto!=udp + */ enum lump_conditions { COND_FALSE, /* always false */ COND_TRUE, /* always true */ @@ -59,14 +60,20 @@ enum lump_conditions { COND_FALSE, /* always false */ COND_IF_DIFF_IP, /* true if RCV ip != SND ip */ COND_IF_RAND /* 50-50 random prob.of being true*/ }; - /* Where: - REALM= ip_addr:port:proto - af = address family (ipv4 or ipv6) - proto = protocol (tcp, udp, tls) + /* Where: + * REALM= ip_addr:port:proto + * af = address family (ipv4 or ipv6) + * proto = protocol (tcp, udp, tls) */ -enum lump_flag { LUMPFLAG_NONE=0, LUMPFLAG_DUPED=1, LUMPFLAG_SHMEM=2, - LUMPFLAG_BRANCH=4, LUMPFLAG_COND_TRUE=8 }; +enum lump_flag { LUMPFLAG_NONE=0, /* */ + LUMPFLAG_DUPED=1, /* lump struct duplicated in pkg, with value + * pointing to initial lump structure + * - e.g., used for branch_route execution */ + LUMPFLAG_SHMEM=2, /* lump stored in shared memory (e.g., tm) */ + LUMPFLAG_BRANCH=4, /* not in use ?!? */ + LUMPFLAG_COND_TRUE=8 /* conditional lump processing */ +}; #define LUMP_SET_COND_TRUE(_lump) (_lump)->flags |= LUMPFLAG_COND_TRUE #define LUMP_IS_COND_TRUE(_lump) ((_lump)->flags & LUMPFLAG_COND_TRUE) @@ -74,7 +81,7 @@ enum lump_flag { LUMPFLAG_NONE=0, LUMPFLAG_DUPED=1, LUMPFLAG_SHMEM=2, typedef struct lump{ enum _hdr_types_t type; /* HDR_VIA_T, HDR_OTHER_T (0), ... */ enum lump_op op; /* DEL, ADD, NOP, UNSPEC(=0) */ - + union{ int offset; /* used for DEL, MODIFY */ enum lump_subst subst; /*what to subst: ip addr, port, proto*/ @@ -82,13 +89,13 @@ typedef struct lump{ char * value; /* used for ADD */ }u; int len; /* length of this header field */ - - + + struct lump* before; /* list of headers to be inserted in front of the current one */ - struct lump* after; /* list of headers to be inserted immediately after - the current one */ - + struct lump* after; /* list of headers to be inserted immediately after + * the current one */ + struct lump* next; enum lump_flag flags; /* additional hints for use from TM's shmem */ @@ -98,7 +105,7 @@ typedef struct lump{ /* * hdrs must be kept sorted after their offset (DEL, NOP, UNSPEC) * and/or their position (ADD). E.g.: - * - to delete header Z insert it in to the list according to its offset + * - to delete header Z insert it in to the list according to its offset * and with op=DELETE * - if you want to add a new header X after a header Y, insert Y in the list * with op NOP and after it X (op ADD). @@ -107,11 +114,11 @@ typedef struct lump{ * -if you want to replace Y with X, insert Y with op=DELETE and then X with * op=ADD. * before and after must contain only ADD ops! - * + * * Difference between "after" & "next" when Adding: * "after" forces the new header immediately after the current one while * "next" means another header can be inserted between them. - * + * */ /* frees the content of a lump struct */ diff --git a/src/core/msg_translator.c b/src/core/msg_translator.c index fd183d4f8..11e75426b 100644 --- a/src/core/msg_translator.c +++ b/src/core/msg_translator.c @@ -3251,7 +3251,12 @@ int sip_msg_update_buffer(sip_msg_t *msg, str *obuf) LM_ERR("invalid buffer parameter\n"); return -1; } - +#ifdef USE_TCP + if(tcp_get_clone_rcvbuf()==0) { + LM_ERR("tcp clone received buffer not enabled\n"); + return -1; + } +#endif if(obuf->len >= BUF_SIZE) { LM_ERR("new buffer is too large (%d)\n", obuf->len); return -1; @@ -3276,6 +3281,7 @@ int sip_msg_update_buffer(sip_msg_t *msg, str *obuf) /* restore msg fields */ msg->buf = tmp.buf; msg->id = tmp.id; + msg->pid = tmp.pid; msg->rcv = tmp.rcv; msg->set_global_address = tmp.set_global_address; msg->set_global_port = tmp.set_global_port; diff --git a/src/core/parser/msg_parser.c b/src/core/parser/msg_parser.c index aff3c0a98..5ac16f1b1 100644 --- a/src/core/parser/msg_parser.c +++ b/src/core/parser/msg_parser.c @@ -169,9 +169,9 @@ char* get_hdr_field(char* const buf, char* const end, struct hdr_field* const hd hdr->body.len=tmp-hdr->body.s; DBG("<%.*s> [%d]; uri=[%.*s]\n", hdr->name.len, ZSW(hdr->name.s), hdr->body.len, to_b->uri.len, ZSW(to_b->uri.s)); - DBG("to body [%.*s], to tag [%.*s]\n", to_b->body.len, - ZSW(to_b->body.s), to_b->tag_value.len, - ZSW(to_b->tag_value.s)); + DBG("to body (%d)[%.*s], to tag (%d)[%.*s]\n", to_b->body.len, + to_b->body.len, ZSW(to_b->body.s), to_b->tag_value.len, + to_b->tag_value.len, ZSW(to_b->tag_value.s)); break; case HDR_CONTENTLENGTH_T: hdr->body.s=tmp; diff --git a/src/core/parser/parse_rr.c b/src/core/parser/parse_rr.c index a089b895f..9557bffc9 100644 --- a/src/core/parser/parse_rr.c +++ b/src/core/parser/parse_rr.c @@ -296,7 +296,8 @@ static inline int do_duplicate_rr(rr_t** _new, rr_t* _r, int _shm) } else { PKG_MEM_ERROR; } - return -2; + ret = -2; + goto error; } memcpy(res, it, sizeof(rr_t)); @@ -313,7 +314,8 @@ static inline int do_duplicate_rr(rr_t** _new, rr_t* _r, int _shm) LM_ERR("Error while duplicating parameters\n"); if (_shm) shm_free(res); else pkg_free(res); - return -3; + ret = -3; + goto error; } xlate_pointers(it, res); @@ -327,6 +329,18 @@ static inline int do_duplicate_rr(rr_t** _new, rr_t* _r, int _shm) it = it->next; } return 0; + +error: + if(*_new != NULL) { + if (_shm) { + shm_free_rr(_new); + } else { + free_rr(_new); + } + *_new = NULL; + } + + return ret; } diff --git a/src/core/ppcfg.c b/src/core/ppcfg.c index 115707aa0..c6b7d2e14 100644 --- a/src/core/ppcfg.c +++ b/src/core/ppcfg.c @@ -80,7 +80,7 @@ int pp_subst_add(char *data) } pp_subst_rules_tail = pr; - LM_INFO("### added subst expression: %s\n", data); + LM_DBG("### added subst expression: [%s]\n", data); return 0; } diff --git a/src/core/socket_info.c b/src/core/socket_info.c index d2e114935..d55f506bc 100644 --- a/src/core/socket_info.c +++ b/src/core/socket_info.c @@ -1070,6 +1070,7 @@ error: req.g.rtgen_family = family;\ } while(0); +#define NETLINK_BUFFER_SIZE 32768 static int get_flags(int family){ struct { @@ -1079,12 +1080,12 @@ static int get_flags(int family){ int rtn = 0; struct nlmsghdr* nlp; struct ifinfomsg *ifi; - char buf[8192]; + char buf[NETLINK_BUFFER_SIZE]; char *p = buf; int nll = 0; int nl_sock = -1; - fill_nl_req(req, RTM_GETLINK, AF_INET); + fill_nl_req(req, RTM_GETLINK, family); if((nl_sock = nl_bound_sock()) < 0) return -1; @@ -1095,6 +1096,10 @@ static int get_flags(int family){ } while(1) { + if ((sizeof(buf) - nll) == 0) { + LM_ERR("netlink buffer overflow in get_flags"); + goto error; + } rtn = recv(nl_sock, p, sizeof(buf) - nll, 0); nlp = (struct nlmsghdr *) p; if(nlp->nlmsg_type == NLMSG_DONE){ @@ -1148,7 +1153,7 @@ static int build_iface_list(void) struct nlmsghdr* nlp; struct ifaddrmsg *ifi; int rtl; - char buf[8192]; + char buf[NETLINK_BUFFER_SIZE]; char *p = buf; int nll = 0; struct rtattr * rtap; @@ -1184,6 +1189,10 @@ static int build_iface_list(void) nll = 0; p = buf; while(1) { + if ((sizeof(buf) - nll) == 0) { + LM_ERR("netlink buffer overflow in build_iface_list"); + goto error; + } rtn = recv(nl_sock, p, sizeof(buf) - nll, 0); LM_DBG("received %d byles \n", rtn); nlp = (struct nlmsghdr *) p; @@ -2142,7 +2151,7 @@ void init_proto_order() /** - * parse '[port:]host[:port]' string to a broken down structure + * parse '[proto:]host[:port]' string to a broken down structure */ int parse_protohostport(str* ins, sr_phostp_t *r) { @@ -2230,7 +2239,7 @@ error_port: } /** - * lookup a local socket by '[port:]host[:port]' string + * lookup a local socket by '[proto:]host[:port]' string */ struct socket_info* lookup_local_socket(str *phostp) { diff --git a/src/core/sr_module.c b/src/core/sr_module.c index 2c76ee2a1..2fc5e8b4b 100644 --- a/src/core/sr_module.c +++ b/src/core/sr_module.c @@ -43,6 +43,8 @@ #include "sr_compat.h" #include "ppcfg.h" #include "async_task.h" +#include "shm_init.h" +#include "daemonize.h" #include #include @@ -109,6 +111,24 @@ unsigned int set_modinit_delay(unsigned int v) return r; } +/* shut down phase for instance - kept in shared memory */ +static int *_ksr_shutdown_phase = NULL; + +int ksr_shutdown_phase_init(void) +{ + if((_ksr_shutdown_phase == NULL) && (shm_initialized())) { + _ksr_shutdown_phase = (int*)shm_mallocxz(sizeof(int)); + } + return 0; +} +/** + * return destroy modules phase state + */ +int ksr_shutdown_phase(void) +{ + return (_ksr_shutdown_phase)?(*_ksr_shutdown_phase):0; +} + /* keep state if server is in destroy modules phase */ static int _sr_destroy_modules_phase = 0; @@ -521,7 +541,7 @@ reload: } /* version control */ if (!version_control(handle, path)) { - exit(-1); + ksr_exit(-1); } /* launch register */ mr = (mod_register_function)dlsym(handle, "mod_register"); @@ -738,6 +758,12 @@ void destroy_modules() struct sr_module* t, *foo; _sr_destroy_modules_phase = 1; + if(_ksr_shutdown_phase!=NULL) { + *_ksr_shutdown_phase = 1; + } + + LM_DBG("starting modules destroy phase\n"); + /* call first destroy function from each module */ t=modules; while(t) { diff --git a/src/core/sr_module.h b/src/core/sr_module.h index 1f833a5e9..3014a88da 100644 --- a/src/core/sr_module.h +++ b/src/core/sr_module.h @@ -544,5 +544,7 @@ int is_rpc_worker(int rank); unsigned int set_modinit_delay(unsigned int v); int destroy_modules_phase(void); +int ksr_shutdown_phase_init(void); +int ksr_shutdown_phase(void); #endif /* sr_module_h */ diff --git a/src/core/str.h b/src/core/str.h index 01b12ecb6..58d7d627f 100644 --- a/src/core/str.h +++ b/src/core/str.h @@ -40,13 +40,16 @@ * need to make a zero-terminated copy of it. * * @section drawbacks Drawbacks - * Note well that the fact that string stored - * using this data structure are not zero terminated makes them a little - * incovenient to use with many standard libc string functions, because these - * usually expect the input to be zero-terminated. In this case you have to - * either make a zero-terminated copy or inject the terminating zero behind - * the actuall string (if possible). Note that injecting a zero terminating - * characters is considered to be dangerous. + * Note well that the fact that a string stored + * using this data structure are not guaranteed to be zero terminated (by + * default they're not) makes them a little incovenient to use with many + * standard libc string functions, because these usually expect the input + * to be zero-terminated. + * In this case you have to either make a zero-terminated copy or inject the + * terminating zero behind the actuall string (if possible). Note that + * injecting a zero terminating characters is considered to be dangerous. + * The functions shm_str_dup() and pkg_str_dup() will always create a + * zero-terminated copy. */ /** @file diff --git a/src/core/tcp_main.c b/src/core/tcp_main.c index f19f75a58..84fec376a 100644 --- a/src/core/tcp_main.c +++ b/src/core/tcp_main.c @@ -95,6 +95,7 @@ #include "tcp_info.h" #include "tcp_options.h" #include "ut.h" +#include "events.h" #include "cfg/cfg_struct.h" #include /* must be included after io_wait.h if SIGIO_RT is used */ @@ -5135,4 +5136,88 @@ void tcp_get_info(struct tcp_gen_info *ti) #endif /* TCP_ASYNC */ } + +/* finds an ws/wss tcpconn & sends on it + * uses the dst members to, proto (ws/wss) and id and tries to send + * returns: number of bytes written (>=0) on success + * <0 on error */ +int wss_send(dest_info_t* dst, const char* buf, unsigned len) +{ + int port; + struct ip_addr ip; + union sockaddr_union* from = NULL; + union sockaddr_union local_addr; + struct tcp_connection *con = NULL; + struct ws_event_info wsev; + sr_event_param_t evp = {0}; + int ret; + + if (unlikely((dst->proto == PROTO_WS +#ifdef USE_TLS + || dst->proto == PROTO_WSS #endif + ) && sr_event_enabled(SREV_TCP_WS_FRAME_OUT))) { + if (unlikely(dst->send_flags.f & SND_F_FORCE_SOCKET + && dst->send_sock)) { + + local_addr = dst->send_sock->su; +#ifdef SO_REUSEPORT + if (cfg_get(tcp, tcp_cfg, reuse_port)) { + LM_DBG("sending to: %s, force_socket=%d, send_sock=%p\n", + su2a(&dst->to,sizeof(struct sockaddr_in)), + (dst->send_flags.f & SND_F_FORCE_SOCKET), + dst->send_sock); + + su_setport(&local_addr, dst->send_sock->port_no); + } + else + su_setport(&local_addr, 0); /* any local port will do */ +#else + su_setport(&local_addr, 0); /* any local port will do */ +#endif + from = &local_addr; + } + + port = su_getport(&dst->to); + if (likely(port)) { + su2ip_addr(&ip, &dst->to); + if(tcp_connection_match==TCPCONN_MATCH_STRICT) { + con = tcpconn_lookup(dst->id, &ip, port, from, + (dst->send_sock)?dst->send_sock->port_no:0, 0); + } else { + con = tcpconn_get(dst->id, &ip, port, from, 0); + } + } + else if (likely(dst->id)) + con = tcpconn_get(dst->id, 0, 0, 0, 0); + else { + LM_CRIT("null_id & to\n"); + goto error; + } + + if (con == NULL) { + LM_WARN("TCP/TLS connection for WebSocket could not be found\n"); + goto error; + } + + memset(&wsev, 0, sizeof(ws_event_info_t)); + wsev.type = SREV_TCP_WS_FRAME_OUT; + wsev.buf = (char*)buf; + wsev.len = len; + wsev.id = con->id; + evp.data = (void *)&wsev; + ret = sr_event_exec(SREV_TCP_WS_FRAME_OUT, &evp); + tcpconn_put(con); + goto done; + } else { + LM_CRIT("used with invalid proto %d\n", dst->proto); + goto error; + } + +done: + return ret; +error: + return -1; +} + +#endif /* USE_TCP */ diff --git a/src/core/tcp_options.h b/src/core/tcp_options.h index f9729544d..61d5828c2 100644 --- a/src/core/tcp_options.h +++ b/src/core/tcp_options.h @@ -157,6 +157,7 @@ void tcp_options_get(struct cfg_group_tcp* t); #ifdef USE_TCP int tcp_set_clone_rcvbuf(int v); +int tcp_get_clone_rcvbuf(void); #endif /* USE_TCP */ #endif /* tcp_options_h */ diff --git a/src/core/tcp_read.c b/src/core/tcp_read.c index 655db7da7..c2d3fa9f4 100644 --- a/src/core/tcp_read.c +++ b/src/core/tcp_read.c @@ -52,6 +52,7 @@ #include "ut.h" #include "trim.h" #include "pt.h" +#include "daemonize.h" #include "cfg/cfg_struct.h" #ifdef CORE_TLS #include "tls/tls_server.h" @@ -109,6 +110,11 @@ int tcp_set_clone_rcvbuf(int v) return r; } +int tcp_get_clone_rcvbuf(void) +{ + return tcp_clone_rcvbuf; +} + #ifdef READ_HTTP11 static inline char *strfindcasestrz(str *haystack, char *needlez) { @@ -311,12 +317,14 @@ again: } }else if (unlikely((bytes_read==0) || (*flags & RD_CONN_FORCE_EOF))){ + LM_DBG("EOF on connection %p (state: %u, flags: %x) - FD %d," + " bytes %d, rd-flags %x ([%s]:%u -> [%s]:%u)", + c, c->state, c->flags, fd, bytes_read, *flags, + ip_addr2a(&c->rcv.src_ip), c->rcv.src_port, + ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port); c->state=S_CONN_EOF; *flags|=RD_CONN_EOF; tcp_emit_closed_event(c, TCP_CLOSED_EOF); - LM_DBG("EOF on %p, FD %d ([%s]:%u ->", c, fd, - ip_addr2a(&c->rcv.src_ip), c->rcv.src_port); - LM_DBG("-> [%s]:%u)\n", ip_addr2a(&c->rcv.dst_ip), c->rcv.dst_port); }else{ if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT)){ TCP_STATS_ESTABLISHED(c->state); @@ -2022,7 +2030,7 @@ void tcp_receive_loop(int unix_sock) error: destroy_io_wait(&io_w); LM_CRIT("exiting..."); - exit(-1); + ksr_exit(-1); } diff --git a/src/core/tcp_server.h b/src/core/tcp_server.h index 0566c500d..dac25bb15 100644 --- a/src/core/tcp_server.h +++ b/src/core/tcp_server.h @@ -13,8 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -33,7 +33,7 @@ int tcp_send(struct dest_info* dst, union sockaddr_union* from, int tcpconn_add_alias(int id, int port, int proto); - +int wss_send(dest_info_t* dst, const char* buf, unsigned len); #endif diff --git a/src/core/ut.h b/src/core/ut.h index 56c1f9e15..936697b60 100644 --- a/src/core/ut.h +++ b/src/core/ut.h @@ -745,9 +745,33 @@ static inline int strz2sint(char* _s, int* _r) return 0; } +/** + * duplicate str structure and content in a single shm block + */ +static inline str* shm_str_dup_block(const str* src) +{ + str *dst; + + if(src==NULL) { + return NULL; + } + dst = (str*)shm_malloc(sizeof(str) + src->len + 1); + if (dst == NULL) { + SHM_MEM_ERROR; + return NULL; + } + memset(dst, 0, sizeof(str) + src->len + 1); + + dst->s = (char*)dst + sizeof(str); + dst->len = src->len; + memcpy(dst->s, src->s, src->len); + + return dst; +} /** * \brief Make a copy of a str structure to a str using shm_malloc + * The copy will be zero-terminated * \param dst destination * \param src source * \return 0 on success, -1 on failure @@ -775,7 +799,7 @@ static inline int shm_str_dup(str* dst, const str* src) dst->len = src->len; } - dst->s = (char*)shm_malloc(dst->len); + dst->s = (char*)shm_malloc(dst->len+1); if (dst->s == NULL) { SHM_MEM_ERROR; return -1; @@ -788,6 +812,7 @@ static inline int shm_str_dup(str* dst, const str* src) } memcpy(dst->s, src->s, dst->len); + dst->s[dst->len] = 0; return 0; } @@ -848,6 +873,7 @@ static inline char* shm_str2char_dup(str *src) /** * \brief Make a copy of a str structure using pkg_malloc + * The copy will be zero-terminated * \param dst destination * \param src source * \return 0 on success, -1 on failure @@ -875,7 +901,7 @@ static inline int pkg_str_dup(str* dst, const str* src) dst->len = src->len; } - dst->s = (char*)pkg_malloc(dst->len); + dst->s = (char*)pkg_malloc(dst->len+1); if (dst->s == NULL) { PKG_MEM_ERROR; return -1; @@ -888,6 +914,7 @@ static inline int pkg_str_dup(str* dst, const str* src) } memcpy(dst->s, src->s, dst->len); + dst->s[dst->len] = 0; return 0; } diff --git a/src/core/xavp.c b/src/core/xavp.c index efa7c32cb..e27c07bd6 100644 --- a/src/core/xavp.c +++ b/src/core/xavp.c @@ -454,6 +454,8 @@ static int xavp_rm_internal(str *name, sr_xavp_t **head, int idx) if(idx>=0) return 1; count++; + } else { + prv = foo; } n++; } else { @@ -1851,6 +1853,8 @@ static int xavi_rm_internal(str *name, sr_xavp_t **head, int idx) if(idx>=0) return 1; count++; + } else { + prv = foo; } n++; } else { diff --git a/src/lib/srdb1/db.c b/src/lib/srdb1/db.c index d33c9390c..54b66d330 100644 --- a/src/lib/srdb1/db.c +++ b/src/lib/srdb1/db.c @@ -477,8 +477,12 @@ int db_check_table_version(db_func_t* dbf, db1_con_t* dbh, const str* table, */ int db_use_table(db1_con_t* _h, const str* _t) { - if (!_h || !_t || !_t->s) { - LM_ERR("invalid parameter value\n"); + if (!_h) { + LM_ERR("invalid connection parameter\n"); + return -1; + } + if (!_t || !_t->s) { + LM_ERR("invalid table parameter value\n"); return -1; } diff --git a/src/lib/srdb1/schema/carrierfailureroute.xml b/src/lib/srdb1/schema/carrierfailureroute.xml index 2de707c59..58a05e786 100644 --- a/src/lib/srdb1/schema/carrierfailureroute.xml +++ b/src/lib/srdb1/schema/carrierfailureroute.xml @@ -59,7 +59,7 @@ string &user_len; - Name of column contains the the scan prefixes. Scan prefixes define the matching + Name of column contains the scan prefixes. Scan prefixes define the matching portion of a phone number, e.g. we have the scan prefixes 49721 and 49, the called number is 49721913740, it matches 49721, because the longest match is taken. If no prefix matches, the number is not failure routed. To prevent this, an empty prefix value of diff --git a/src/main.c b/src/main.c index e57bfa40f..37181cc64 100644 --- a/src/main.c +++ b/src/main.c @@ -164,6 +164,10 @@ Options:\n\ disable with no or off\n\ --alias=val Add an alias, the value has to be '[proto:]hostname[:port]'\n\ (like for 'alias' global parameter)\n\ + --atexit=val Control atexit callbacks execution from external libraries\n\ + which may access destroyed shm memory causing crash on shutdown.\n\ + Can be y[es] or 1 to enable atexit callbacks, n[o] or 0 to disable,\n\ + default is yes.\n\ -A define Add config pre-processor define (e.g., -A WITH_AUTH,\n\ -A 'FLT_ACC=1', -A 'DEFVAL=\"str-val\"')\n\ -b nr Maximum receive buffer size which will not be exceeded by\n\ @@ -533,6 +537,8 @@ char *sr_memmng_shm = NULL; static int *_sr_instance_started = NULL; +int ksr_atexit_mode = 1; + /** * return 1 if all child processes were forked * - note: they might still be in init phase (i.e., child init) @@ -735,7 +741,7 @@ void handle_sigs(void) LM_NOTICE("Thank you for flying " NAME "!!!\n"); /* shutdown/kill all the children */ shutdown_children(SIGTERM, 1); - exit(0); + ksr_exit(0); break; case SIGUSR1: @@ -805,9 +811,9 @@ void handle_sigs(void) /* exit */ shutdown_children(SIGTERM, 1); if (WIFSIGNALED(chld_status)) { - exit(1); + ksr_exit(1); } else { - exit(0); + ksr_exit(0); } break; @@ -1933,6 +1939,7 @@ int main(int argc, char** argv) {"modparam", required_argument, 0, KARGOPTVAL + 6}, {"log-engine", required_argument, 0, KARGOPTVAL + 7}, {"debug", required_argument, 0, KARGOPTVAL + 8}, + {"atexit", required_argument, 0, KARGOPTVAL + 10}, {0, 0, 0, 0 } }; @@ -2002,6 +2009,16 @@ int main(int argc, char** argv) goto error; } break; + case KARGOPTVAL+10: + if(optarg[0]=='y' || optarg[0]=='1') { + ksr_atexit_mode = 1; + } else if(optarg[0]=='n' || optarg[0]=='0') { + ksr_atexit_mode = 0; + } else { + LM_ERR("bad atexit value: %s\n", optarg); + goto error; + } + break; default: if (c == 'h' || (optarg && strcmp(optarg, "-h") == 0)) { @@ -2164,6 +2181,7 @@ int main(int argc, char** argv) case KARGOPTVAL+6: case KARGOPTVAL+7: case KARGOPTVAL+8: + case KARGOPTVAL+10: break; /* long options */ @@ -2541,6 +2559,8 @@ try_again: if (ksr_route_locks_set_init()<0) goto error; + ksr_shutdown_phase_init(); + /* init lookup for core event routes */ sr_core_ert_init(); @@ -2864,7 +2884,7 @@ try_again: strerror(errno), errno); } /* else terminate process */ - return ret; + ksr_exit(ret); error: /*kill everything*/ @@ -2874,7 +2894,7 @@ error: fprintf(stderr, "error sending exit status: %s [%d]\n", strerror(errno), errno); } - return -1; + ksr_exit(-1); } diff --git a/src/modules/alias_db/alias_db.c b/src/modules/alias_db/alias_db.c index 401a35d6c..a6ab23ebc 100644 --- a/src/modules/alias_db/alias_db.c +++ b/src/modules/alias_db/alias_db.c @@ -20,9 +20,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: - * -------- - * 2004-09-01: first version (ramona) */ @@ -43,6 +40,8 @@ MODULE_VERSION +/* clang-format off */ + /* Module destroy function prototype */ static void destroy(void); @@ -122,23 +121,23 @@ struct module_exports exports = { child_init, /* per-child·init·function */ destroy /* destroy function */ }; +/* clang-format on */ -static int alias_flags_fixup(void** param) +static int alias_flags_fixup(void **param) { char *c; unsigned int flags; - c = (char*)*param; + c = (char *)*param; flags = 0; if(alias_db_use_domain) { flags |= ALIAS_DOMAIN_FLAG; } - while (*c) { - switch (*c) - { + while(*c) { + switch(*c) { case 'd': case 'D': flags &= ~ALIAS_DOMAIN_FLAG; @@ -152,61 +151,58 @@ static int alias_flags_fixup(void** param) flags |= ALIAS_DOMAIN_FLAG; break; default: - LM_ERR("unsupported flag '%c'\n",*c); + LM_ERR("unsupported flag '%c'\n", *c); return -1; } c++; } pkg_free(*param); - *param = (void*)(unsigned long)flags; + *param = (void *)(unsigned long)flags; return 0; } -static int lookup_fixup(void** param, int param_no) +static int lookup_fixup(void **param, int param_no) { - if (param_no==1) - { + if(param_no == 1) { /* string or pseudo-var - table name */ return fixup_spve_null(param, 1); - } else if (param_no==2) { + } else if(param_no == 2) { /* string - flags ? */ return alias_flags_fixup(param); } else { - LM_CRIT(" invalid number of params %d \n",param_no); + LM_CRIT(" invalid number of params %d \n", param_no); return -1; } } -static int find_fixup(void** param, int param_no) +static int find_fixup(void **param, int param_no) { pv_spec_t *sp; - if (param_no==1) - { + if(param_no == 1) { /* string or pseudo-var - table name */ return fixup_spve_null(param, 1); - } else if(param_no==2) { + } else if(param_no == 2) { /* pseudo-var - source URI */ return fixup_pvar_null(param, 1); - } else if(param_no==3) { + } else if(param_no == 3) { /* pvar (AVP or VAR) - destination URI */ - if (fixup_pvar_null(param, 1)) + if(fixup_pvar_null(param, 1)) return E_CFG; - sp = (pv_spec_t*)*param; - if (sp->type!=PVT_AVP && sp->type!=PVT_SCRIPTVAR) - { + sp = (pv_spec_t *)*param; + if(sp->type != PVT_AVP && sp->type != PVT_SCRIPTVAR) { LM_ERR("PV type %d (param 3) cannot be written\n", sp->type); pv_spec_free(sp); return E_CFG; } return 0; - } else if (param_no==4) { + } else if(param_no == 4) { /* string - flags ? */ return alias_flags_fixup(param); } else { - LM_CRIT(" invalid number of params %d \n",param_no); + LM_CRIT(" invalid number of params %d \n", param_no); return -1; } } @@ -217,17 +213,15 @@ static int find_fixup(void** param, int param_no) */ static int child_init(int rank) { - if (rank==PROC_INIT || rank==PROC_MAIN || rank==PROC_TCP_MAIN) + if(rank == PROC_INIT || rank == PROC_MAIN || rank == PROC_TCP_MAIN) return 0; /* do nothing for the main process */ db_handle = adbf.init(&db_url); - if (!db_handle) - { + if(!db_handle) { LM_ERR("unable to connect database\n"); return -1; } return 0; - } @@ -237,15 +231,13 @@ static int child_init(int rank) static int mod_init(void) { /* Find a database module */ - if (db_bind_mod(&db_url, &adbf)) - { + if(db_bind_mod(&db_url, &adbf)) { LM_ERR("unable to bind database module\n"); return -1; } - if (!DB_CAPABILITY(adbf, DB_CAP_QUERY)) - { + if(!DB_CAPABILITY(adbf, DB_CAP_QUERY)) { LM_CRIT("database modules does not " - "provide all functions needed by alias_db module\n"); + "provide all functions needed by alias_db module\n"); return -1; } @@ -258,13 +250,13 @@ static int mod_init(void) */ static void destroy(void) { - if (db_handle) { + if(db_handle) { adbf.close(db_handle); db_handle = 0; } } -static int w_alias_db_lookup1(struct sip_msg* _msg, char* _table, char* p2) +static int w_alias_db_lookup1(struct sip_msg *_msg, char *_table, char *p2) { str table_s; unsigned long flags; @@ -274,7 +266,8 @@ static int w_alias_db_lookup1(struct sip_msg* _msg, char* _table, char* p2) flags |= ALIAS_DOMAIN_FLAG; } - if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) { + if(_table == NULL + || fixup_get_svalue(_msg, (gparam_p)_table, &table_s) != 0) { LM_ERR("invalid table parameter\n"); return -1; } @@ -282,20 +275,21 @@ static int w_alias_db_lookup1(struct sip_msg* _msg, char* _table, char* p2) return alias_db_lookup_ex(_msg, table_s, flags); } -static int w_alias_db_lookup2(struct sip_msg* _msg, char* _table, char* flags) +static int w_alias_db_lookup2(struct sip_msg *_msg, char *_table, char *flags) { str table_s; - if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) { + if(_table == NULL + || fixup_get_svalue(_msg, (gparam_p)_table, &table_s) != 0) { LM_ERR("invalid table parameter\n"); - return -1; + return -1; } return alias_db_lookup_ex(_msg, table_s, (unsigned long)flags); } -static int w_alias_db_find3(struct sip_msg* _msg, char* _table, char* _in, - char* _out) +static int w_alias_db_find3( + struct sip_msg *_msg, char *_table, char *_in, char *_out) { str table_s; unsigned long flags; @@ -305,20 +299,22 @@ static int w_alias_db_find3(struct sip_msg* _msg, char* _table, char* _in, flags |= ALIAS_DOMAIN_FLAG; } - if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) { + if(_table == NULL + || fixup_get_svalue(_msg, (gparam_p)_table, &table_s) != 0) { LM_ERR("invalid table parameter\n"); return -1; } - return alias_db_find(_msg, table_s, _in, _out, (char*)flags); + return alias_db_find(_msg, table_s, _in, _out, (char *)flags); } -static int w_alias_db_find4(struct sip_msg* _msg, char* _table, char* _in, - char* _out, char* flags) +static int w_alias_db_find4( + struct sip_msg *_msg, char *_table, char *_in, char *_out, char *flags) { str table_s; - if(_table==NULL || fixup_get_svalue(_msg, (gparam_p)_table, &table_s)!=0) { + if(_table == NULL + || fixup_get_svalue(_msg, (gparam_p)_table, &table_s) != 0) { LM_ERR("invalid table parameter\n"); return -1; } @@ -328,8 +324,9 @@ static int w_alias_db_find4(struct sip_msg* _msg, char* _table, char* _in, int bind_alias_db(struct alias_db_binds *pxb) { - if (pxb == NULL) { - LM_WARN("bind_alias_db: Cannot load alias_db API into a NULL pointer\n"); + if(pxb == NULL) { + LM_WARN("bind_alias_db: Cannot load alias_db API into a NULL " + "pointer\n"); return -1; } @@ -342,7 +339,7 @@ int bind_alias_db(struct alias_db_binds *pxb) /** * */ -static int ki_alias_db_lookup(sip_msg_t* msg, str* stable) +static int ki_alias_db_lookup(sip_msg_t *msg, str *stable) { unsigned long flags; @@ -357,7 +354,7 @@ static int ki_alias_db_lookup(sip_msg_t* msg, str* stable) /** * */ -static int ki_alias_db_lookup_ex(sip_msg_t* msg, str* stable, str* sflags) +static int ki_alias_db_lookup_ex(sip_msg_t *msg, str *stable, str *sflags) { unsigned long flags; int i; @@ -366,9 +363,8 @@ static int ki_alias_db_lookup_ex(sip_msg_t* msg, str* stable, str* sflags) if(alias_db_use_domain) { flags |= ALIAS_DOMAIN_FLAG; } - for(i=0; ilen; i++) { - switch (sflags->s[i]) - { + for(i = 0; i < sflags->len; i++) { + switch(sflags->s[i]) { case 'd': case 'D': flags &= ~ALIAS_DOMAIN_FLAG; diff --git a/src/modules/alias_db/alias_db.h b/src/modules/alias_db/alias_db.h index 0e0cabbb5..94c57538a 100644 --- a/src/modules/alias_db/alias_db.h +++ b/src/modules/alias_db/alias_db.h @@ -1,6 +1,4 @@ -/* - * $Id$ - * +/* * ALIAS_DB Module * * Copyright (C) 2004 Voice Sistem @@ -17,13 +15,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * History: - * -------- - * 2004-09-01: first version (ramona) */ @@ -36,13 +31,13 @@ /* Module parameters variables */ -extern str user_column; /* 'username' column name */ -extern str domain_column; /* 'domain' column name */ -extern str alias_user_column; /* 'alias_username' column name */ -extern str alias_domain_column; /* 'alias_domain' column name */ +extern str user_column; /* 'username' column name */ +extern str domain_column; /* 'domain' column name */ +extern str alias_user_column; /* 'alias_username' column name */ +extern str alias_domain_column; /* 'alias_domain' column name */ extern str domain_prefix; -extern int ald_append_branches; /* append branches after an alias lookup */ +extern int ald_append_branches; /* append branches after an alias lookup */ -extern db1_con_t* db_handle; /* Database connection handle */ +extern db1_con_t *db_handle; /* Database connection handle */ #endif /* _ALIAS_DB_H_ */ diff --git a/src/modules/alias_db/alookup.c b/src/modules/alias_db/alookup.c index 28dd91699..62dbc14ca 100644 --- a/src/modules/alias_db/alookup.c +++ b/src/modules/alias_db/alookup.c @@ -1,6 +1,4 @@ -/* - * $Id$ - * +/* * ALIAS_DB Module * * Copyright (C) 2004 Voice Sistem SRL @@ -17,13 +15,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * History: - * -------- - * 2004-09-01: first version (ramona) */ #include @@ -41,32 +36,30 @@ #include "alias_db.h" #include "alookup.h" -#define MAX_USERURI_SIZE 256 +#define MAX_USERURI_SIZE 256 -extern db_func_t adbf; /* DB functions */ +extern db_func_t adbf; /* DB functions */ extern int alias_db_use_domain; char useruri_buf[MAX_USERURI_SIZE]; -typedef int (*set_alias_f)(struct sip_msg* _msg, str *alias, int no, void *p); +typedef int (*set_alias_f)(struct sip_msg *_msg, str *alias, int no, void *p); /** * */ -static int alias_db_query(struct sip_msg* _msg, str table, - struct sip_uri *puri, unsigned long flags, - set_alias_f set_alias, void *param) +static int alias_db_query(struct sip_msg *_msg, str table, struct sip_uri *puri, + unsigned long flags, set_alias_f set_alias, void *param) { str user_s; db_key_t db_keys[2]; db_val_t db_vals[2]; db_key_t db_cols[2]; - db1_res_t* db_res = NULL; + db1_res_t *db_res = NULL; int i; - if (flags&ALIAS_REVERSE_FLAG) - { + if(flags & ALIAS_REVERSE_FLAG) { /* revert lookup: user->alias */ db_keys[0] = &user_column; db_keys[1] = &domain_column; @@ -85,101 +78,96 @@ static int alias_db_query(struct sip_msg* _msg, str table, db_vals[0].val.str_val.s = puri->user.s; db_vals[0].val.str_val.len = puri->user.len; - if ( flags&ALIAS_DOMAIN_FLAG ) { + if(flags & ALIAS_DOMAIN_FLAG) { db_vals[1].type = DB1_STR; db_vals[1].nul = 0; db_vals[1].val.str_val.s = puri->host.s; db_vals[1].val.str_val.len = puri->host.len; - if (domain_prefix.s && domain_prefix.len>0 - && domain_prefix.lenhost.len - && strncasecmp(puri->host.s,domain_prefix.s, - domain_prefix.len)==0) - { - db_vals[1].val.str_val.s += domain_prefix.len; + if(domain_prefix.s && domain_prefix.len > 0 + && domain_prefix.len < puri->host.len + && strncasecmp(puri->host.s, domain_prefix.s, domain_prefix.len) + == 0) { + db_vals[1].val.str_val.s += domain_prefix.len; db_vals[1].val.str_val.len -= domain_prefix.len; } } adbf.use_table(db_handle, &table); - if(adbf.query( db_handle, db_keys, NULL, db_vals, db_cols, - (flags&ALIAS_DOMAIN_FLAG)?2:1 /*no keys*/, 2 /*no cols*/, - NULL, &db_res)!=0 || db_res==NULL) - { + if(adbf.query(db_handle, db_keys, NULL, db_vals, db_cols, + (flags & ALIAS_DOMAIN_FLAG) ? 2 : 1 /*no keys*/, 2 /*no cols*/, + NULL, &db_res) + != 0 + || db_res == NULL) { LM_ERR("failed to query database\n"); goto err_server; } - if (RES_ROW_N(db_res)<=0 || RES_ROWS(db_res)[0].values[0].nul != 0) - { + if(RES_ROW_N(db_res) <= 0 || RES_ROWS(db_res)[0].values[0].nul != 0) { LM_DBG("no alias found for R-URI\n"); goto err_server; } memcpy(useruri_buf, "sip:", 4); - for(i=0; iparsed_uri, flags, - set_alias_to_ruri, NULL); + return alias_db_query( + _msg, table, &_msg->parsed_uri, flags, set_alias_to_ruri, NULL); } -int alias_db_lookup(struct sip_msg* _msg, str table) +int alias_db_lookup(struct sip_msg *_msg, str table) { unsigned long flags = 0; - if(alias_db_use_domain) flags = ALIAS_DOMAIN_FLAG; + if(alias_db_use_domain) + flags = ALIAS_DOMAIN_FLAG; return alias_db_lookup_ex(_msg, table, flags); } -int set_alias_to_pvar(struct sip_msg* _msg, str *alias, int no, void *p) +int set_alias_to_pvar(struct sip_msg *_msg, str *alias, int no, void *p) { pv_value_t val; - pv_spec_t *pvs=(pv_spec_t*)p; + pv_spec_t *pvs = (pv_spec_t *)p; if(no && !ald_append_branches) return 0; @@ -253,8 +239,7 @@ int set_alias_to_pvar(struct sip_msg* _msg, str *alias, int no, void *p) val.ri = 0; val.rs = *alias; - if(pv_set_spec_value(_msg, pvs, (int)(no?EQ_T:ASSIGN_T), &val)<0) - { + if(pv_set_spec_value(_msg, pvs, (int)(no ? EQ_T : ASSIGN_T), &val) < 0) { LM_ERR("setting PV AVP failed\n"); return -1; } @@ -262,30 +247,26 @@ int set_alias_to_pvar(struct sip_msg* _msg, str *alias, int no, void *p) } -int alias_db_find(struct sip_msg* _msg, str table, char* _in, char* _out, - char* flags) +int alias_db_find( + struct sip_msg *_msg, str table, char *_in, char *_out, char *flags) { pv_value_t val; struct sip_uri puri; /* get the input value */ - if (pv_get_spec_value(_msg, (pv_spec_t*)_in, &val)!=0) - { + if(pv_get_spec_value(_msg, (pv_spec_t *)_in, &val) != 0) { LM_ERR("failed to get PV value\n"); return -1; } - if ( (val.flags&PV_VAL_STR)==0 ) - { + if((val.flags & PV_VAL_STR) == 0) { LM_ERR("PV vals is not string\n"); return -1; } - if (parse_uri(val.rs.s, val.rs.len, &puri)<0) - { - LM_ERR("failed to parse uri %.*s\n",val.rs.len,val.rs.s); + if(parse_uri(val.rs.s, val.rs.len, &puri) < 0) { + LM_ERR("failed to parse uri %.*s\n", val.rs.len, val.rs.s); return -1; } - return alias_db_query(_msg, table, &puri, (unsigned long)flags, - set_alias_to_pvar, _out); + return alias_db_query( + _msg, table, &puri, (unsigned long)flags, set_alias_to_pvar, _out); } - diff --git a/src/modules/alias_db/alookup.h b/src/modules/alias_db/alookup.h index 70cf9eb44..2f8262dfc 100644 --- a/src/modules/alias_db/alookup.h +++ b/src/modules/alias_db/alookup.h @@ -1,6 +1,4 @@ -/* - * $Id$ - * +/* * ALIAS_DB Module * * Copyright (C) 2004 Voice Sistem SRL @@ -17,13 +15,10 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * - * History: - * -------- - * 2004-09-01: first version (ramona) */ @@ -32,12 +27,12 @@ #include "../../core/parser/msg_parser.h" -#define ALIAS_REVERSE_FLAG (1<<0) -#define ALIAS_DOMAIN_FLAG (1<<1) +#define ALIAS_REVERSE_FLAG (1 << 0) +#define ALIAS_DOMAIN_FLAG (1 << 1) -int alias_db_lookup(struct sip_msg* _msg, str _table); -int alias_db_lookup_ex(struct sip_msg* _msg, str _table, unsigned long flags); -int alias_db_find(struct sip_msg* _msg, str _table, char* _in, char* _out, - char* flags); +int alias_db_lookup(struct sip_msg *_msg, str _table); +int alias_db_lookup_ex(struct sip_msg *_msg, str _table, unsigned long flags); +int alias_db_find( + struct sip_msg *_msg, str _table, char *_in, char *_out, char *flags); #endif /* _ALOOKUP_H_ */ diff --git a/src/modules/alias_db/api.h b/src/modules/alias_db/api.h index 1f7767730..d9dbb9a26 100644 --- a/src/modules/alias_db/api.h +++ b/src/modules/alias_db/api.h @@ -1,26 +1,54 @@ +/* + * ALIAS_DB Module + * + * Copyright (C) 2011 Crocodile RCS + * + * This file is part of a module for Kamailio, a free SIP server. + * + * 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 + * + * 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. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + */ + #ifndef ALIASDB_API_H #define ALIASDB_API_H + #include "../../core/str.h" -typedef int (*alias_db_lookup_t)(sip_msg_t*, str table); -typedef int (*alias_db_lookup_ex_t)(sip_msg_t*, str table, unsigned long flags); -typedef int (*alias_db_find_t)(sip_msg_t*, str table, char* _in, char* _out, char *flags); +typedef int (*alias_db_lookup_t)(sip_msg_t *, str table); +typedef int (*alias_db_lookup_ex_t)( + sip_msg_t *, str table, unsigned long flags); +typedef int (*alias_db_find_t)( + sip_msg_t *, str table, char *_in, char *_out, char *flags); +/* clang-format off */ typedef struct alias_db_binds { alias_db_lookup_t alias_db_lookup; alias_db_lookup_ex_t alias_db_lookup_ex; alias_db_find_t alias_db_find; } alias_db_api_t; +/* clang-format on */ -typedef int (*bind_alias_db_f)(alias_db_api_t*); +typedef int (*bind_alias_db_f)(alias_db_api_t *); -int bind_alias_db(struct alias_db_binds*); +int bind_alias_db(struct alias_db_binds *); inline static int alias_db_load_api(alias_db_api_t *pxb) { bind_alias_db_f bind_alias_db_exports; - if (!(bind_alias_db_exports = (bind_alias_db_f)find_export("bind_alias_db", 1, 0))) - { + if(!(bind_alias_db_exports = + (bind_alias_db_f)find_export("bind_alias_db", 1, 0))) { LM_ERR("Failed to import bind_alias_db\n"); return -1; } diff --git a/src/modules/app_jsdt/duk_config.h b/src/modules/app_jsdt/duk_config.h index 130168a99..c7cebdec5 100644 --- a/src/modules/app_jsdt/duk_config.h +++ b/src/modules/app_jsdt/duk_config.h @@ -1,9 +1,9 @@ /* * duk_config.h configuration header generated by genconfig.py. * - * Git commit: 6001888049cb42656f8649db020e804bcdeca6a7 - * Git describe: v2.5.0 - * Git branch: master + * Git commit: fffa346eff06a8764b02c31d4336f63a773a95c3 + * Git describe: v2.6.0 + * Git branch: v2-maintenance * * Supported platforms: * - Mac OSX, iPhone, Darwin @@ -964,9 +964,7 @@ #elif defined(DUK_F_PPC64) /* --- PowerPC 64-bit --- */ #define DUK_USE_ARCH_STRING "ppc64" -#if !defined(DUK_USE_BYTEORDER) -#define DUK_USE_BYTEORDER 3 -#endif +/* No forced byteorder (both little and big endian are possible). */ #undef DUK_USE_PACKED_TVAL #define DUK_F_PACKED_TVAL_PROVIDED #elif defined(DUK_F_SPARC32) @@ -2917,6 +2915,8 @@ typedef struct duk_hthread duk_context; #define DUK_USE_CACHE_CATCHER #define DUK_USE_CALLSTACK_LIMIT 10000 #define DUK_USE_CBOR_BUILTIN +#define DUK_USE_CBOR_DEC_RECLIMIT 1000 +#define DUK_USE_CBOR_ENC_RECLIMIT 1000 #define DUK_USE_CBOR_SUPPORT #define DUK_USE_COMPILER_RECLIMIT 2500 #define DUK_USE_COROUTINE_SUPPORT diff --git a/src/modules/app_jsdt/duktape.c b/src/modules/app_jsdt/duktape.c index 366883c53..cd2f79190 100644 --- a/src/modules/app_jsdt/duktape.c +++ b/src/modules/app_jsdt/duktape.c @@ -1,8 +1,8 @@ /* - * Single source autogenerated distributable for Duktape 2.5.0. + * Single source autogenerated distributable for Duktape 2.6.0. * - * Git commit 6001888049cb42656f8649db020e804bcdeca6a7 (v2.5.0). - * Git branch master. + * Git commit fffa346eff06a8764b02c31d4336f63a773a95c3 (v2.6.0). + * Git branch v2-maintenance. * * See Duktape AUTHORS.rst and LICENSE.txt for copyright and * licensing information. @@ -525,7 +525,8 @@ typedef union duk_double_union duk_double_union; } while (0) #define DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL(u) do { \ - if (DUK__DBLUNION_IS_NAN_NOTFULL((u))) { \ + /* Check must be full. */ \ + if (DUK__DBLUNION_IS_NAN_FULL((u))) { \ DUK__DBLUNION_SET_NAN_NOTFULL((u)); \ } \ } while (0) @@ -537,12 +538,11 @@ typedef union duk_double_union duk_double_union; */ #if defined(DUK_USE_PACKED_TVAL) -#if defined(DUK_USE_FULL_TVAL) #define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_FULL((u)) #define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_FULL((u)) #define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_FULL((u)) #define DUK_DBLUNION_SET_NAN(d) DUK__DBLUNION_SET_NAN_FULL((d)) -#else +#if 0 #define DUK_DBLUNION_NORMALIZE_NAN_CHECK(u) DUK__DBLUNION_NORMALIZE_NAN_CHECK_NOTFULL((u)) #define DUK_DBLUNION_IS_NAN(u) DUK__DBLUNION_IS_NAN_NOTFULL((u)) #define DUK_DBLUNION_IS_NORMALIZED_NAN(u) DUK__DBLUNION_IS_NORMALIZED_NAN_NOTFULL((u)) @@ -3141,10 +3141,12 @@ DUK_INTERNAL_DECL duk_bool_t duk_float_equals(duk_float_t x, duk_float_t y); /* JSON */ #define DUK_STR_FMT_PTR "%p" #define DUK_STR_FMT_INVALID_JSON "invalid json (at offset %ld)" -#define DUK_STR_JSONDEC_RECLIMIT "json decode recursion limit" -#define DUK_STR_JSONENC_RECLIMIT "json encode recursion limit" #define DUK_STR_CYCLIC_INPUT "cyclic input" +/* Generic codec */ +#define DUK_STR_DEC_RECLIMIT "decode recursion limit" +#define DUK_STR_ENC_RECLIMIT "encode recursion limit" + /* Object property access */ #define DUK_STR_INVALID_BASE "invalid base value" #define DUK_STR_STRICT_CALLER_READ "cannot read strict 'caller'" @@ -11289,14 +11291,14 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[4281] = { 137,194,70,46,142,68,165,19,236,1,64,174,187,161,95,37,134,204,23,225,35, 23,71,34,82,137,246,128,160,89,93,208,167,147,195,201,194,70,46,142,68,165, 19,238,1,64,182,187,161,71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70, -72,115,96,0,0,0,0,0,2,234,32,91,60,165,195,201,194,8,134,149,216,162,0,192, -41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176,195, -192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20,1, -119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219,36, -98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0,0, -83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1,102, -8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48,20, -28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179, +72,115,96,0,0,0,0,0,15,106,32,91,60,165,195,201,194,8,134,149,216,162,0, +192,41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176, +195,192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20, +1,119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219, +36,98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0, +0,83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1, +102,8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48, +20,28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179, 216,162,152,192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235, 81,76,104,73,137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168, 166,56,36,196,159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149, @@ -11489,7 +11491,7 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[4281] = { 137,194,70,46,142,68,165,19,236,1,64,174,187,161,95,37,134,204,23,225,35, 23,71,34,82,137,246,128,160,89,93,208,167,147,195,201,194,70,46,142,68,165, 19,238,1,64,182,187,161,71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70, -72,115,96,32,106,2,128,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0, +72,115,96,32,106,15,0,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0, 192,41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176, 195,192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20, 1,119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219, @@ -11689,14 +11691,14 @@ DUK_INTERNAL const duk_uint8_t duk_builtins_data[4281] = { 137,194,70,46,142,68,165,19,236,1,64,174,187,161,95,37,134,204,23,225,35, 23,71,34,82,137,246,128,160,89,93,208,167,147,195,201,194,70,46,142,68,165, 19,238,1,64,182,187,161,71,105,20,19,177,139,163,145,41,68,16,7,6,15,82,70, -72,115,96,0,2,234,32,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0,192, -41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176,195, -192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20,1, -119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219,36, -98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0,0, -83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1,102, -8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48,20, -28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179, +72,115,96,0,15,106,32,0,0,0,0,91,60,165,195,201,194,8,134,149,216,162,0, +192,41,225,8,2,48,177,36,1,149,13,196,15,0,200,209,97,199,128,99,32,176, +195,192,113,57,143,0,167,133,32,230,80,28,202,139,175,238,2,48,189,192,20, +1,119,80,87,193,186,129,89,56,72,197,209,200,193,185,35,23,71,109,13,219, +36,98,232,237,156,13,26,208,211,14,102,19,87,137,91,95,128,0,10,96,24,92,0, +0,83,2,53,56,0,0,165,3,28,204,160,160,226,100,226,200,211,76,241,240,0,1, +102,8,22,75,64,137,73,20,230,105,133,7,19,39,22,70,154,103,143,128,0,11,48, +20,28,76,156,113,75,34,78,62,0,0,45,3,103,31,0,0,22,65,44,57,137,62,33,179, 216,162,152,192,131,18,124,162,27,61,138,41,108,32,196,159,16,217,232,235, 81,76,104,73,137,62,81,13,158,142,181,20,184,16,98,79,136,108,244,244,168, 166,56,36,196,159,40,134,207,79,74,138,93,10,49,39,194,173,192,158,158,149, @@ -16443,6 +16445,7 @@ struct duk_internal_thread_state { duk_ljstate lj; duk_bool_t creating_error; duk_hthread *curr_thread; + duk_uint8_t thread_state; duk_int_t call_recursion_depth; }; @@ -16541,6 +16544,7 @@ DUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) { duk_memcpy((void *) &snapshot->lj, (const void *) lj, sizeof(duk_ljstate)); snapshot->creating_error = heap->creating_error; snapshot->curr_thread = heap->curr_thread; + snapshot->thread_state = thr->state; snapshot->call_recursion_depth = heap->call_recursion_depth; lj->jmpbuf_ptr = NULL; @@ -16550,6 +16554,8 @@ DUK_EXTERNAL void duk_suspend(duk_hthread *thr, duk_thread_state *state) { heap->creating_error = 0; heap->curr_thread = NULL; heap->call_recursion_depth = 0; + + thr->state = DUK_HTHREAD_STATE_INACTIVE; } DUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) { @@ -16566,6 +16572,8 @@ DUK_EXTERNAL void duk_resume(duk_hthread *thr, const duk_thread_state *state) { DUK_ASSERT(thr->heap->pf_prevent_count == 0); DUK_ASSERT(thr->heap->creating_error == 0); + thr->state = snapshot->thread_state; + heap = thr->heap; duk_memcpy((void *) &heap->lj, (const void *) &snapshot->lj, sizeof(duk_ljstate)); @@ -30090,6 +30098,8 @@ typedef struct { duk_uint8_t *buf_end; duk_size_t len; duk_idx_t idx_buf; + duk_uint_t recursion_depth; + duk_uint_t recursion_limit; } duk_cbor_encode_context; typedef struct { @@ -30097,6 +30107,8 @@ typedef struct { const duk_uint8_t *buf; duk_size_t off; duk_size_t len; + duk_uint_t recursion_depth; + duk_uint_t recursion_limit; } duk_cbor_decode_context; DUK_LOCAL void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx); @@ -30120,6 +30132,34 @@ DUK_LOCAL void duk__cbor_encode_error(duk_cbor_encode_context *enc_ctx) { (void) duk_type_error(enc_ctx->thr, "cbor encode error"); } +DUK_LOCAL void duk__cbor_encode_req_stack(duk_cbor_encode_context *enc_ctx) { + duk_require_stack(enc_ctx->thr, 4); +} + +DUK_LOCAL void duk__cbor_encode_objarr_entry(duk_cbor_encode_context *enc_ctx) { + duk_hthread *thr = enc_ctx->thr; + + /* Native stack check in object/array recursion. */ + duk_native_stack_check(thr); + + /* When working with deeply recursive structures, this is important + * to ensure there's no effective depth limit. + */ + duk__cbor_encode_req_stack(enc_ctx); + + DUK_ASSERT(enc_ctx->recursion_depth <= enc_ctx->recursion_limit); + if (enc_ctx->recursion_depth >= enc_ctx->recursion_limit) { + DUK_ERROR_RANGE(thr, DUK_STR_ENC_RECLIMIT); + DUK_WO_NORETURN(return;); + } + enc_ctx->recursion_depth++; +} + +DUK_LOCAL void duk__cbor_encode_objarr_exit(duk_cbor_encode_context *enc_ctx) { + DUK_ASSERT(enc_ctx->recursion_depth > 0); + enc_ctx->recursion_depth--; +} + /* Check that a size_t is in uint32 range to avoid out-of-range casts. */ DUK_LOCAL void duk__cbor_encode_sizet_uint32_check(duk_cbor_encode_context *enc_ctx, duk_size_t len) { if (DUK_UNLIKELY(sizeof(duk_size_t) > sizeof(duk_uint32_t) && len > (duk_size_t) DUK_UINT32_MAX)) { @@ -30522,6 +30562,8 @@ DUK_LOCAL void duk__cbor_encode_object(duk_cbor_encode_context *enc_ctx) { /* Caller must ensure space. */ DUK_ASSERT(duk__cbor_get_reserve(enc_ctx) >= 1 + 8); + duk__cbor_encode_objarr_entry(enc_ctx); + /* XXX: Support for specific built-ins like Date and RegExp. */ if (duk_is_array(enc_ctx->thr, -1)) { /* Shortest encoding for arrays >= 256 in length is actually @@ -30546,7 +30588,7 @@ DUK_LOCAL void duk__cbor_encode_object(duk_cbor_encode_context *enc_ctx) { duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U); duk__cbor_encode_ensure(enc_ctx, len); p = enc_ctx->ptr; - duk_memcpy((void *) p, (const void *) buf, len); + duk_memcpy_unsafe((void *) p, (const void *) buf, len); p += len; enc_ctx->ptr = p; } else { @@ -30585,6 +30627,8 @@ DUK_LOCAL void duk__cbor_encode_object(duk_cbor_encode_context *enc_ctx) { enc_ctx->ptr = p; } } + + duk__cbor_encode_objarr_exit(enc_ctx); } DUK_LOCAL void duk__cbor_encode_buffer(duk_cbor_encode_context *enc_ctx) { @@ -30601,7 +30645,7 @@ DUK_LOCAL void duk__cbor_encode_buffer(duk_cbor_encode_context *enc_ctx) { duk__cbor_encode_uint32(enc_ctx, (duk_uint32_t) len, 0x40U); duk__cbor_encode_ensure(enc_ctx, len); p = enc_ctx->ptr; - duk_memcpy((void *) p, (const void *) buf, len); + duk_memcpy_unsafe((void *) p, (const void *) buf, len); p += len; enc_ctx->ptr = p; } @@ -30648,11 +30692,6 @@ DUK_LOCAL void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx) { * This can be improved by registering custom tags with IANA. */ - /* When working with deeply recursive structures, this is important - * to ensure there's no effective depth limit. - */ - duk_require_stack(enc_ctx->thr, 4); - /* Reserve space for up to 64-bit types (1 initial byte + 8 * followup bytes). This allows encoding of integers, floats, * string/buffer length fields, etc without separate checks @@ -30720,12 +30759,33 @@ DUK_LOCAL void duk__cbor_encode_value(duk_cbor_encode_context *enc_ctx) { * Decoding */ -DUK_LOCAL void duk__cbor_req_stack(duk_cbor_decode_context *dec_ctx) { +DUK_LOCAL void duk__cbor_decode_error(duk_cbor_decode_context *dec_ctx) { + (void) duk_type_error(dec_ctx->thr, "cbor decode error"); +} + +DUK_LOCAL void duk__cbor_decode_req_stack(duk_cbor_decode_context *dec_ctx) { duk_require_stack(dec_ctx->thr, 4); } -DUK_LOCAL void duk__cbor_decode_error(duk_cbor_decode_context *dec_ctx) { - (void) duk_type_error(dec_ctx->thr, "cbor decode error"); +DUK_LOCAL void duk__cbor_decode_objarr_entry(duk_cbor_decode_context *dec_ctx) { + duk_hthread *thr = dec_ctx->thr; + + /* Native stack check in object/array recursion. */ + duk_native_stack_check(thr); + + duk__cbor_decode_req_stack(dec_ctx); + + DUK_ASSERT(dec_ctx->recursion_depth <= dec_ctx->recursion_limit); + if (dec_ctx->recursion_depth >= dec_ctx->recursion_limit) { + DUK_ERROR_RANGE(thr, DUK_STR_DEC_RECLIMIT); + DUK_WO_NORETURN(return;); + } + dec_ctx->recursion_depth++; +} + +DUK_LOCAL void duk__cbor_decode_objarr_exit(duk_cbor_decode_context *dec_ctx) { + DUK_ASSERT(dec_ctx->recursion_depth > 0); + dec_ctx->recursion_depth--; } DUK_LOCAL duk_uint8_t duk__cbor_decode_readbyte(duk_cbor_decode_context *dec_ctx) { @@ -31004,9 +31064,7 @@ DUK_LOCAL void duk__cbor_decode_join_buffers(duk_cbor_decode_context *dec_ctx, d buf_data = (duk_uint8_t *) duk_require_buffer(dec_ctx->thr, idx, &buf_size); if (p != NULL) { - if (buf_size > 0U) { - duk_memcpy((void *) p, (const void *) buf_data, buf_size); - } + duk_memcpy_unsafe((void *) p, (const void *) buf_data, buf_size); p += buf_size; } else { total_size += buf_size; @@ -31171,7 +31229,7 @@ DUK_LOCAL void duk__cbor_decode_string(duk_cbor_decode_context *dec_ctx, duk_uin DUK_LOCAL duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) { duk_uint32_t idx, len; - duk__cbor_req_stack(dec_ctx); + duk__cbor_decode_objarr_entry(dec_ctx); /* Support arrays up to 0xfffffffeU in length. 0xffffffff is * used as an indefinite length marker. @@ -31181,7 +31239,7 @@ DUK_LOCAL duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, du } else { len = duk__cbor_decode_aival_uint32(dec_ctx, ib); if (len == 0xffffffffUL) { - return 0; + goto failure; } } @@ -31193,7 +31251,7 @@ DUK_LOCAL duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, du } if (idx == len) { if (ai == 0x1fU) { - return 0; + goto failure; } break; } @@ -31201,24 +31259,32 @@ DUK_LOCAL duk_bool_t duk__cbor_decode_array(duk_cbor_decode_context *dec_ctx, du duk_put_prop_index(dec_ctx->thr, -2, (duk_uarridx_t) idx); idx++; if (idx == 0U) { - return 0; /* wrapped */ + goto failure; /* wrapped */ } } +#if 0 + success: +#endif + duk__cbor_decode_objarr_exit(dec_ctx); return 1; + + failure: + /* No need to unwind recursion checks, caller will throw. */ + return 0; } DUK_LOCAL duk_bool_t duk__cbor_decode_map(duk_cbor_decode_context *dec_ctx, duk_uint8_t ib, duk_uint8_t ai) { duk_uint32_t count; - duk__cbor_req_stack(dec_ctx); + duk__cbor_decode_objarr_entry(dec_ctx); if (ai == 0x1fU) { count = 0xffffffffUL; } else { count = duk__cbor_decode_aival_uint32(dec_ctx, ib); if (count == 0xffffffffUL) { - return 0; + goto failure; } } @@ -31249,7 +31315,15 @@ DUK_LOCAL duk_bool_t duk__cbor_decode_map(duk_cbor_decode_context *dec_ctx, duk_ duk_put_prop(dec_ctx->thr, -3); } +#if 0 + success: +#endif + duk__cbor_decode_objarr_exit(dec_ctx); return 1; + + failure: + /* No need to unwind recursion checks, caller will throw. */ + return 0; } DUK_LOCAL duk_double_t duk__cbor_decode_float(duk_cbor_decode_context *dec_ctx) { @@ -31626,8 +31700,13 @@ DUK_LOCAL void duk__cbor_encode(duk_hthread *thr, duk_idx_t idx, duk_uint_t enco enc_ctx.buf = buf; enc_ctx.buf_end = buf + enc_ctx.len; + enc_ctx.recursion_depth = 0; + enc_ctx.recursion_limit = DUK_USE_CBOR_ENC_RECLIMIT; + duk_dup(thr, idx); + duk__cbor_encode_req_stack(&enc_ctx); duk__cbor_encode_value(&enc_ctx); + DUK_ASSERT(enc_ctx.recursion_depth == 0); duk_resize_buffer(enc_ctx.thr, enc_ctx.idx_buf, (duk_size_t) (enc_ctx.ptr - enc_ctx.buf)); duk_replace(thr, idx); } @@ -31649,8 +31728,12 @@ DUK_LOCAL void duk__cbor_decode(duk_hthread *thr, duk_idx_t idx, duk_uint_t deco dec_ctx.off = 0; /* dec_ctx.len: set above */ - duk__cbor_req_stack(&dec_ctx); + dec_ctx.recursion_depth = 0; + dec_ctx.recursion_limit = DUK_USE_CBOR_DEC_RECLIMIT; + + duk__cbor_decode_req_stack(&dec_ctx); duk__cbor_decode_value(&dec_ctx); + DUK_ASSERT(dec_ctx.recursion_depth == 0); if (dec_ctx.off != dec_ctx.len) { (void) duk_type_error(thr, "trailing garbage"); } @@ -36373,28 +36456,28 @@ DUK_INTERNAL duk_ret_t duk_bi_global_object_unescape(duk_hthread *thr) { #define DUK__JSON_STRINGIFY_BUFSIZE 128 #define DUK__JSON_MAX_ESC_LEN 10 /* '\Udeadbeef' */ -DUK_LOCAL_DECL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_syntax_error(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_eat_white(duk_json_dec_ctx *js_ctx); #if defined(DUK_USE_JX) -DUK_LOCAL_DECL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL duk_uint8_t duk__json_dec_peek(duk_json_dec_ctx *js_ctx); #endif -DUK_LOCAL_DECL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n); -DUK_LOCAL_DECL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx); -DUK_LOCAL_DECL void duk__dec_string(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL duk_uint8_t duk__json_dec_get(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL duk_uint8_t duk__json_dec_get_nonwhite(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL duk_uint_fast32_t duk__json_dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n); +DUK_LOCAL_DECL void duk__json_dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx); +DUK_LOCAL_DECL void duk__json_dec_string(duk_json_dec_ctx *js_ctx); #if defined(DUK_USE_JX) -DUK_LOCAL_DECL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL void duk__dec_pointer(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL void duk__dec_buffer(duk_json_dec_ctx *js_ctx); -#endif -DUK_LOCAL_DECL void duk__dec_number(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL void duk__dec_object(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL void duk__dec_array(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL void duk__dec_value(duk_json_dec_ctx *js_ctx); -DUK_LOCAL_DECL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_plain_string(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_pointer(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_buffer(duk_json_dec_ctx *js_ctx); +#endif +DUK_LOCAL_DECL void duk__json_dec_number(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_objarr_entry(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_objarr_exit(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_object(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_array(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_value(duk_json_dec_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_dec_reviver_walk(duk_json_dec_ctx *js_ctx); DUK_LOCAL_DECL void duk__emit_1(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch); DUK_LOCAL_DECL void duk__emit_2(duk_json_enc_ctx *js_ctx, duk_uint_fast8_t ch1, duk_uint_fast8_t ch2); @@ -36405,29 +36488,29 @@ DUK_LOCAL_DECL void duk__emit_cstring(duk_json_enc_ctx *js_ctx, const char *p); #endif DUK_LOCAL_DECL void duk__emit_stridx(duk_json_enc_ctx *js_ctx, duk_small_uint_t stridx); DUK_LOCAL_DECL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uint_fast32_t cp, duk_uint8_t *q); -DUK_LOCAL_DECL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k); -DUK_LOCAL_DECL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str); -DUK_LOCAL_DECL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top); -DUK_LOCAL_DECL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top); -DUK_LOCAL_DECL void duk__enc_object(duk_json_enc_ctx *js_ctx); -DUK_LOCAL_DECL void duk__enc_array(duk_json_enc_ctx *js_ctx); -DUK_LOCAL_DECL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder); -DUK_LOCAL_DECL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv); -DUK_LOCAL_DECL void duk__enc_double(duk_json_enc_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k); +DUK_LOCAL_DECL void duk__json_enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str); +DUK_LOCAL_DECL void duk__json_enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top); +DUK_LOCAL_DECL void duk__json_enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top); +DUK_LOCAL_DECL void duk__json_enc_object(duk_json_enc_ctx *js_ctx); +DUK_LOCAL_DECL void duk__json_enc_array(duk_json_enc_ctx *js_ctx); +DUK_LOCAL_DECL duk_bool_t duk__json_enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder); +DUK_LOCAL_DECL duk_bool_t duk__json_enc_allow_into_proplist(duk_tval *tv); +DUK_LOCAL_DECL void duk__json_enc_double(duk_json_enc_ctx *js_ctx); #if defined(DUK_USE_FASTINT) -DUK_LOCAL_DECL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv); +DUK_LOCAL_DECL void duk__json_enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv); #endif #if defined(DUK_USE_JX) || defined(DUK_USE_JC) -DUK_LOCAL_DECL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h); -DUK_LOCAL_DECL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr); +DUK_LOCAL_DECL void duk__json_enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h); +DUK_LOCAL_DECL void duk__json_enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr); #if defined(DUK_USE_BUFFEROBJECT_SUPPORT) -DUK_LOCAL_DECL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj); +DUK_LOCAL_DECL void duk__json_enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj); #endif #endif #if defined(DUK_USE_JSON_STRINGIFY_FASTPATH) -DUK_LOCAL_DECL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h); +DUK_LOCAL_DECL void duk__json_enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h); #endif -DUK_LOCAL_DECL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth); +DUK_LOCAL_DECL void duk__json_enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth); /* * Helper tables @@ -36552,7 +36635,7 @@ DUK_LOCAL const duk_uint8_t duk__json_decnumber_lookup[256] = { * CESU-8 encodings. */ -DUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_syntax_error(duk_json_dec_ctx *js_ctx) { /* Shared handler to minimize parser size. Cause will be * hidden, unfortunately, but we'll have an offset which * is often quite enough. @@ -36562,7 +36645,7 @@ DUK_LOCAL void duk__dec_syntax_error(duk_json_dec_ctx *js_ctx) { DUK_WO_NORETURN(return;); } -DUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_eat_white(duk_json_dec_ctx *js_ctx) { const duk_uint8_t *p; duk_uint8_t t; @@ -36593,24 +36676,24 @@ DUK_LOCAL void duk__dec_eat_white(duk_json_dec_ctx *js_ctx) { } #if defined(DUK_USE_JX) -DUK_LOCAL duk_uint8_t duk__dec_peek(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL duk_uint8_t duk__json_dec_peek(duk_json_dec_ctx *js_ctx) { DUK_ASSERT(js_ctx->p <= js_ctx->p_end); return *js_ctx->p; } #endif -DUK_LOCAL duk_uint8_t duk__dec_get(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL duk_uint8_t duk__json_dec_get(duk_json_dec_ctx *js_ctx) { DUK_ASSERT(js_ctx->p <= js_ctx->p_end); return *js_ctx->p++; } -DUK_LOCAL duk_uint8_t duk__dec_get_nonwhite(duk_json_dec_ctx *js_ctx) { - duk__dec_eat_white(js_ctx); - return duk__dec_get(js_ctx); +DUK_LOCAL duk_uint8_t duk__json_dec_get_nonwhite(duk_json_dec_ctx *js_ctx) { + duk__json_dec_eat_white(js_ctx); + return duk__json_dec_get(js_ctx); } /* For JX, expressing the whole unsigned 32-bit range matters. */ -DUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n) { +DUK_LOCAL duk_uint_fast32_t duk__json_dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, duk_small_uint_t n) { duk_small_uint_t i; duk_uint_fast32_t res = 0; duk_uint8_t x; @@ -36619,7 +36702,7 @@ DUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, for (i = 0; i < n; i++) { /* XXX: share helper from lexer; duk_lexer.c / hexval(). */ - x = duk__dec_get(js_ctx); + x = duk__json_dec_get(js_ctx); DUK_DDD(DUK_DDDPRINT("decode_hex_escape: i=%ld, n=%ld, res=%ld, x=%ld", (long) i, (long) n, (long) res, (long) x)); @@ -36638,12 +36721,12 @@ DUK_LOCAL duk_uint_fast32_t duk__dec_decode_hex_escape(duk_json_dec_ctx *js_ctx, return res; syntax_error: - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); DUK_UNREACHABLE(); return 0; } -DUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx) { +DUK_LOCAL void duk__json_dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t stridx) { duk_hstring *h; const duk_uint8_t *p; duk_uint8_t x, y; @@ -36665,7 +36748,7 @@ DUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t st if (x == 0) { break; } - y = duk__dec_get(js_ctx); + y = duk__json_dec_get(js_ctx); if (x != y) { /* Catches EOF of JSON input. */ goto syntax_error; @@ -36676,18 +36759,18 @@ DUK_LOCAL void duk__dec_req_stridx(duk_json_dec_ctx *js_ctx, duk_small_uint_t st return; syntax_error: - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); DUK_UNREACHABLE(); } -DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p) { +DUK_LOCAL duk_small_int_t duk__json_dec_string_escape(duk_json_dec_ctx *js_ctx, duk_uint8_t **ext_p) { duk_uint_fast32_t cp; /* EOF (-1) will be cast to an unsigned value first * and then re-cast for the switch. In any case, it * will match the default case (syntax error). */ - cp = (duk_uint_fast32_t) duk__dec_get(js_ctx); + cp = (duk_uint_fast32_t) duk__json_dec_get(js_ctx); switch (cp) { case DUK_ASC_BACKSLASH: break; case DUK_ASC_DOUBLEQUOTE: break; @@ -36698,13 +36781,13 @@ DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_u case DUK_ASC_LC_F: cp = 0x0c; break; case DUK_ASC_LC_B: cp = 0x08; break; case DUK_ASC_LC_U: { - cp = duk__dec_decode_hex_escape(js_ctx, 4); + cp = duk__json_dec_decode_hex_escape(js_ctx, 4); break; } #if defined(DUK_USE_JX) case DUK_ASC_UC_U: { if (js_ctx->flag_ext_custom) { - cp = duk__dec_decode_hex_escape(js_ctx, 8); + cp = duk__json_dec_decode_hex_escape(js_ctx, 8); } else { return 1; /* syntax error */ } @@ -36712,7 +36795,7 @@ DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_u } case DUK_ASC_LC_X: { if (js_ctx->flag_ext_custom) { - cp = duk__dec_decode_hex_escape(js_ctx, 2); + cp = duk__json_dec_decode_hex_escape(js_ctx, 2); } else { return 1; /* syntax error */ } @@ -36729,7 +36812,7 @@ DUK_LOCAL duk_small_int_t duk__dec_string_escape(duk_json_dec_ctx *js_ctx, duk_u return 0; } -DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_string(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; duk_bufwriter_ctx bw_alloc; duk_bufwriter_ctx *bw; @@ -36788,7 +36871,7 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) { * quite slow but it's uncommon). */ js_ctx->p = p; - if (duk__dec_string_escape(js_ctx, &q) != 0) { + if (duk__json_dec_string_escape(js_ctx, &q) != 0) { goto syntax_error; } break; @@ -36805,12 +36888,12 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) { q = DUK_BW_ENSURE_RAW(js_ctx->thr, bw, DUK_UNICODE_MAX_XUTF8_LENGTH, q); - x = duk__dec_get(js_ctx); + x = duk__json_dec_get(js_ctx); if (x == DUK_ASC_DOUBLEQUOTE) { break; } else if (x == DUK_ASC_BACKSLASH) { - if (duk__dec_string_escape(js_ctx, &q) != 0) { + if (duk__json_dec_string_escape(js_ctx, &q) != 0) { goto syntax_error; } } else if (x < 0x20) { @@ -36830,7 +36913,7 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) { return; syntax_error: - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); DUK_UNREACHABLE(); } @@ -36838,7 +36921,7 @@ DUK_LOCAL void duk__dec_string(duk_json_dec_ctx *js_ctx) { /* Decode a plain string consisting entirely of identifier characters. * Used to parse plain keys (e.g. "foo: 123"). */ -DUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_plain_string(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; const duk_uint8_t *p; duk_small_int_t x; @@ -36880,7 +36963,7 @@ DUK_LOCAL void duk__dec_plain_string(duk_json_dec_ctx *js_ctx) { #endif /* DUK_USE_JX */ #if defined(DUK_USE_JX) -DUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_pointer(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; const duk_uint8_t *p; duk_small_int_t x; @@ -36927,13 +37010,13 @@ DUK_LOCAL void duk__dec_pointer(duk_json_dec_ctx *js_ctx) { return; syntax_error: - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); DUK_UNREACHABLE(); } #endif /* DUK_USE_JX */ #if defined(DUK_USE_JX) -DUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_buffer(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; const duk_uint8_t *p; duk_uint8_t *buf; @@ -36985,13 +37068,13 @@ DUK_LOCAL void duk__dec_buffer(duk_json_dec_ctx *js_ctx) { return; syntax_error: - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); DUK_UNREACHABLE(); } #endif /* DUK_USE_JX */ /* Parse a number, other than NaN or +/- Infinity */ -DUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_number(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; const duk_uint8_t *p_start; const duk_uint8_t *p; @@ -37047,7 +37130,7 @@ DUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) { (duk_tval *) duk_get_tval(thr, -1))); duk_numconv_parse(thr, 10 /*radix*/, s2n_flags); if (duk_is_nan(thr, -1)) { - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); } DUK_ASSERT(duk_is_number(thr, -1)); DUK_DDD(DUK_DDDPRINT("parse_number: final number: %!T", @@ -37056,22 +37139,24 @@ DUK_LOCAL void duk__dec_number(duk_json_dec_ctx *js_ctx) { /* [ ... num ] */ } -DUK_LOCAL void duk__dec_objarr_entry(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_objarr_entry(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; duk_require_stack(thr, DUK_JSON_DEC_REQSTACK); /* c recursion check */ + duk_native_stack_check(thr); + DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */ DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); if (js_ctx->recursion_depth >= js_ctx->recursion_limit) { - DUK_ERROR_RANGE(thr, DUK_STR_JSONDEC_RECLIMIT); + DUK_ERROR_RANGE(thr, DUK_STR_DEC_RECLIMIT); DUK_WO_NORETURN(return;); } js_ctx->recursion_depth++; } -DUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_objarr_exit(duk_json_dec_ctx *js_ctx) { /* c recursion check */ DUK_ASSERT(js_ctx->recursion_depth > 0); @@ -37079,14 +37164,14 @@ DUK_LOCAL void duk__dec_objarr_exit(duk_json_dec_ctx *js_ctx) { js_ctx->recursion_depth--; } -DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_object(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; duk_int_t key_count; /* XXX: a "first" flag would suffice */ duk_uint8_t x; DUK_DDD(DUK_DDDPRINT("parse_object")); - duk__dec_objarr_entry(js_ctx); + duk__json_dec_objarr_entry(js_ctx); duk_push_object(thr); @@ -37094,7 +37179,7 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) { key_count = 0; for (;;) { - x = duk__dec_get_nonwhite(js_ctx); + x = duk__json_dec_get_nonwhite(js_ctx); DUK_DDD(DUK_DDDPRINT("parse_object: obj=%!T, x=%ld, key_count=%ld", (duk_tval *) duk_get_tval(thr, -1), @@ -37104,7 +37189,7 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) { if (x == DUK_ASC_COMMA && key_count > 0) { /* accept comma, expect new value */ - x = duk__dec_get_nonwhite(js_ctx); + x = duk__json_dec_get_nonwhite(js_ctx); } else if (x == DUK_ASC_RCURLY) { /* eat closing brace */ break; @@ -37121,11 +37206,11 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) { /* parse key and value */ if (x == DUK_ASC_DOUBLEQUOTE) { - duk__dec_string(js_ctx); + duk__json_dec_string(js_ctx); #if defined(DUK_USE_JX) } else if (js_ctx->flag_ext_custom && duk_unicode_is_identifier_start((duk_codepoint_t) x)) { - duk__dec_plain_string(js_ctx); + duk__json_dec_plain_string(js_ctx); #endif } else { goto syntax_error; @@ -37133,12 +37218,12 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) { /* [ ... obj key ] */ - x = duk__dec_get_nonwhite(js_ctx); + x = duk__json_dec_get_nonwhite(js_ctx); if (x != DUK_ASC_COLON) { goto syntax_error; } - duk__dec_value(js_ctx); + duk__json_dec_value(js_ctx); /* [ ... obj key val ] */ @@ -37154,22 +37239,22 @@ DUK_LOCAL void duk__dec_object(duk_json_dec_ctx *js_ctx) { DUK_DDD(DUK_DDDPRINT("parse_object: final object is %!T", (duk_tval *) duk_get_tval(thr, -1))); - duk__dec_objarr_exit(js_ctx); + duk__json_dec_objarr_exit(js_ctx); return; syntax_error: - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); DUK_UNREACHABLE(); } -DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_array(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; duk_uarridx_t arr_idx; duk_uint8_t x; DUK_DDD(DUK_DDDPRINT("parse_array")); - duk__dec_objarr_entry(js_ctx); + duk__json_dec_objarr_entry(js_ctx); duk_push_array(thr); @@ -37177,7 +37262,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) { arr_idx = 0; for (;;) { - x = duk__dec_get_nonwhite(js_ctx); + x = duk__json_dec_get_nonwhite(js_ctx); DUK_DDD(DUK_DDDPRINT("parse_array: arr=%!T, x=%ld, arr_idx=%ld", (duk_tval *) duk_get_tval(thr, -1), @@ -37193,7 +37278,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) { break; } else if (arr_idx == 0) { /* accept anything, expect first value (EOF will be - * caught by duk__dec_value() below. + * caught by duk__json_dec_value() below. */ js_ctx->p--; /* backtrack (safe) */ } else { @@ -37203,7 +37288,7 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) { /* parse value */ - duk__dec_value(js_ctx); + duk__json_dec_value(js_ctx); /* [ ... arr val ] */ @@ -37222,30 +37307,30 @@ DUK_LOCAL void duk__dec_array(duk_json_dec_ctx *js_ctx) { DUK_DDD(DUK_DDDPRINT("parse_array: final array is %!T", (duk_tval *) duk_get_tval(thr, -1))); - duk__dec_objarr_exit(js_ctx); + duk__json_dec_objarr_exit(js_ctx); return; syntax_error: - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); DUK_UNREACHABLE(); } -DUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_value(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; duk_uint8_t x; - x = duk__dec_get_nonwhite(js_ctx); + x = duk__json_dec_get_nonwhite(js_ctx); DUK_DDD(DUK_DDDPRINT("parse_value: initial x=%ld", (long) x)); - /* Note: duk__dec_req_stridx() backtracks one char */ + /* Note: duk__json_dec_req_stridx() backtracks one char */ if (x == DUK_ASC_DOUBLEQUOTE) { - duk__dec_string(js_ctx); + duk__json_dec_string(js_ctx); } else if ((x >= DUK_ASC_0 && x <= DUK_ASC_9) || (x == DUK_ASC_MINUS)) { #if defined(DUK_USE_JX) - if (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__dec_peek(js_ctx) == DUK_ASC_UC_I) { - duk__dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY); /* "-Infinity", '-' has been eaten */ + if (js_ctx->flag_ext_custom && x == DUK_ASC_MINUS && duk__json_dec_peek(js_ctx) == DUK_ASC_UC_I) { + duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_MINUS_INFINITY); /* "-Infinity", '-' has been eaten */ duk_push_number(thr, -DUK_DOUBLE_INFINITY); } else { #else @@ -37253,60 +37338,63 @@ DUK_LOCAL void duk__dec_value(duk_json_dec_ctx *js_ctx) { #endif /* We already ate 'x', so backup one byte. */ js_ctx->p--; /* safe */ - duk__dec_number(js_ctx); + duk__json_dec_number(js_ctx); } } else if (x == DUK_ASC_LC_T) { - duk__dec_req_stridx(js_ctx, DUK_STRIDX_TRUE); + duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_TRUE); duk_push_true(thr); } else if (x == DUK_ASC_LC_F) { - duk__dec_req_stridx(js_ctx, DUK_STRIDX_FALSE); + duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_FALSE); duk_push_false(thr); } else if (x == DUK_ASC_LC_N) { - duk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL); + duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_LC_NULL); duk_push_null(thr); #if defined(DUK_USE_JX) } else if (js_ctx->flag_ext_custom && x == DUK_ASC_LC_U) { - duk__dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED); + duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_LC_UNDEFINED); duk_push_undefined(thr); } else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_N) { - duk__dec_req_stridx(js_ctx, DUK_STRIDX_NAN); + duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_NAN); duk_push_nan(thr); } else if (js_ctx->flag_ext_custom && x == DUK_ASC_UC_I) { - duk__dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY); + duk__json_dec_req_stridx(js_ctx, DUK_STRIDX_INFINITY); duk_push_number(thr, DUK_DOUBLE_INFINITY); } else if (js_ctx->flag_ext_custom && x == DUK_ASC_LPAREN) { - duk__dec_pointer(js_ctx); + duk__json_dec_pointer(js_ctx); } else if (js_ctx->flag_ext_custom && x == DUK_ASC_PIPE) { - duk__dec_buffer(js_ctx); + duk__json_dec_buffer(js_ctx); #endif } else if (x == DUK_ASC_LCURLY) { - duk__dec_object(js_ctx); + duk__json_dec_object(js_ctx); } else if (x == DUK_ASC_LBRACKET) { - duk__dec_array(js_ctx); + duk__json_dec_array(js_ctx); } else { /* catches EOF (NUL) */ goto syntax_error; } - duk__dec_eat_white(js_ctx); + duk__json_dec_eat_white(js_ctx); /* [ ... val ] */ return; syntax_error: - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); DUK_UNREACHABLE(); } -/* Recursive value reviver, implements the Walk() algorithm. No C recursion - * check is done here because the initial parsing step will already ensure - * there is a reasonable limit on C recursion depth and hence object depth. +/* Recursive value reviver, implements the Walk() algorithm. The parsing + * step ensures there is a reasonable depth limit to the input. However, + * the reviver may create more depth by editing object or array entries, so + * we have both C recursion limit and native stack checks here. */ -DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) { +DUK_LOCAL void duk__json_dec_reviver_walk(duk_json_dec_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; duk_hobject *h; duk_uarridx_t i, arr_len; + duk__json_dec_objarr_entry(js_ctx); + DUK_DDD(DUK_DDDPRINT("walk: top=%ld, holder=%!T, name=%!T", (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -2), @@ -37329,7 +37417,7 @@ DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) { duk_dup_top(thr); (void) duk_push_uint_to_hstring(thr, (duk_uint_t) i); /* -> [ ... holder name val val ToString(i) ] */ - duk__dec_reviver_walk(js_ctx); /* -> [ ... holder name val new_elem ] */ + duk__json_dec_reviver_walk(js_ctx); /* -> [ ... holder name val new_elem ] */ if (duk_is_undefined(thr, -1)) { duk_pop(thr); @@ -37356,7 +37444,7 @@ DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) { duk_dup_m2(thr); /* [ ... holder name val enum obj_key val obj_key ] */ - duk__dec_reviver_walk(js_ctx); + duk__json_dec_reviver_walk(js_ctx); /* [ ... holder name val enum obj_key new_elem ] */ if (duk_is_undefined(thr, -1)) { @@ -37385,6 +37473,8 @@ DUK_LOCAL void duk__dec_reviver_walk(duk_json_dec_ctx *js_ctx) { duk_insert(thr, -4); /* -> [ ... reviver holder name val ] */ duk_call_method(thr, 2); /* -> [ ... res ] */ + duk__json_dec_objarr_exit(js_ctx); + DUK_DDD(DUK_DDDPRINT("walk: top=%ld, result=%!T", (long) duk_get_top(thr), (duk_tval *) duk_get_tval(thr, -1))); } @@ -37494,7 +37584,7 @@ DUK_LOCAL duk_uint8_t *duk__emit_esc_auto_fast(duk_json_enc_ctx *js_ctx, duk_uin return q; } -DUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) { +DUK_LOCAL void duk__json_enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) { const duk_int8_t *p, *p_start, *p_end; /* Note: intentionally signed. */ duk_size_t k_len; duk_codepoint_t cp; @@ -37537,7 +37627,7 @@ DUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) } quote_normally: - duk__enc_quote_string(js_ctx, k); + duk__json_enc_quote_string(js_ctx, k); } /* The Quote(value) operation: quote a string. @@ -37545,13 +37635,13 @@ DUK_LOCAL void duk__enc_key_autoquote(duk_json_enc_ctx *js_ctx, duk_hstring *k) * Stack policy: [ ] -> [ ]. */ -DUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str) { +DUK_LOCAL void duk__json_enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_str) { duk_hthread *thr = js_ctx->thr; const duk_uint8_t *p, *p_start, *p_end, *p_now, *p_tmp; duk_uint8_t *q; duk_ucodepoint_t cp; /* typed for duk_unicode_decode_xutf8() */ - DUK_DDD(DUK_DDDPRINT("duk__enc_quote_string: h_str=%!O", (duk_heaphdr *) h_str)); + DUK_DDD(DUK_DDDPRINT("duk__json_enc_quote_string: h_str=%!O", (duk_heaphdr *) h_str)); DUK_ASSERT(h_str != NULL); p_start = DUK_HSTRING_GET_DATA(h_str); @@ -37682,7 +37772,7 @@ DUK_LOCAL void duk__enc_quote_string(duk_json_enc_ctx *js_ctx, duk_hstring *h_st /* Encode a double (checked by caller) from stack top. Stack top may be * replaced by serialized string but is not popped (caller does that). */ -DUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) { +DUK_LOCAL void duk__json_enc_double(duk_json_enc_ctx *js_ctx) { duk_hthread *thr; duk_tval *tv; duk_double_t d; @@ -37746,7 +37836,7 @@ DUK_LOCAL void duk__enc_double(duk_json_enc_ctx *js_ctx) { #if defined(DUK_USE_FASTINT) /* Encode a fastint from duk_tval ptr, no value stack effects. */ -DUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) { +DUK_LOCAL void duk__json_enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) { duk_int64_t v; /* Fastint range is signed 48-bit so longest value is -2^47 = -140737488355328 @@ -37771,7 +37861,7 @@ DUK_LOCAL void duk__enc_fastint_tval(duk_json_enc_ctx *js_ctx, duk_tval *tv) { #if defined(DUK_USE_JX) || defined(DUK_USE_JC) #if defined(DUK_USE_HEX_FASTPATH) -DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) { +DUK_LOCAL duk_uint8_t *duk__json_enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) { duk_uint8_t *q; duk_uint16_t *q16; duk_small_uint_t x; @@ -37829,7 +37919,7 @@ DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size return q; } #else /* DUK_USE_HEX_FASTPATH */ -DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) { +DUK_LOCAL duk_uint8_t *duk__json_enc_buffer_data_hex(const duk_uint8_t *src, duk_size_t src_len, duk_uint8_t *dst) { const duk_uint8_t *p; const duk_uint8_t *p_end; duk_uint8_t *q; @@ -37848,7 +37938,7 @@ DUK_LOCAL duk_uint8_t *duk__enc_buffer_data_hex(const duk_uint8_t *src, duk_size } #endif /* DUK_USE_HEX_FASTPATH */ -DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len) { +DUK_LOCAL void duk__json_enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_data, duk_size_t buf_len) { duk_hthread *thr; duk_uint8_t *q; duk_size_t space; @@ -37880,7 +37970,7 @@ DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_d #if defined(DUK_USE_JX) { *q++ = DUK_ASC_PIPE; - q = duk__enc_buffer_data_hex(buf_data, buf_len, q); + q = duk__json_enc_buffer_data_hex(buf_data, buf_len, q); *q++ = DUK_ASC_PIPE; } @@ -37893,7 +37983,7 @@ DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_d DUK_ASSERT(js_ctx->flag_ext_compatible); duk_memcpy((void *) q, (const void *) "{\"_buf\":\"", 9); /* len: 9 */ q += 9; - q = duk__enc_buffer_data_hex(buf_data, buf_len, q); + q = duk__json_enc_buffer_data_hex(buf_data, buf_len, q); *q++ = DUK_ASC_DOUBLEQUOTE; *q++ = DUK_ASC_RCURLY; } @@ -37902,15 +37992,15 @@ DUK_LOCAL void duk__enc_buffer_data(duk_json_enc_ctx *js_ctx, duk_uint8_t *buf_d DUK_BW_SET_PTR(thr, &js_ctx->bw, q); } -DUK_LOCAL void duk__enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) { - duk__enc_buffer_data(js_ctx, +DUK_LOCAL void duk__json_enc_buffer_jx_jc(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) { + duk__json_enc_buffer_data(js_ctx, (duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h), (duk_size_t) DUK_HBUFFER_GET_SIZE(h)); } #endif /* DUK_USE_JX || DUK_USE_JC */ #if defined(DUK_USE_JSON_STRINGIFY_FASTPATH) -DUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) { +DUK_LOCAL void duk__json_enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuffer *h) { duk_size_t i, n; const duk_uint8_t *buf; duk_uint8_t *q; @@ -37934,7 +38024,7 @@ DUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuff buf = (const duk_uint8_t *) DUK_HBUFFER_GET_DATA_PTR(js_ctx->thr->heap, h); if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { for (i = 0; i < n; i++) { - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth + 1); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth + 1); q = DUK_BW_ENSURE_GETPTR(js_ctx->thr, &js_ctx->bw, 32); q += DUK_SPRINTF((char *) q, "\"%lu\": %u,", (unsigned long) i, (unsigned int) buf[i]); DUK_BW_SET_PTR(js_ctx->thr, &js_ctx->bw, q); @@ -37950,14 +38040,14 @@ DUK_LOCAL void duk__enc_buffer_json_fastpath(duk_json_enc_ctx *js_ctx, duk_hbuff DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth); } DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY); } #endif /* DUK_USE_JSON_STRINGIFY_FASTPATH */ #if defined(DUK_USE_JX) || defined(DUK_USE_JC) -DUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) { +DUK_LOCAL void duk__json_enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) { char buf[64]; /* XXX: how to figure correct size? */ const char *fmt; @@ -37995,14 +38085,14 @@ DUK_LOCAL void duk__enc_pointer(duk_json_enc_ctx *js_ctx, void *ptr) { #if defined(DUK_USE_BUFFEROBJECT_SUPPORT) #if defined(DUK_USE_JX) || defined(DUK_USE_JC) -DUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) { +DUK_LOCAL void duk__json_enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) { DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); if (h_bufobj->buf == NULL || !DUK_HBUFOBJ_VALID_SLICE(h_bufobj)) { DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL); } else { /* Handle both full and partial slice (as long as covered). */ - duk__enc_buffer_data(js_ctx, + duk__json_enc_buffer_data(js_ctx, (duk_uint8_t *) DUK_HBUFOBJ_GET_SLICE_BASE(js_ctx->thr->heap, h_bufobj), (duk_size_t) h_bufobj->length); } @@ -38014,7 +38104,7 @@ DUK_LOCAL void duk__enc_bufobj(duk_json_enc_ctx *js_ctx, duk_hbufobj *h_bufobj) * directly related to indent depth. */ #if defined(DUK_USE_PREFER_SIZE) -DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) { +DUK_LOCAL void duk__json_enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) { DUK_ASSERT(js_ctx->h_gap != NULL); DUK_ASSERT(DUK_HSTRING_GET_BYTELEN(js_ctx->h_gap) > 0); /* caller guarantees */ @@ -38024,7 +38114,7 @@ DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t dept } } #else /* DUK_USE_PREFER_SIZE */ -DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) { +DUK_LOCAL void duk__json_enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t depth) { const duk_uint8_t *gap_data; duk_size_t gap_len; duk_size_t avail_bytes; /* bytes of indent available for copying */ @@ -38077,13 +38167,14 @@ DUK_LOCAL void duk__enc_newline_indent(duk_json_enc_ctx *js_ctx, duk_uint_t dept #endif /* DUK_USE_PREFER_SIZE */ /* Shared entry handling for object/array serialization. */ -DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) { +DUK_LOCAL void duk__json_enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) { duk_hthread *thr = js_ctx->thr; duk_hobject *h_target; duk_uint_fast32_t i, n; *entry_top = duk_get_top(thr); + duk_native_stack_check(thr); duk_require_stack(thr, DUK_JSON_ENC_REQSTACK); /* Loop check using a hybrid approach: a fixed-size visited[] array @@ -38121,7 +38212,7 @@ DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_ DUK_ASSERT_DISABLE(js_ctx->recursion_depth >= 0); /* unsigned */ DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); if (js_ctx->recursion_depth >= js_ctx->recursion_limit) { - DUK_ERROR_RANGE(thr, DUK_STR_JSONENC_RECLIMIT); + DUK_ERROR_RANGE(thr, DUK_STR_ENC_RECLIMIT); DUK_WO_NORETURN(return;); } js_ctx->recursion_depth++; @@ -38131,7 +38222,7 @@ DUK_LOCAL void duk__enc_objarr_entry(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_ } /* Shared exit handling for object/array serialization. */ -DUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) { +DUK_LOCAL void duk__json_enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_top) { duk_hthread *thr = js_ctx->thr; duk_hobject *h_target; @@ -38163,7 +38254,7 @@ DUK_LOCAL void duk__enc_objarr_exit(duk_json_enc_ctx *js_ctx, duk_idx_t *entry_t * * Stack policy: [ object ] -> [ object ]. */ -DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) { +DUK_LOCAL void duk__json_enc_object(duk_json_enc_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; duk_hstring *h_key; duk_idx_t entry_top; @@ -38173,9 +38264,9 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) { duk_uarridx_t arr_len, i; duk_size_t prev_size; - DUK_DDD(DUK_DDDPRINT("duk__enc_object: obj=%!T", (duk_tval *) duk_get_tval(thr, -1))); + DUK_DDD(DUK_DDDPRINT("duk__json_enc_object: obj=%!T", (duk_tval *) duk_get_tval(thr, -1))); - duk__enc_objarr_entry(js_ctx, &entry_top); + duk__json_enc_objarr_entry(js_ctx, &entry_top); idx_obj = entry_top - 1; @@ -38217,17 +38308,17 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) { prev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw); if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); - duk__enc_key_autoquote(js_ctx, h_key); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth); + duk__json_enc_key_autoquote(js_ctx, h_key); DUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE); } else { - duk__enc_key_autoquote(js_ctx, h_key); + duk__json_enc_key_autoquote(js_ctx, h_key); DUK__EMIT_1(js_ctx, DUK_ASC_COLON); } /* [ ... key ] */ - if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_obj) == 0)) { + if (DUK_UNLIKELY(duk__json_enc_value(js_ctx, idx_obj) == 0)) { /* Value would yield 'undefined', so skip key altogether. * Side effects have already happened. */ @@ -38245,12 +38336,12 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) { DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { DUK_ASSERT(js_ctx->recursion_depth >= 1); - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); } } DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY); - duk__enc_objarr_exit(js_ctx, &entry_top); + duk__json_enc_objarr_exit(js_ctx, &entry_top); DUK_ASSERT_TOP(thr, entry_top); } @@ -38259,17 +38350,17 @@ DUK_LOCAL void duk__enc_object(duk_json_enc_ctx *js_ctx) { * * Stack policy: [ array ] -> [ array ]. */ -DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) { +DUK_LOCAL void duk__json_enc_array(duk_json_enc_ctx *js_ctx) { duk_hthread *thr = js_ctx->thr; duk_idx_t entry_top; duk_idx_t idx_arr; duk_bool_t emitted; duk_uarridx_t i, arr_len; - DUK_DDD(DUK_DDDPRINT("duk__enc_array: array=%!T", + DUK_DDD(DUK_DDDPRINT("duk__json_enc_array: array=%!T", (duk_tval *) duk_get_tval(thr, -1))); - duk__enc_objarr_entry(js_ctx, &entry_top); + duk__json_enc_objarr_entry(js_ctx, &entry_top); idx_arr = entry_top - 1; @@ -38286,14 +38377,14 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) { if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { DUK_ASSERT(js_ctx->recursion_depth >= 1); - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth); } (void) duk_push_uint_to_hstring(thr, (duk_uint_t) i); /* -> [ ... key ] */ /* [ ... key ] */ - if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_arr) == 0)) { + if (DUK_UNLIKELY(duk__json_enc_value(js_ctx, idx_arr) == 0)) { /* Value would normally be omitted, replace with 'null'. */ DUK__EMIT_STRIDX(js_ctx, DUK_STRIDX_LC_NULL); } else { @@ -38311,12 +38402,12 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) { DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { DUK_ASSERT(js_ctx->recursion_depth >= 1); - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); } } DUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET); - duk__enc_objarr_exit(js_ctx, &entry_top); + duk__json_enc_objarr_exit(js_ctx, &entry_top); DUK_ASSERT_TOP(thr, entry_top); } @@ -38325,14 +38416,14 @@ DUK_LOCAL void duk__enc_array(duk_json_enc_ctx *js_ctx) { * * Stack policy: [ ... key ] -> [ ... ] */ -DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) { +DUK_LOCAL duk_bool_t duk__json_enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_holder) { duk_hthread *thr = js_ctx->thr; duk_tval *tv; duk_tval *tv_holder; duk_tval *tv_key; duk_small_int_t c; - DUK_DDD(DUK_DDDPRINT("duk__enc_value: idx_holder=%ld, holder=%!T, key=%!T", + DUK_DDD(DUK_DDDPRINT("duk__json_enc_value: idx_holder=%ld, holder=%!T, key=%!T", (long) idx_holder, (duk_tval *) duk_get_tval(thr, idx_holder), (duk_tval *) duk_get_tval(thr, -1))); @@ -38402,7 +38493,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold duk_hbufobj *h_bufobj; h_bufobj = (duk_hbufobj *) h; DUK_HBUFOBJ_ASSERT_VALID(h_bufobj); - duk__enc_bufobj(js_ctx, h_bufobj); + duk__json_enc_bufobj(js_ctx, h_bufobj); goto pop2_emitted; } /* Otherwise bufferobjects get serialized as normal objects. */ @@ -38498,7 +38589,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold #if defined(DUK_USE_JX) || defined(DUK_USE_JC) /* When JX/JC not in use, the type mask above will avoid this case if needed. */ case DUK_TAG_POINTER: { - duk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv)); + duk__json_enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv)); break; } #endif /* DUK_USE_JX || DUK_USE_JC */ @@ -38508,7 +38599,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { goto pop2_undef; } - duk__enc_quote_string(js_ctx, h); + duk__json_enc_quote_string(js_ctx, h); break; } case DUK_TAG_OBJECT: { @@ -38521,9 +38612,9 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold DUK_ASSERT(!DUK_HOBJECT_IS_CALLABLE(h)); if (duk_js_isarray_hobject(h)) { - duk__enc_array(js_ctx); + duk__json_enc_array(js_ctx); } else { - duk__enc_object(js_ctx); + duk__json_enc_object(js_ctx); } break; } @@ -38536,7 +38627,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold case DUK_TAG_BUFFER: { #if defined(DUK_USE_JX) || defined(DUK_USE_JC) if (js_ctx->flag_ext_custom_or_compatible) { - duk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv)); + duk__json_enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv)); break; } #endif @@ -38545,7 +38636,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold * to handle realloc side effects correctly. */ duk_to_object(thr, -1); - duk__enc_object(js_ctx); + duk__json_enc_object(js_ctx); break; } case DUK_TAG_LIGHTFUNC: { @@ -38564,7 +38655,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold /* Number serialization has a significant impact relative to * other fast path code, so careful fast path for fastints. */ - duk__enc_fastint_tval(js_ctx, tv); + duk__json_enc_fastint_tval(js_ctx, tv); break; #endif default: { @@ -38574,7 +38665,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold /* XXX: A fast path for usual integers would be useful when * fastint support is not enabled. */ - duk__enc_double(js_ctx); + duk__json_enc_double(js_ctx); break; } } @@ -38591,7 +38682,7 @@ DUK_LOCAL duk_bool_t duk__enc_value(duk_json_enc_ctx *js_ctx, duk_idx_t idx_hold } /* E5 Section 15.12.3, main algorithm, step 4.b.ii steps 1-4. */ -DUK_LOCAL duk_bool_t duk__enc_allow_into_proplist(duk_tval *tv) { +DUK_LOCAL duk_bool_t duk__json_enc_allow_into_proplist(duk_tval *tv) { duk_small_int_t c; /* XXX: some kind of external internal type checker? @@ -38674,7 +38765,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du if (DUK_UNLIKELY(DUK_HSTRING_HAS_SYMBOL(h))) { goto emit_undefined; } - duk__enc_quote_string(js_ctx, h); + duk__json_enc_quote_string(js_ctx, h); break; } case DUK_TAG_OBJECT: { @@ -38719,7 +38810,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du DUK_ASSERT(js_ctx->recursion_depth <= js_ctx->recursion_limit); if (js_ctx->recursion_depth >= js_ctx->recursion_limit) { DUK_DD(DUK_DDPRINT("fast path recursion limit")); - DUK_ERROR_RANGE(js_ctx->thr, DUK_STR_JSONDEC_RECLIMIT); + DUK_ERROR_RANGE(js_ctx->thr, DUK_STR_DEC_RECLIMIT); DUK_WO_NORETURN(return 0;); } @@ -38846,11 +38937,11 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du prev_size = DUK_BW_GET_SIZE(js_ctx->thr, &js_ctx->bw); if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); - duk__enc_key_autoquote(js_ctx, k); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth); + duk__json_enc_key_autoquote(js_ctx, k); DUK__EMIT_2(js_ctx, DUK_ASC_COLON, DUK_ASC_SPACE); } else { - duk__enc_key_autoquote(js_ctx, k); + duk__json_enc_key_autoquote(js_ctx, k); DUK__EMIT_1(js_ctx, DUK_ASC_COLON); } @@ -38873,7 +38964,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { DUK_ASSERT(js_ctx->recursion_depth >= 1); - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); } } DUK__EMIT_1(js_ctx, DUK_ASC_RCURLY); @@ -38901,7 +38992,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du duk_bool_t has_inherited; if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth); } if (DUK_LIKELY(i < asize)) { @@ -38950,7 +39041,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du DUK__UNEMIT_1(js_ctx); /* eat trailing comma */ if (DUK_UNLIKELY(js_ctx->h_gap != NULL)) { DUK_ASSERT(js_ctx->recursion_depth >= 1); - duk__enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); + duk__json_enc_newline_indent(js_ctx, js_ctx->recursion_depth - 1U); } } DUK__EMIT_1(js_ctx, DUK_ASC_RBRACKET); @@ -38992,7 +39083,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du DUK__EMIT_STRIDX(js_ctx, js_ctx->stridx_custom_function); #if defined(DUK_USE_BUFFEROBJECT_SUPPORT) } else if (c_bit & c_bufobj) { - duk__enc_bufobj(js_ctx, (duk_hbufobj *) obj); + duk__json_enc_bufobj(js_ctx, (duk_hbufobj *) obj); #endif #endif } else if (c_bit & c_abort) { @@ -39032,7 +39123,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du #if defined(DUK_USE_JX) || defined(DUK_USE_JC) if (js_ctx->flag_ext_custom_or_compatible) { - duk__enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv)); + duk__json_enc_buffer_jx_jc(js_ctx, DUK_TVAL_GET_BUFFER(tv)); break; } #endif @@ -39040,13 +39131,13 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du /* Plain buffers mimic Uint8Arrays, and have enumerable index * properties. */ - duk__enc_buffer_json_fastpath(js_ctx, DUK_TVAL_GET_BUFFER(tv)); + duk__json_enc_buffer_json_fastpath(js_ctx, DUK_TVAL_GET_BUFFER(tv)); break; } case DUK_TAG_POINTER: { #if defined(DUK_USE_JX) || defined(DUK_USE_JC) if (js_ctx->flag_ext_custom_or_compatible) { - duk__enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv)); + duk__json_enc_pointer(js_ctx, DUK_TVAL_GET_POINTER(tv)); break; } else { goto emit_undefined; @@ -39068,7 +39159,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du /* Number serialization has a significant impact relative to * other fast path code, so careful fast path for fastints. */ - duk__enc_fastint_tval(js_ctx, tv); + duk__json_enc_fastint_tval(js_ctx, tv); break; } #endif @@ -39081,7 +39172,7 @@ DUK_LOCAL duk_bool_t duk__json_stringify_fast_value(duk_json_enc_ctx *js_ctx, du /* XXX: Stack discipline is annoying, could be changed in numconv. */ duk_push_tval(js_ctx->thr, tv); - duk__enc_double(js_ctx); + duk__json_enc_double(js_ctx); duk_pop(js_ctx->thr); #if 0 @@ -39193,14 +39284,15 @@ void duk_bi_json_parse_helper(duk_hthread *thr, DUK_HSTRING_GET_BYTELEN(h_text); DUK_ASSERT(*(js_ctx->p_end) == 0x00); - duk__dec_value(js_ctx); /* -> [ ... value ] */ + duk__json_dec_value(js_ctx); /* -> [ ... value ] */ + DUK_ASSERT(js_ctx->recursion_depth == 0); - /* Trailing whitespace has been eaten by duk__dec_value(), so if + /* Trailing whitespace has been eaten by duk__json_dec_value(), so if * we're not at end of input here, it's a SyntaxError. */ if (js_ctx->p != js_ctx->p_end) { - duk__dec_syntax_error(js_ctx); + duk__json_dec_syntax_error(js_ctx); } if (duk_is_callable(thr, idx_reviver)) { @@ -39218,7 +39310,9 @@ void duk_bi_json_parse_helper(duk_hthread *thr, (duk_tval *) duk_get_tval(thr, -2), (duk_tval *) duk_get_tval(thr, -1))); - duk__dec_reviver_walk(js_ctx); /* [ ... val root "" ] -> [ ... val val' ] */ + DUK_ASSERT(js_ctx->recursion_depth == 0); + duk__json_dec_reviver_walk(js_ctx); /* [ ... val root "" ] -> [ ... val val' ] */ + DUK_ASSERT(js_ctx->recursion_depth == 0); duk_remove_m2(thr); /* -> [ ... val' ] */ } else { DUK_DDD(DUK_DDDPRINT("reviver does not exist or is not callable: %!T", @@ -39366,14 +39460,14 @@ void duk_bi_json_stringify_helper(duk_hthread *thr, duk_uarridx_t plist_idx = 0; duk_small_uint_t enum_flags; - js_ctx->idx_proplist = duk_push_array(thr); /* XXX: array internal? */ + js_ctx->idx_proplist = duk_push_bare_array(thr); enum_flags = DUK_ENUM_ARRAY_INDICES_ONLY | DUK_ENUM_SORT_ARRAY_INDICES; /* expensive flag */ duk_enum(thr, idx_replacer, enum_flags); while (duk_next(thr, -1 /*enum_index*/, 1 /*get_value*/)) { /* [ ... proplist enum_obj key val ] */ - if (duk__enc_allow_into_proplist(duk_get_tval(thr, -1))) { + if (duk__json_enc_allow_into_proplist(duk_get_tval(thr, -1))) { /* XXX: duplicates should be eliminated here */ DUK_DDD(DUK_DDDPRINT("proplist enum: key=%!T, val=%!T --> accept", (duk_tval *) duk_get_tval(thr, -2), @@ -39533,7 +39627,7 @@ void duk_bi_json_stringify_helper(duk_hthread *thr, js_ctx->recursion_limit = DUK_USE_JSON_ENC_RECLIMIT; DUK_ASSERT(js_ctx->recursion_depth == 0); - if (DUK_UNLIKELY(duk__enc_value(js_ctx, idx_holder) == 0)) { /* [ ... holder key ] -> [ ... holder ] */ + if (DUK_UNLIKELY(duk__json_enc_value(js_ctx, idx_holder) == 0)) { /* [ ... holder key ] -> [ ... holder ] */ /* Result is undefined. */ duk_push_undefined(thr); } else { @@ -41436,7 +41530,9 @@ DUK_INTERNAL void duk_proxy_ownkeys_postprocess(duk_hthread *thr, duk_hobject *h } /* [ obj trap_result res_arr propname ] */ - duk_put_prop_index(thr, -2, idx++); + duk_push_uarridx(thr, idx++); + duk_insert(thr, -2); + duk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WEC); continue; skip_key: @@ -42461,6 +42557,7 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) { #endif /* DUK_USE_REGEXP_SUPPORT */ const duk_uint8_t *p_start, *p_end, *p; /* input string scan */ const duk_uint8_t *q_start; /* match string */ + duk_size_t p_blen; duk_size_t q_blen; #if defined(DUK_USE_REGEXP_SUPPORT) @@ -42469,13 +42566,19 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_replace(duk_hthread *thr) { p_start = DUK_HSTRING_GET_DATA(h_input); p_end = p_start + DUK_HSTRING_GET_BYTELEN(h_input); + p_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_input); p = p_start; h_search = duk_known_hstring(thr, 0); q_start = DUK_HSTRING_GET_DATA(h_search); q_blen = (duk_size_t) DUK_HSTRING_GET_BYTELEN(h_search); + if (q_blen > p_blen) { + break; /* no match */ + } + p_end -= q_blen; /* ensure full memcmp() fits in while */ + DUK_ASSERT(p_end >= p); match_start_coff = 0; @@ -43290,44 +43393,65 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_locale_compare(duk_hthread *thr) #if defined(DUK_USE_ES6) DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread *thr) { duk_int_t magic; - duk_hstring *h; + duk_hstring *h_target; + duk_size_t blen_target; duk_hstring *h_search; duk_size_t blen_search; - const duk_uint8_t *p_cmp_start; - duk_bool_t result; + duk_int_t off; + duk_bool_t result = 0; + duk_size_t blen_left; - h = duk_push_this_coercible_to_string(thr); - DUK_ASSERT(h != NULL); + /* Because string byte lengths are in [0,DUK_INT_MAX] it's safe to + * subtract two string lengths without overflow. + */ + DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX); + + h_target = duk_push_this_coercible_to_string(thr); + DUK_ASSERT(h_target != NULL); h_search = duk__str_tostring_notregexp(thr, 0); DUK_ASSERT(h_search != NULL); magic = duk_get_current_magic(thr); - p_cmp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h); + /* Careful to avoid pointer overflows in the matching logic. */ + + blen_target = DUK_HSTRING_GET_BYTELEN(h_target); blen_search = DUK_HSTRING_GET_BYTELEN(h_search); +#if 0 + /* If search string is longer than the target string, we can + * never match. Could check explicitly, but should be handled + * correctly below. + */ + if (blen_search > blen_target) { + goto finish; + } +#endif + + off = 0; if (duk_is_undefined(thr, 1)) { if (magic) { - p_cmp_start = p_cmp_start + DUK_HSTRING_GET_BYTELEN(h) - blen_search; + off = (duk_int_t) blen_target - (duk_int_t) blen_search; } else { - /* p_cmp_start already OK */ + DUK_ASSERT(off == 0); } } else { duk_int_t len; duk_int_t pos; DUK_ASSERT(DUK_HSTRING_MAX_BYTELEN <= DUK_INT_MAX); - len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h); + len = (duk_int_t) DUK_HSTRING_GET_CHARLEN(h_target); pos = duk_to_int_clamped(thr, 1, 0, len); DUK_ASSERT(pos >= 0 && pos <= len); + off = (duk_int_t) duk_heap_strcache_offset_char2byte(thr, h_target, (duk_uint_fast32_t) pos); if (magic) { - p_cmp_start -= blen_search; /* Conceptually subtracted last, but do already here. */ + off -= (duk_int_t) blen_search; } - DUK_ASSERT(pos >= 0 && pos <= len); - - p_cmp_start += duk_heap_strcache_offset_char2byte(thr, h, (duk_uint_fast32_t) pos); + } + if (off < 0 || off > (duk_int_t) blen_target) { + goto finish; } /* The main comparison can be done using a memcmp() rather than @@ -43337,16 +43461,18 @@ DUK_INTERNAL duk_ret_t duk_bi_string_prototype_startswith_endswith(duk_hthread * * comparison range. */ - result = 0; - if (p_cmp_start >= DUK_HSTRING_GET_DATA(h) && - (duk_size_t) (p_cmp_start - (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h)) + blen_search <= DUK_HSTRING_GET_BYTELEN(h)) { - if (duk_memcmp((const void *) p_cmp_start, - (const void *) DUK_HSTRING_GET_DATA(h_search), - (size_t) blen_search) == 0) { + DUK_ASSERT(off >= 0); + DUK_ASSERT((duk_size_t) off <= blen_target); + blen_left = blen_target - (duk_size_t) off; + if (blen_left >= blen_search) { + const duk_uint8_t *p_cmp_start = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_target) + off; + const duk_uint8_t *p_search = (const duk_uint8_t *) DUK_HSTRING_GET_DATA(h_search); + if (duk_memcmp_unsafe((const void *) p_cmp_start, (const void *) p_search, (size_t) blen_search) == 0) { result = 1; } } + finish: duk_push_boolean(thr, result); return 1; } @@ -52244,6 +52370,7 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags #if defined(DUK_USE_VOLUNTARY_GC) duk_size_t tmp; #endif + duk_bool_t entry_creating_error; DUK_STATS_INC(heap, stats_ms_try_count); #if defined(DUK_USE_DEBUG) @@ -52314,6 +52441,8 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags DUK_ASSERT(heap->ms_running == 0); heap->ms_prevent_count = 1; heap->ms_running = 1; + entry_creating_error = heap->creating_error; + heap->creating_error = 0; /* * Free activation/catcher freelists on every mark-and-sweep for now. @@ -52444,6 +52573,7 @@ DUK_INTERNAL void duk_heap_mark_and_sweep(duk_heap *heap, duk_small_uint_t flags DUK_ASSERT(heap->ms_running == 1); heap->ms_prevent_count = 0; heap->ms_running = 0; + heap->creating_error = entry_creating_error; /* for nested error handling, see GH-2278 */ /* * Assertions after @@ -55979,6 +56109,13 @@ DUK_LOCAL void duk__sort_enum_keys_es6(duk_hthread *thr, duk_hobject *h_obj, duk keys[idx_insert] = h_curr; } } + + /* Entry part has been reordered now with no side effects. + * If the object has a hash part, it will now be incorrect + * and we need to rehash. Do that by forcing a resize to + * the current size. + */ + duk_hobject_resize_entrypart(thr, h_obj, DUK_HOBJECT_GET_ESIZE(h_obj)); } /* @@ -74164,10 +74301,13 @@ DUK_LOCAL void duk__parse_stmt(duk_compiler_ctx *comp_ctx, duk_ivalue *res, duk_ */ test_func_decl = allow_source_elem; #if defined(DUK_USE_NONSTD_FUNC_STMT) - /* Lenient: allow function declarations outside top level in - * non-strict mode but reject them in strict mode. + /* Lenient: allow function declarations outside top level in both + * strict and non-strict modes. However, don't allow labelled + * function declarations in strict mode. */ - test_func_decl = test_func_decl || !comp_ctx->curr_func.is_strict; + test_func_decl = test_func_decl || + !comp_ctx->curr_func.is_strict || + label_id < 0; #endif /* DUK_USE_NONSTD_FUNC_STMT */ /* Strict: never allow function declarations outside top level. */ if (test_func_decl) { @@ -77196,17 +77336,21 @@ DUK_LOCAL duk_small_uint_t duk__handle_longjmp(duk_hthread *thr, duk_activation DUK_DD(DUK_DDPRINT("-> yield an error, converted to a throw in the resumer, propagate")); goto check_longjmp; } else { - duk_hthread_activation_unwind_norz(resumer); - duk__handle_yield(thr, resumer, &thr->heap->lj.value1); + /* When handling the yield, the last reference to + * 'thr' may disappear. + */ + DUK_GC_TORTURE(resumer->heap); + duk_hthread_activation_unwind_norz(resumer); + DUK_GC_TORTURE(resumer->heap); thr->state = DUK_HTHREAD_STATE_YIELDED; thr->resumer = NULL; DUK_HTHREAD_DECREF_NORZ(thr, resumer); resumer->state = DUK_HTHREAD_STATE_RUNNING; DUK_HEAP_SWITCH_THREAD(thr->heap, resumer); -#if 0 - thr = resumer; /* not needed, as we exit right away */ -#endif + duk__handle_yield(thr, resumer, &thr->heap->lj.value1); + thr = resumer; + DUK_GC_TORTURE(resumer->heap); DUK_DD(DUK_DDPRINT("-> yield a value, restart execution in resumer")); retval = DUK__LONGJMP_RESTART; @@ -83909,6 +84053,7 @@ void duk__putvar_helper(duk_hthread *thr, duk_tval *val, duk_bool_t strict) { duk__id_lookup_result ref; + duk_tval tv_tmp_val; duk_tval tv_tmp_obj; duk_tval tv_tmp_key; duk_bool_t parents; @@ -83926,10 +84071,13 @@ void duk__putvar_helper(duk_hthread *thr, DUK_ASSERT(val != NULL); /* env and act may be NULL */ - DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env); - DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name); + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(env); + DUK_ASSERT_REFCOUNT_NONZERO_HEAPHDR(name); DUK_ASSERT_REFCOUNT_NONZERO_TVAL(val); + DUK_TVAL_SET_TVAL(&tv_tmp_val, val); /* Stabilize. */ + val = NULL; + /* * In strict mode E5 protects 'eval' and 'arguments' from being * assigned to (or even declared anywhere). Attempt to do so @@ -83961,7 +84109,7 @@ void duk__putvar_helper(duk_hthread *thr, tv_val = ref.value; DUK_ASSERT(tv_val != NULL); - DUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, val); /* side effects */ + DUK_TVAL_SET_TVAL_UPDREF(thr, tv_val, &tv_tmp_val); /* side effects */ /* ref.value invalidated here */ } else { @@ -83969,7 +84117,7 @@ void duk__putvar_helper(duk_hthread *thr, DUK_TVAL_SET_OBJECT(&tv_tmp_obj, ref.holder); DUK_TVAL_SET_STRING(&tv_tmp_key, name); - (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, strict); + (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, &tv_tmp_val, strict); /* ref.value invalidated here */ } @@ -83994,7 +84142,7 @@ void duk__putvar_helper(duk_hthread *thr, DUK_TVAL_SET_OBJECT(&tv_tmp_obj, thr->builtins[DUK_BIDX_GLOBAL]); DUK_TVAL_SET_STRING(&tv_tmp_key, name); - (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, val, 0); /* 0 = no throw */ + (void) duk_hobject_putprop(thr, &tv_tmp_obj, &tv_tmp_key, &tv_tmp_val, 0); /* 0 = no throw */ /* NB: 'val' may be invalidated here because put_value may realloc valstack, * caller beware. @@ -91415,10 +91563,12 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_ * as 'undefined'. The same is done when saved[] pointers are insane * (this should, of course, never happen in practice). */ + duk_push_uarridx(thr, (duk_uarridx_t) (i / 2)); + if (re_ctx.saved[i] && re_ctx.saved[i + 1] && re_ctx.saved[i + 1] >= re_ctx.saved[i]) { duk_push_lstring(thr, (const char *) re_ctx.saved[i], - (duk_size_t) (re_ctx.saved[i+1] - re_ctx.saved[i])); + (duk_size_t) (re_ctx.saved[i + 1] - re_ctx.saved[i])); if (i == 0) { /* Assumes that saved[0] and saved[1] are always * set by regexp bytecode (if not, char_end_offset @@ -91431,8 +91581,8 @@ DUK_LOCAL void duk__regexp_match_helper(duk_hthread *thr, duk_small_int_t force_ duk_push_undefined(thr); } - /* [ ... re_obj input bc saved_buf res_obj val ] */ - duk_put_prop_index(thr, -2, (duk_uarridx_t) (i / 2)); + /* [ ... re_obj input bc saved_buf res_obj idx val ] */ + duk_def_prop(thr, -3, DUK_DEFPROP_HAVE_VALUE | DUK_DEFPROP_SET_WEC); } /* [ ... re_obj input bc saved_buf res_obj ] */ diff --git a/src/modules/app_jsdt/duktape.h b/src/modules/app_jsdt/duktape.h index 7850c996f..e5b46c234 100644 --- a/src/modules/app_jsdt/duktape.h +++ b/src/modules/app_jsdt/duktape.h @@ -1,13 +1,13 @@ /* - * Duktape public API for Duktape 2.5.0. + * Duktape public API for Duktape 2.6.0. * * See the API reference for documentation on call semantics. The exposed, * supported API is between the "BEGIN PUBLIC API" and "END PUBLIC API" * comments. Other parts of the header are Duktape internal and related to * e.g. platform/compiler/feature detection. * - * Git commit 6001888049cb42656f8649db020e804bcdeca6a7 (v2.5.0). - * Git branch master. + * Git commit fffa346eff06a8764b02c31d4336f63a773a95c3 (v2.6.0). + * Git branch v2-maintenance. * * See Duktape AUTHORS.rst and LICENSE.txt for copyright and * licensing information. @@ -176,16 +176,16 @@ * development snapshots have 99 for patch level (e.g. 0.10.99 would be a * development version after 0.10.0 but before the next official release). */ -#define DUK_VERSION 20500L +#define DUK_VERSION 20600L /* Git commit, describe, and branch for Duktape build. Useful for * non-official snapshot builds so that application code can easily log * which Duktape snapshot was used. Not available in the ECMAScript * environment. */ -#define DUK_GIT_COMMIT "6001888049cb42656f8649db020e804bcdeca6a7" -#define DUK_GIT_DESCRIBE "v2.5.0" -#define DUK_GIT_BRANCH "master" +#define DUK_GIT_COMMIT "fffa346eff06a8764b02c31d4336f63a773a95c3" +#define DUK_GIT_DESCRIBE "v2.6.0" +#define DUK_GIT_BRANCH "v2-maintenance" /* External duk_config.h provides platform/compiler/OS dependent * typedefs and macros, and DUK_USE_xxx config options so that diff --git a/src/modules/app_python3/app_python3_mod.c b/src/modules/app_python3/app_python3_mod.c index 502a6d540..0ce93b71c 100644 --- a/src/modules/app_python3/app_python3_mod.c +++ b/src/modules/app_python3/app_python3_mod.c @@ -346,7 +346,9 @@ int apy_load_script(void) } Py_Initialize(); +#if PY_VERSION_HEX < 0x03070000 PyEval_InitThreads(); +#endif myThreadState = PyThreadState_Get(); PY_GIL_ENSURE; diff --git a/src/modules/auth_diameter/message.c b/src/modules/auth_diameter/message.c index ad81816a4..2dcb80de1 100644 --- a/src/modules/auth_diameter/message.c +++ b/src/modules/auth_diameter/message.c @@ -185,7 +185,7 @@ AAAMessage* AAATranslateMessage( unsigned char* source, unsigned int sourceLen, int attach_buf) { unsigned char *ptr; - AAAMessage *msg; + AAAMessage *msg = NULL; unsigned char version; unsigned int msg_len; AAA_AVP *avp; @@ -310,7 +310,9 @@ AAAMessage* AAATranslateMessage( unsigned char* source, unsigned int sourceLen, return msg; error: LM_ERR(" message conversion dropped!!\n"); - AAAFreeMessage(&msg); + if (msg) { + AAAFreeMessage(&msg); + } return 0; } diff --git a/src/modules/avp/avp.xml b/src/modules/avp/avp.xml index 93fdea7fc..fa47e88cb 100644 --- a/src/modules/avp/avp.xml +++ b/src/modules/avp/avp.xml @@ -168,7 +168,7 @@ The attr_equals() function checks whether the attribute identified by the argument attribute - exists and its value is identical the the value given by the + exists and its value is identical the value given by the argument value. If so, it returns true and false otherwise. diff --git a/src/modules/carrierroute/README b/src/modules/carrierroute/README index 8f1b4a053..1dfc46d86 100644 --- a/src/modules/carrierroute/README +++ b/src/modules/carrierroute/README @@ -1262,7 +1262,7 @@ modparam("carrierroute", "carrierfailureroute_domain_col", "domain") 19. carrierfailureroute_scan_prefix_col (string) - Name of column contains the the scan prefixes. Scan prefixes define the + Name of column contains the scan prefixes. Scan prefixes define the matching portion of a phone number, e.g. we have the scan prefixes 49721 and 49, the called number is 49721913740, it matches 49721, because the longest match is taken. If no prefix matches, the number is diff --git a/src/modules/carrierroute/doc/carrierroute_db.xml b/src/modules/carrierroute/doc/carrierroute_db.xml index cc88b1988..f755d08a4 100644 --- a/src/modules/carrierroute/doc/carrierroute_db.xml +++ b/src/modules/carrierroute/doc/carrierroute_db.xml @@ -273,7 +273,7 @@ modparam("carrierroute", "carrierfailureroute_domain_col", "domain")
<varname>carrierfailureroute_scan_prefix_col</varname> (string) - Name of column contains the the scan prefixes. Scan prefixes define the matching + Name of column contains the scan prefixes. Scan prefixes define the matching portion of a phone number, e.g. we have the scan prefixes 49721 and 49, the called number is 49721913740, it matches 49721, because the longest match is taken. If no prefix matches, the number is not failure routed. To prevent this, an empty prefix value of diff --git a/src/modules/cfgt/cfgt_int.c b/src/modules/cfgt/cfgt_int.c index c47a1cecc..7b0c99128 100644 --- a/src/modules/cfgt/cfgt_int.c +++ b/src/modules/cfgt/cfgt_int.c @@ -429,6 +429,8 @@ void cfgt_save_node(cfgt_node_p node) } fclose(fp); node->jdoc.free_fn(dest.s); + LM_INFO("*** node uuid:[%.*s] id:[%d] saved ***\n", + STR_FMT(&node->uuid), node->msgid); } else { LM_ERR("Can't open file [%s] to write\n", dest.s); pkg_free(dest.s); @@ -767,7 +769,7 @@ int cfgt_msgin(sr_event_param_t *evp) int cfgt_pre(struct sip_msg *msg, unsigned int flags, void *bar) { str unknown = {"unknown", 7}; - int get_hdr_result = 0; + int get_hdr_result = 0, res; if(_cfgt_node) { if(_cfgt_node->msgid == 0) { @@ -786,7 +788,10 @@ int cfgt_pre(struct sip_msg *msg, unsigned int flags, void *bar) } pkg_str_dup(&_cfgt_node->uuid, &unknown); } - return _cfgt_get_uuid_id(_cfgt_node); + res = _cfgt_get_uuid_id(_cfgt_node); + LM_INFO("*** node uuid:[%.*s] id:[%d] created ***\n", + STR_FMT(&_cfgt_node->uuid), _cfgt_node->msgid); + return res; } else { LM_DBG("_cfgt_node->uuid:[%.*s]\n", _cfgt_node->uuid.len, _cfgt_node->uuid.s); diff --git a/src/modules/counters/counters.c b/src/modules/counters/counters.c index 5ddbac3e6..696bc0be3 100644 --- a/src/modules/counters/counters.c +++ b/src/modules/counters/counters.c @@ -132,7 +132,7 @@ struct module_exports exports = { -/** parse the the script_counter modparam. +/** parse the script_counter modparam. * Format: [grp.]name[( |:)desc] * E.g.: * "name" => new counter: *cnt_script_grp."name" @@ -554,4 +554,4 @@ int mod_register(char *path, int *dlflags, void *p1, void *p2) return 0; } -/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ \ No newline at end of file +/* vi: set ts=4 sw=4 tw=79:ai:cindent: */ diff --git a/src/modules/cplc/README b/src/modules/cplc/README index 442a84baf..f5b3a9b05 100644 --- a/src/modules/cplc/README +++ b/src/modules/cplc/README @@ -228,8 +228,8 @@ modparam("cpl-c","domain_column","domain") 3.5. cpl_xml_column (string) - Indicates the name of the column used for storing the the XML version - of the cpl script. + Indicates the name of the column used for storing the XML version of + the cpl script. Default value is “cpl_xml”. @@ -240,8 +240,8 @@ modparam("cpl-c","cpl_xml_column","cpl_xml") 3.6. cpl_bin_column (string) - Indicates the name of the column used for storing the the binary - version of the cpl script (compiled version). + Indicates the name of the column used for storing the binary version of + the cpl script (compiled version). Default value is “cpl_bin”. diff --git a/src/modules/cplc/doc/cplc_admin.xml b/src/modules/cplc/doc/cplc_admin.xml index 0c9f15b62..d83b9271a 100644 --- a/src/modules/cplc/doc/cplc_admin.xml +++ b/src/modules/cplc/doc/cplc_admin.xml @@ -175,7 +175,7 @@ modparam("cpl-c","domain_column","domain") <varname>cpl_xml_column</varname> (string) Indicates the name of the column used for storing the - the XML version of the cpl script. + XML version of the cpl script. @@ -195,7 +195,7 @@ modparam("cpl-c","cpl_xml_column","cpl_xml") <varname>cpl_bin_column</varname> (string) Indicates the name of the column used for storing the - the binary version of the cpl script (compiled version). + binary version of the cpl script (compiled version). diff --git a/src/modules/crypto/crypto_aes.c b/src/modules/crypto/crypto_aes.c index 8b80d62a2..f9aacf541 100644 --- a/src/modules/crypto/crypto_aes.c +++ b/src/modules/crypto/crypto_aes.c @@ -76,7 +76,9 @@ int crypto_aes_init(unsigned char *key_data, int key_data_len, { int i, nrounds = 5; int x; - unsigned char key[32], iv[32]; + unsigned char key[32], iv[32]; /* IV is only 16 bytes, but makes it easier */ + memset(key, 0, sizeof(key)); + memset(iv, 0, sizeof(iv)); /* * Gen key & IV for AES 256 CBC mode. A SHA1 digest is used to hash diff --git a/src/modules/ctl/binrpc_run.c b/src/modules/ctl/binrpc_run.c index 064b32b48..1ce980055 100644 --- a/src/modules/ctl/binrpc_run.c +++ b/src/modules/ctl/binrpc_run.c @@ -627,10 +627,17 @@ int process_rpc_req(unsigned char* buf, int size, int* bytes_needed, rpc_export_t* rpc_e; struct binrpc_ctx f_ctx; struct binrpc_parse_ctx* ctx; - + + if(ksr_shutdown_phase()) { + /* during shutdown - no more RPC command handling */ + LM_DBG("shutdown phase - skipping rpc command\n"); + return -1; + } + if (sizeparent->name); goto close_connection; } + LM_INFO("bytes read: %d\n", bytes_read); r->end+=bytes_read; if (bytes_read && (bytes_readbytes_to_go)){ r->bytes_to_go-=bytes_read; @@ -514,6 +515,7 @@ again: /* error while processing the packet => close the connection */ goto close_connection; } + LM_INFO("bytes processed: %d\n", bytes_processed); r->proc+=bytes_processed; r->bytes_to_go=bytes_needed; if (bytes_needed>0){ diff --git a/src/modules/db_mongodb/README b/src/modules/db_mongodb/README index 90c722c54..1d94f7f7e 100644 --- a/src/modules/db_mongodb/README +++ b/src/modules/db_mongodb/README @@ -100,7 +100,7 @@ Chapter 1. Admin Guide 5. Usage - Load the module and set the the DB URL for specific modules to: + Load the module and set the DB URL for specific modules to: mongodb://username:password@host:port/database. Username, password and port are optional. diff --git a/src/modules/db_mongodb/doc/db_mongodb_admin.xml b/src/modules/db_mongodb/doc/db_mongodb_admin.xml index a7723bec5..00cf7a59e 100644 --- a/src/modules/db_mongodb/doc/db_mongodb_admin.xml +++ b/src/modules/db_mongodb/doc/db_mongodb_admin.xml @@ -96,7 +96,7 @@
Usage - Load the module and set the the DB URL for specific modules to: + Load the module and set the DB URL for specific modules to: mongodb://username:password@host:port/database. Username, password and port are optional. diff --git a/src/modules/dialog/dialog.c b/src/modules/dialog/dialog.c index 61e4b0cbc..7e5b00425 100644 --- a/src/modules/dialog/dialog.c +++ b/src/modules/dialog/dialog.c @@ -2942,7 +2942,7 @@ static void rpc_dlg_list_match_ex(rpc_t *rpc, void *c, int with_context) vkey = 1; } else if(mkey.len==4 && strncmp(mkey.s, "turi", mkey.len)==0) { vkey = 2; - } else if(mkey.len==5 && strncmp(mkey.s, "callid", mkey.len)==0) { + } else if(mkey.len==6 && strncmp(mkey.s, "callid", mkey.len)==0) { vkey = 3; } else { LM_ERR("invalid key %.*s\n", mkey.len, mkey.s); diff --git a/src/modules/dialog/dlg_cseq.c b/src/modules/dialog/dlg_cseq.c index fd993b076..70b2b43c2 100644 --- a/src/modules/dialog/dlg_cseq.c +++ b/src/modules/dialog/dlg_cseq.c @@ -381,7 +381,20 @@ int dlg_cseq_msg_sent(sr_event_param_t *evp) goto done; } - LM_DBG("traking cseq updates\n"); + if(!IS_SIP(&msg)) { + /* nothing to do for non-sip requests */ + goto done; + } + + if(get_to(&msg)->tag_value.len<=0) { + /* intial request - handle only INVITEs, ACKs and CANCELs */ + if(!(msg.first_line.u.request.method_value + & (METHOD_INVITE|METHOD_ACK|METHOD_CANCEL))) { + goto done; + } + } + + LM_DBG("tracking cseq updates\n"); via = (struct via_body*)msg.h_via1->parsed; if(via->branch==NULL || via->branch->value.len<=0) { diff --git a/src/modules/dialog/dlg_dmq.c b/src/modules/dialog/dlg_dmq.c index a5628f485..38dc105fb 100644 --- a/src/modules/dialog/dlg_dmq.c +++ b/src/modules/dialog/dlg_dmq.c @@ -534,11 +534,11 @@ int dlg_dmq_replicate_action(dlg_dmq_action_t action, dlg_cell_t* dlg, if (dlg->vars != NULL) { srjson_t *pj = NULL; pj = srjson_CreateObject(&jdoc); - for(var=dlg->vars ; var ; var=var->next) { + for(var=dlg->vars ; var ; var=var->next) { srjson_AddStrToObject(&jdoc, pj, var->key.s, var->value.s, var->value.len); - } - srjson_AddItemToObject(&jdoc, jdoc.root, "vars", pj); + } + srjson_AddItemToObject(&jdoc, jdoc.root, "vars", pj); } if (dlg->profile_links) { @@ -646,22 +646,22 @@ error: int dmq_send_all_dlgs(dmq_node_t* dmq_node) { int index; - dlg_entry_t entry; + dlg_entry_t *entry; dlg_cell_t *dlg; LM_DBG("sending all dialogs \n"); for(index = 0; index< d_table->size; index++){ /* lock the whole entry */ - entry = (d_table->entries)[index]; - dlg_lock( d_table, &entry); + entry = &d_table->entries[index]; + dlg_lock( d_table, entry); - for(dlg = entry.first; dlg != NULL; dlg = dlg->next){ - dlg->dflags |= DLG_FLAG_CHANGED_PROF; - dlg_dmq_replicate_action(DLG_DMQ_UPDATE, dlg, 0, dmq_node); + for(dlg = entry->first; dlg != NULL; dlg = dlg->next){ + dlg->dflags |= DLG_FLAG_CHANGED_PROF; + dlg_dmq_replicate_action(DLG_DMQ_UPDATE, dlg, 0, dmq_node); } - dlg_unlock( d_table, &entry); + dlg_unlock( d_table, entry); } return 0; @@ -672,7 +672,7 @@ int dmq_send_all_dlgs(dmq_node_t* dmq_node) { * @brief dmq response callback */ int dlg_dmq_resp_callback_f(struct sip_msg* msg, int code, - dmq_node_t* node, void* param) + dmq_node_t* node, void* param) { LM_DBG("dmq response callback triggered [%p %d %p]\n", msg, code, param); return 0; diff --git a/src/modules/dialog/dlg_handlers.c b/src/modules/dialog/dlg_handlers.c index 7cf6b7ba7..3f8adefb7 100644 --- a/src/modules/dialog/dlg_handlers.c +++ b/src/modules/dialog/dlg_handlers.c @@ -749,15 +749,15 @@ static void dlg_on_send(struct cell* t, int type, struct tmcb_params *param) LM_DBG("dialog_on_send CB\n"); iuid = (dlg_iuid_t*)(*param->param); if (iuid==NULL) - return; + return; dlg = dlg_get_by_iuid(iuid); if(dlg==NULL) - return; + return; /* sync over dmq */ if (dlg_enable_dmq) { - dlg_dmq_replicate_action(DLG_DMQ_UPDATE, dlg, 1, 0); + dlg_dmq_replicate_action(DLG_DMQ_UPDATE, dlg, 1, 0); } /* unref by 2: 1 set when adding in tm cb, 1 set by dlg_get_by_iuid() */ diff --git a/src/modules/dialog/dlg_hash.c b/src/modules/dialog/dlg_hash.c index 5557e8757..2714c439e 100644 --- a/src/modules/dialog/dlg_hash.c +++ b/src/modules/dialog/dlg_hash.c @@ -857,7 +857,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 or not + * \param mode let hash table slot locked or not, even when dlg is not found * \return dialog structure on success, NULL on failure */ static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry, @@ -865,24 +865,50 @@ static inline struct dlg_cell* internal_get_dlg(unsigned int h_entry, unsigned int *dir, int mode) { struct dlg_cell *dlg; + struct dlg_cell *dlg_no_totag=NULL; struct dlg_entry *d_entry; + unsigned int dir_no_totag = DLG_DIR_NONE; d_entry = &(d_table->entries[h_entry]); dlg_lock( d_table, d_entry); for( dlg = d_entry->first ; dlg ; dlg = dlg->next ) { - /* Check callid / fromtag / totag */ + /* check callid / fromtag / totag */ if (match_dialog( dlg, callid, ftag, ttag, dir)==1) { + /* if to-tag is empty continue to search in case another dialog + * is found with a matching to-tag. */ + if (dlg->tag[DLG_CALLEE_LEG].len == 0) { + dlg_no_totag = dlg; + dir_no_totag = *dir; + continue; + } + ref_dlg_unsafe(dlg, 1); - 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); + if(likely(mode==0)) { + dlg_unlock( d_table, d_entry); + } + LM_DBG("dialog callid='%.*s' found on entry %u, dir=%d to-tag='%.*s'\n", + callid->len, callid->s, h_entry, *dir, + dlg->tag[DLG_CALLEE_LEG].len, dlg->tag[DLG_CALLEE_LEG].s); + return dlg; } } - if(likely(mode==0)) dlg_unlock( d_table, d_entry); + if (dlg_no_totag) { + ref_dlg_unsafe(dlg_no_totag, 1); + } + if(likely(mode==0)) { + dlg_unlock(d_table, d_entry); + } + if (dlg_no_totag) { + *dir = dir_no_totag; + LM_DBG("dialog callid='%.*s' found on entry %u, dir=%d no-to-tag\n", + callid->len, callid->s, h_entry, *dir); + return dlg_no_totag; + } + LM_DBG("no dialog callid='%.*s' found\n", callid->len, callid->s); return 0; } diff --git a/src/modules/dialog/dlg_var.c b/src/modules/dialog/dlg_var.c index fa9eae9d1..b2a373a50 100644 --- a/src/modules/dialog/dlg_var.c +++ b/src/modules/dialog/dlg_var.c @@ -434,10 +434,11 @@ int pv_set_dlg_variable(struct sip_msg* msg, pv_param_t *param, int op, pv_value /* unlock dialog */ if (dlg) { dlg->dflags |= DLG_FLAG_CHANGED_VARS; - dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); - if ( dlg_db_mode==DB_MODE_REALTIME ) + if ( dlg_db_mode==DB_MODE_REALTIME ) { + /* dlg_lock() / dlg_unlock() are reentrant */ update_dialog_dbinfo(dlg); - + } + dlg_unlock(d_table, &(d_table->entries[dlg->h_entry])); } print_lists(dlg); diff --git a/src/modules/dispatcher/README b/src/modules/dispatcher/README index a30d001f6..0b2334771 100644 --- a/src/modules/dispatcher/README +++ b/src/modules/dispatcher/README @@ -1058,8 +1058,8 @@ modparam("dispatcher", "reload_delta", 1) (serial forking ordered by priority). + “9” - use weight based load distribution. You have to set the attribute 'weight' for each address (gateway) in destination - set. For more see the description of the 'weight' attribute in - the 'Special Attributes' section. + set. See also the description of the 'weight' attribute in the + 'Special Attributes' section. + “10” - use call load distribution. You have to set the attribute 'duid' (as an unique string id) per each address in destination set. Also, you must set the parameter @@ -1081,10 +1081,14 @@ modparam("dispatcher", "reload_delta", 1) active host rweights in destination group). The major difference from the weight distribution is the probability recalculation according to rweight value in case - of host enabling/disabling - For example, 100 calls in 3-hosts group with rweight params - 1/2/1 will be distributed as 25/50/25. After third host - failing distribution will be changed to 33/67/0. + of destinations being active or inactive. + For example, 100 calls in 3-destinations group with rweight + params 1/2/1 will be distributed as 25/50/25. If the third + destination becomes inactive, the distribution is changed to + 33/67/0. If the computation of percentage per destination is + not an exact integer number, the value is trucated and the + last destination is used to fill the remaining percentage till + 100. Using this algorithm, you can also enable congestion control by setting the attibute 'cc=1', when 'cc' is enabled the 'rweight' attribute will also be used to control congestion @@ -1097,6 +1101,8 @@ modparam("dispatcher", "reload_delta", 1) above their congestion threshold(weight), the load distribution is instead done using the ratio of estimated congestion ms. + See also the description of the 'rweight' attribute in the + 'Special Attributes' section. + “12” - dispatch to all destination in setid at once (parallel forking). Note that the XAVPs are no longer set with the values of the destination records, no re-routing making sense @@ -1681,11 +1687,17 @@ kamctl rpc dispatcher.hash 4 bob server.com If set to 0, then no active call limit is used.> * 'weight' - used for weight based load distribution. It must be set to a positive integer value beteen 0 and 100. The value represents - the percent of calls to be sent to that gateways.> + the percent of calls to be sent to that gateways. The sum must not + exceed 100, otherwise the destinations whose weight added to the + sum go over 100 are ignored. If the sum is less than 100, then the + last destination is used to fill the missing percentage. See also + the description of the corresponding algorithm parameter for + ds_select_dst(). * 'rweight' - used for relative weight based load distribution. It must be set to a positive integer value between 1 and 100 (otherwise host will be excluded from relative weight distribution - type). + type). See also the description of the corresponding algorithm + parameter for ds_select_dst(). * 'socket' - used to set the sending socket for the gateway. It is used for sending the SIP traffic as well as OPTIONS keepalives. * 'sockname' - used to set by name the sending socket for the diff --git a/src/modules/dispatcher/dispatch.c b/src/modules/dispatcher/dispatch.c index b78a89fdb..aee5eb8ea 100644 --- a/src/modules/dispatcher/dispatch.c +++ b/src/modules/dispatcher/dispatch.c @@ -872,14 +872,14 @@ next_line: goto error; } - LM_DBG("found [%d] dest sets\n", _ds_list_nr); - fclose(f); f = NULL; /* Update list - should it be sync'ed? */ _ds_list_nr = setn; *crt_idx = *next_idx; + LM_DBG("found [%d] dest sets\n", _ds_list_nr); + ds_log_sets(); return 0; @@ -1120,14 +1120,14 @@ int ds_load_db(void) goto err2; } - LM_DBG("found [%d] dest sets\n", _ds_list_nr); - ds_dbf.free_result(ds_db_handle, res); /* update data - should it be sync'ed? */ _ds_list_nr = setn; *crt_idx = *next_idx; + LM_DBG("found [%d] dest sets\n", _ds_list_nr); + ds_log_sets(); if(dest_errs > 0) diff --git a/src/modules/dispatcher/dispatcher.c b/src/modules/dispatcher/dispatcher.c index 836038442..18ece721f 100644 --- a/src/modules/dispatcher/dispatcher.c +++ b/src/modules/dispatcher/dispatcher.c @@ -1063,7 +1063,6 @@ static int ki_ds_list_exists(struct sip_msg *msg, int set) static int fixup_ds_list_exist(void **param, int param_no) { return fixup_igp_null(param, param_no); - return 0; } static int ds_parse_reply_codes() diff --git a/src/modules/dispatcher/doc/dispatcher_admin.xml b/src/modules/dispatcher/doc/dispatcher_admin.xml index 0b9b4495b..11fff9c7d 100644 --- a/src/modules/dispatcher/doc/dispatcher_admin.xml +++ b/src/modules/dispatcher/doc/dispatcher_admin.xml @@ -1189,7 +1189,7 @@ modparam("dispatcher", "reload_delta", 1) 9 - use weight based load distribution. You have to set the attribute 'weight' for each address (gateway) in - destination set. For more see the description of the 'weight' + destination set. See also the description of the 'weight' attribute in the 'Special Attributes' section. @@ -1228,12 +1228,15 @@ modparam("dispatcher", "reload_delta", 1) The major difference from the weight distribution is the probability recalculation according to rweight value in case of - host enabling/disabling + destinations being active or inactive. - For example, 100 calls in 3-hosts group with rweight params 1/2/1 - will be distributed as 25/50/25. After third host failing - distribution will be changed to 33/67/0. + For example, 100 calls in 3-destinations group with rweight params 1/2/1 + will be distributed as 25/50/25. If the third destination becomes + inactive, the distribution is changed to 33/67/0. If the computation + of percentage per destination is not an exact integer number, the value + is trucated and the last destination is used to fill the remaining + percentage till 100. Using this algorithm, you can also enable congestion control by setting the @@ -1248,6 +1251,10 @@ modparam("dispatcher", "reload_delta", 1) If all the gateways in a set are above their congestion threshold(weight), the load distribution is instead done using the ratio of estimated congestion ms. + + See also the description of the 'rweight' attribute in the + 'Special Attributes' section. + @@ -2100,13 +2107,19 @@ kamctl rpc dispatcher.hash 4 bob server.com 'weight' - used for weight based load distribution. It must be set to a positive integer value beteen 0 and 100. The value represents - the percent of calls to be sent to that gateways.> + the percent of calls to be sent to that gateways. The sum must not + exceed 100, otherwise the destinations whose weight added to the + sum go over 100 are ignored. If the sum is less than 100, then the + last destination is used to fill the missing percentage. See also + the description of the corresponding algorithm parameter for + ds_select_dst(). 'rweight' - used for relative weight based load distribution. It must be set to a positive integer value between 1 and 100 (otherwise host will be excluded from relative weight distribution - type). + type). See also the description of the corresponding algorithm + parameter for ds_select_dst(). 'socket' - used to set the sending socket for the gateway. It is diff --git a/src/modules/dlgs/dlgs_mod.c b/src/modules/dlgs/dlgs_mod.c index e26e0d989..503dd8c19 100644 --- a/src/modules/dlgs/dlgs_mod.c +++ b/src/modules/dlgs/dlgs_mod.c @@ -250,13 +250,16 @@ static int w_dlgs_update(sip_msg_t *msg, char *p1, char *p2) */ static int ki_dlgs_count(sip_msg_t *msg, str *vfield, str *vop, str *vdata) { + int ret; + LM_DBG("counting by: [%.*s] [%.*s] [%.*s]\n", vfield->len, vfield->s, vop->len, vop->s, vdata->len, vdata->s); - if(dlgs_count(msg, vfield, vop, vdata) < 0) { - return -1; + ret = dlgs_count(msg, vfield, vop, vdata); + if(ret <= 0) { + return (ret-1); } - return 1; + return ret; } /** @@ -338,8 +341,11 @@ static int w_dlgs_tags_rm(sip_msg_t *msg, char *ptags, char *p2) */ static int ki_dlgs_tags_count(sip_msg_t *msg, str *vtags) { - if(dlgs_tags_count(msg, vtags)<0) { - return -1; + int ret; + + ret = dlgs_tags_count(msg, vtags); + if(ret<=0) { + return (ret-1); } return 1; } diff --git a/src/modules/dlgs/dlgs_records.c b/src/modules/dlgs/dlgs_records.c index 6b4a6b70e..1f6af22ba 100644 --- a/src/modules/dlgs/dlgs_records.c +++ b/src/modules/dlgs/dlgs_records.c @@ -340,6 +340,7 @@ int dlgs_add_item(sip_msg_t *msg, str *src, str *dst, str *data) prev->next = nitem; } dsht->slots[idx].esize++; + dlgs_update_stats(&dsht->slots[idx].astats, nitem->state, 1); lock_release(&dsht->slots[idx].lock); return 0; } diff --git a/src/modules/drouting/README b/src/modules/drouting/README index a61a00e6d..7c6b10fd2 100644 --- a/src/modules/drouting/README +++ b/src/modules/drouting/README @@ -167,10 +167,10 @@ Chapter 1. Admin Guide 1.1. Introduction Dynamic Routing is a module for selecting (based on multiple criteria) - the the best gateway/destination to be used for delivering a certain - call. Least Cost Routing (LCR) is a special case of dynamic routing - - when the rules are ordered based on costs. Dynamic Routing comes with - many features regarding routing rule selection: + the best gateway/destination to be used for delivering a certain call. + Least Cost Routing (LCR) is a special case of dynamic routing - when + the rules are ordered based on costs. Dynamic Routing comes with many + features regarding routing rule selection: * prefix based * caller/group based * time based diff --git a/src/modules/drouting/doc/drouting_admin.xml b/src/modules/drouting/doc/drouting_admin.xml index facb72b31..323c183a9 100644 --- a/src/modules/drouting/doc/drouting_admin.xml +++ b/src/modules/drouting/doc/drouting_admin.xml @@ -18,7 +18,7 @@ Introduction Dynamic Routing is a module for selecting (based on multiple - criteria) the the best gateway/destination to be used for delivering a + criteria) the best gateway/destination to be used for delivering a certain call. Least Cost Routing (LCR) is a special case of dynamic routing - when the rules are ordered based on costs. Dynamic Routing comes with many features regarding routing rule selection: diff --git a/src/modules/drouting/routing.c b/src/modules/drouting/routing.c index a1d32fa0b..da4385911 100644 --- a/src/modules/drouting/routing.c +++ b/src/modules/drouting/routing.c @@ -268,6 +268,7 @@ int add_dst(rt_data_t *r, #define GWABUF_MAX_SIZE 512 char gwabuf[GWABUF_MAX_SIZE]; str gwas; + unsigned short port; if(NULL == r || NULL == ip) { LM_ERR("invalid parametres\n"); @@ -331,7 +332,8 @@ int add_dst(rt_data_t *r, } /* note we discard the port discovered by the resolve function - we are interested only in the port that was actually configured. */ - if((he = sip_resolvehost(&uri.host, NULL, (char *)(void *)&uri.proto)) + port = 0; + if((he = sip_resolvehost(&uri.host, &port, (char *)(void *)&uri.proto)) == 0) { if(dr_force_dns) { LM_ERR("cannot resolve <%.*s>\n", uri.host.len, uri.host.s); diff --git a/src/modules/evapi/evapi_mod.c b/src/modules/evapi/evapi_mod.c index bcc582f6e..a9c4d9ad3 100644 --- a/src/modules/evapi/evapi_mod.c +++ b/src/modules/evapi/evapi_mod.c @@ -756,6 +756,59 @@ static int ki_evapi_async_unicast(sip_msg_t *msg, str *sdata, str *stag) return 1; } +static int ki_evapi_async_multicast(sip_msg_t *msg, str *sdata, str *stag) +{ + unsigned int tindex; + unsigned int tlabel; + tm_cell_t *t = 0; + + if(tmb.t_suspend==NULL) { + LM_ERR("evapi async relay is disabled - tm module not loaded\n"); + return -1; + } + + t = tmb.t_gett(); + if (t==NULL || t==T_UNDEFINED) + { + if(tmb.t_newtran(msg)<0) + { + LM_ERR("cannot create the transaction\n"); + return -1; + } + t = tmb.t_gett(); + if (t==NULL || t==T_UNDEFINED) + { + LM_ERR("cannot lookup the transaction\n"); + return -1; + } + } + if(tmb.t_suspend(msg, &tindex, &tlabel)<0) + { + LM_ERR("failed to suspend request processing\n"); + return -1; + } + + LM_DBG("transaction suspended [%u:%u]\n", tindex, tlabel); + + + if(sdata->s==NULL || sdata->len == 0) { + LM_ERR("invalid data parameter\n"); + return -1; + } + + if(stag->s==NULL || stag->len == 0) { + LM_ERR("invalid tag parameter\n"); + return -1; + } + + if(evapi_relay_multicast(sdata, stag)<0) { + LM_ERR("failed to relay event: [[%.*s]] to [%.*s] \n", + sdata->len, sdata->s, stag->len, stag->s); + return -2; + } + return 1; +} + /** * */ @@ -824,6 +877,11 @@ static sr_kemi_t sr_kemi_evapi_exports[] = { { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("evapi"), str_init("async_multicast"), + SR_KEMIP_INT, ki_evapi_async_multicast, + { SR_KEMIP_STR, SR_KEMIP_STR, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } }; /* clang-format on */ diff --git a/src/modules/exec/exec.c b/src/modules/exec/exec.c index 0e809ed8a..763e30816 100644 --- a/src/modules/exec/exec.c +++ b/src/modules/exec/exec.c @@ -326,11 +326,17 @@ int exec_cmd(sip_msg_t *msg, char *cmd) exit_status = pclose(pipe); if(WIFEXITED(exit_status)) { /* exited properly .... */ /* return false if script exited with non-zero status */ - if(WEXITSTATUS(exit_status) != 0) + if(WEXITSTATUS(exit_status) != 0) { + LM_DBG("cmd %s with non-zero status - exit_status=%d," + " wexitstatus: %d, errno=%d: %s\n", + cmd, exit_status, WEXITSTATUS(exit_status), + errno, strerror(errno)); ret = -1; + } } else { /* exited erroneously */ - LM_ERR("cmd %s failed. exit_status=%d, errno=%d: %s\n", cmd, - exit_status, errno, strerror(errno)); + LM_ERR("cmd %s failed. exit_status=%d, wexitstatus: %d, errno=%d: %s\n", + cmd, exit_status, WEXITSTATUS(exit_status), + errno, strerror(errno)); ret = -1; } diff --git a/src/modules/htable/README b/src/modules/htable/README index ca193e221..85f19c710 100644 --- a/src/modules/htable/README +++ b/src/modules/htable/README @@ -1165,6 +1165,16 @@ kamcmd htable.stats items in hash tables. The event route is executed only once, after core and module initialization, but before Kamailio forks any child processes. + + Note: do not expect to use functions from all other modules here, even + if they are loaded before the htable module, because many of them + initialize their runtime structures inside child init callbacks, which + are executed after this moment, when forking child processes. For + example, sqlops cannot be used, connections to database are initialized + in child init. Even more, it is recommended not to use functions from + other modules, because it can mess up what they created in mod init + callback and expect in child init callback. It should be ok to use + functions from htable module or assignment operations. ... event_route[htable:mod-init] { $sht(a=>x) = 1; diff --git a/src/modules/htable/doc/htable_admin.xml b/src/modules/htable/doc/htable_admin.xml index 573d801bb..3a7f101bc 100644 --- a/src/modules/htable/doc/htable_admin.xml +++ b/src/modules/htable/doc/htable_admin.xml @@ -1528,6 +1528,18 @@ kamcmd htable.stats once, after core and module initialization, but before &kamailio; forks any child processes. + + Note: do not expect to use functions from all other modules here, + even if they are loaded before the htable module, because many of + them initialize their runtime structures inside child init callbacks, + which are executed after this moment, when forking child processes. + For example, sqlops cannot be used, connections to database are + initialized in child init. Even more, it is recommended not to use + functions from other modules, because it can mess up what they + created in mod init callback and expect in child init callback. It + should be ok to use functions from htable module or assignment + operations. + ... event_route[htable:mod-init] { diff --git a/src/modules/http_async_client/http_async_client_mod.c b/src/modules/http_async_client/http_async_client_mod.c index 7bfbb004c..d0b99daec 100644 --- a/src/modules/http_async_client/http_async_client_mod.c +++ b/src/modules/http_async_client/http_async_client_mod.c @@ -275,6 +275,8 @@ static int mod_init(void) return -1; } + set_curl_mem_callbacks(); + /* init faked sip msg */ if(faked_msg_init()<0) { LM_ERR("failed to init faked sip msg\n"); diff --git a/src/modules/http_async_client/http_multi.c b/src/modules/http_async_client/http_multi.c index b5c2e8d63..9ed1b2dc9 100644 --- a/src/modules/http_async_client/http_multi.c +++ b/src/modules/http_async_client/http_multi.c @@ -385,7 +385,6 @@ void set_curl_mem_callbacks(void) LM_ERR ("invalid memory manager: %d\n", curl_memory_manager); break; } - } int init_http_multi(struct event_base *evbase, struct http_m_global *wg) @@ -393,7 +392,6 @@ int init_http_multi(struct event_base *evbase, struct http_m_global *wg) g = wg; g->evbase = evbase; - set_curl_mem_callbacks(); g->multi = curl_multi_init(); LM_DBG("curl_multi %p initialized on global %p (evbase %p)\n", g->multi, g, evbase); diff --git a/src/modules/http_async_client/http_multi.h b/src/modules/http_async_client/http_multi.h index c830daa9b..10070eb6b 100644 --- a/src/modules/http_async_client/http_multi.h +++ b/src/modules/http_async_client/http_multi.h @@ -37,7 +37,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/src/modules/http_client/README b/src/modules/http_client/README index 623d87320..6724cc571 100644 --- a/src/modules/http_client/README +++ b/src/modules/http_client/README @@ -91,7 +91,7 @@ Hugh Waite 2. Developer Guide - 1. + 1. Introduction 2. Available Functions 2.1. int http_connect(msg, connection, url, result, @@ -872,7 +872,7 @@ Chapter 2. Developer Guide Table of Contents - 1. + 1. Introduction 2. Available Functions 2.1. int http_connect(msg, connection, url, result, content_type, @@ -882,6 +882,8 @@ Chapter 2. Developer Guide 2.3. int http_query(msg, url, dest, post) 2.4. http_get_content_type(str connection) +1. Introduction + This module provides a set of API functions that other modules can use in order to integrate with HTTP services. diff --git a/src/modules/http_client/doc/http_client.xml b/src/modules/http_client/doc/http_client.xml index d806aa739..a908872e5 100644 --- a/src/modules/http_client/doc/http_client.xml +++ b/src/modules/http_client/doc/http_client.xml @@ -56,9 +56,8 @@ - + - - + diff --git a/src/modules/http_client/doc/http_client_admin.xml b/src/modules/http_client/doc/http_client_admin.xml index 691a99531..6f1c89769 100644 --- a/src/modules/http_client/doc/http_client_admin.xml +++ b/src/modules/http_client/doc/http_client_admin.xml @@ -74,8 +74,7 @@ External Libraries or Applications The following libraries or applications must be - installed before - running &kamailio; with this module loaded: + installed before running &kamailio; with this module loaded: @@ -86,7 +85,7 @@
- +
Parameters
@@ -297,7 +296,7 @@ modparam("http_client", "cipher_suites", "ecdhe_ecdsa_aes_128_gcm_sha_256,rsa_ae <varname>verify_peer</varname> (int) If set to 0, TLS verification of the server certificate - is disabled. This means that the connection will get + is disabled. This means that the connection will get encrypted, but there's no authentication. There's no proof that the transmission of data is to the host that is meant to receive data. @@ -324,7 +323,7 @@ modparam("http_client", "verify_peer", 1) <varname>verify_host</varname> (int) If set to 0, domain verification of the server certificate - is disabled. This means that the connection will get + is disabled. This means that the connection will get encrypted but there is no check that data will be sent to the host that is meant to receive it. Disable with caution. @@ -535,11 +534,11 @@ modparam("http_client", "query_maxdatasize", 2048) Overrides the default cipher_suite modparam. - timeout Timeout used for this connection. Overrides the + timeout Timeout used for this connection. Overrides the default connection_timeout for the module. - tlsversion TLS version used for this connection. Overrides the + tlsversion TLS version used for this connection. Overrides the default tlsversion for the module. @@ -648,7 +647,7 @@ modparam("http_client", "config_file", "httpconnections.cfg) [authapiserver] url = https://api.runbo.example.com/v4.2/auth timeout = 1 -maxdatasize = 4 +maxdatasize = 4 tlsversion = TLSv1.2 verify_peer = yes client_key = default_key.pem diff --git a/src/modules/http_client/doc/http_client_devel.xml b/src/modules/http_client/doc/http_client_devel.xml index 80bb99b4c..5e810edc0 100644 --- a/src/modules/http_client/doc/http_client_devel.xml +++ b/src/modules/http_client/doc/http_client_devel.xml @@ -10,11 +10,14 @@ - + &develguide;
+ Introduction + This module provides a set of API functions that other modules can use in order to integrate with HTTP services. +
Available Functions @@ -93,7 +96,7 @@ int http_query(msg, url, dest, post) - Sends a HTTP GET or POST request to a given connection. If post data + Sends a HTTP GET or POST request to a given connection. If post data is defined, POST will be used, otherwise GET. The default settings defined as module params of the http_client module will be used for the connection. @@ -144,7 +147,6 @@
-
diff --git a/src/modules/http_client/functions.c b/src/modules/http_client/functions.c index 3c99d77f1..1acebfbca 100644 --- a/src/modules/http_client/functions.c +++ b/src/modules/http_client/functions.c @@ -668,6 +668,18 @@ int http_client_query( query_params.http_proxy_port = default_http_proxy_port; } } + if(default_tls_clientcert.s != NULL && default_tls_clientcert.len > 0) { + query_params.clientcert = default_tls_clientcert.s; + } + if(default_tls_clientkey.s != NULL && default_tls_clientkey.len > 0) { + query_params.clientkey = default_tls_clientkey.s; + } + if(default_tls_cacert != NULL) { + query_params.cacert = default_tls_cacert; + } + if(default_cipher_suite_list.s != NULL && default_cipher_suite_list.len) { + query_params.ciphersuites = default_cipher_suite_list.s; + } res = curL_query_url(_m, _url, _dst, &query_params); diff --git a/src/modules/http_client/http_client.c b/src/modules/http_client/http_client.c index 177e50eb1..e34dae58f 100644 --- a/src/modules/http_client/http_client.c +++ b/src/modules/http_client/http_client.c @@ -894,8 +894,9 @@ static int ki_http_query_helper(sip_msg_t *_m, str *url, str *post, str *hdrs, LM_ERR("invalid url parameter\n"); return -1; } - ret = http_client_query(_m, url->s, &result, (post && post->s)?post->s:NULL, - (hdrs && hdrs->s)?hdrs->s:NULL); + ret = http_client_query(_m, url->s, &result, + (post && post->s && post->len>0)?post->s:NULL, + (hdrs && hdrs->s && hdrs->len>0)?hdrs->s:NULL); val.rs = result; val.flags = PV_VAL_STR; diff --git a/src/modules/imc/imc_cmd.c b/src/modules/imc/imc_cmd.c index 4ace0b800..9dbc403e3 100644 --- a/src/modules/imc/imc_cmd.c +++ b/src/modules/imc/imc_cmd.c @@ -942,13 +942,15 @@ int imc_handle_members(struct sip_msg* msg, imc_cmd_t *cmd, struct imc_uri room; memset(&room, '\0', sizeof(room)); - if (build_imc_uri(&room, cmd->param[0].s ? cmd->param[0] : dst->parsed.user, &dst->parsed)) - goto error; + if (build_imc_uri(&room, cmd->param[0].s ? cmd->param[0] : dst->parsed.user, + &dst->parsed)) { + goto done; + } rm = imc_get_room(&room.parsed.user, &room.parsed.host); if (rm == NULL || (rm->flags & IMC_ROOM_DELETED)) { LM_ERR("Room [%.*s] does not exist!\n", STR_FMT(&room.uri)); - goto error; + goto done; } /* verify if the user is a member of the room */ @@ -956,7 +958,7 @@ int imc_handle_members(struct sip_msg* msg, imc_cmd_t *cmd, if (member == NULL) { LM_ERR("User [%.*s] is not member of room [%.*s]!\n", STR_FMT(&src->uri), STR_FMT(&rm->uri)); - goto error; + goto done; } p = imc_body_buf; @@ -1004,13 +1006,16 @@ int imc_handle_members(struct sip_msg* msg, imc_cmd_t *cmd, body.len = p - body.s; LM_DBG("members = '%.*s'\n", STR_FMT(&body)); - LM_ERR("Message-ID: '%.*s'\n", STR_FMT(get_callid(msg))); + LM_DBG("Message-ID: '%.*s'\n", STR_FMT(get_callid(msg))); imc_send_message(&rm->uri, &member->uri, build_headers(msg), &body); rv = 0; + goto done; + overrun: LM_ERR("Buffer too small for member list message\n"); -error: + +done: if (room.uri.s != NULL) pkg_free(room.uri.s); if (rm != NULL) imc_release_room(rm); return rv; @@ -1065,7 +1070,8 @@ int imc_handle_rooms(struct sip_msg* msg, imc_cmd_t *cmd, LM_DBG("rooms = '%.*s'\n", STR_FMT(&body)); imc_send_message(&dst->uri, &src->uri, build_headers(msg), &body); - rv = 0; + return 0; + error: LM_ERR("Buffer too small for member list message\n"); return rv; diff --git a/src/modules/ims_qos/rx_aar.c b/src/modules/ims_qos/rx_aar.c index b1e8df51b..d9f242f43 100644 --- a/src/modules/ims_qos/rx_aar.c +++ b/src/modules/ims_qos/rx_aar.c @@ -276,7 +276,7 @@ void async_aar_reg_callback(int is_timeout, void *param, AAAMessage *aaa, long e if (cdp_result >= 2000 && cdp_result < 3000) { counter_inc(ims_qos_cnts_h.successful_registration_aars); if (is_rereg) { - LM_DBG("this is a re-registration, therefore we don't need to do anything except know that the the subscription was successful\n"); + LM_DBG("this is a re-registration, therefore we don't need to do anything except know that the subscription was successful\n"); result = CSCF_RETURN_TRUE; create_return_code(result); goto done; diff --git a/src/modules/janssonrpcc/janssonrpc_funcs.c b/src/modules/janssonrpcc/janssonrpc_funcs.c index 93e62bd53..70b3e9413 100644 --- a/src/modules/janssonrpcc/janssonrpc_funcs.c +++ b/src/modules/janssonrpcc/janssonrpc_funcs.c @@ -44,7 +44,6 @@ int jsonrpc_request(struct sip_msg* _m, str params; str options; str route; - param_hooks_t phooks; param_t* pit=NULL; param_t* freeme=NULL; int retry; @@ -85,7 +84,7 @@ int jsonrpc_request(struct sip_msg* _m, options.len--; } - if (parse_params(&options, CLASS_ANY, &phooks, &pit)<0) { + if (parse_params(&options, CLASS_ANY, NULL, &pit)<0) { ERR("failed parsing params value\n"); return -1; } @@ -95,8 +94,7 @@ int jsonrpc_request(struct sip_msg* _m, for (; pit;pit=pit->next) { if PIT_MATCHES("route") { - pkg_str_dup(&route, &pit->body); - CHECK_MALLOC_GOTO(route.s, end); + route = pit->body; } else if PIT_MATCHES("timeout") { timeout = atoi(pit->body.s); @@ -123,8 +121,6 @@ skip_parse: goto end; } - retval = 0; - retval = mod_jsonrpc_request( _m, /* sip_msg */ conn, /* connection group */ @@ -138,7 +134,6 @@ skip_parse: end: if(freeme) free_params(freeme); - if(route.s) pkg_free(route.s); return retval; } diff --git a/src/modules/jsonrpcs/jsonrpcs_mod.c b/src/modules/jsonrpcs/jsonrpcs_mod.c index 6f3491b03..c3b800304 100644 --- a/src/modules/jsonrpcs/jsonrpcs_mod.c +++ b/src/modules/jsonrpcs/jsonrpcs_mod.c @@ -1227,7 +1227,7 @@ static void mod_destroy(void) /** * */ -static int jsonrpc_dispatch(sip_msg_t* msg, char* s1, char* s2) +static int ki_jsonrpcs_dispatch(sip_msg_t* msg) { rpc_export_t* rpce; jsonrpc_ctx_t* ctx; @@ -1315,6 +1315,14 @@ send_reply: } +/** + * + */ +static int jsonrpc_dispatch(sip_msg_t* msg, char* s1, char* s2) +{ + return ki_jsonrpcs_dispatch(msg); +} + int jsonrpc_exec_ex(str *cmd, str *rpath) { rpc_export_t* rpce; @@ -1551,6 +1559,11 @@ static sr_kemi_xval_t* ki_jsonrpcs_response(sip_msg_t *msg) */ /* clang-format off */ static sr_kemi_t sr_kemi_jsonrpcs_exports[] = { + { str_init("jsonrpcs"), str_init("dispatch"), + SR_KEMIP_INT, ki_jsonrpcs_dispatch, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { str_init("jsonrpcs"), str_init("exec"), SR_KEMIP_INT, ki_jsonrpcs_exec, { SR_KEMIP_STR, SR_KEMIP_NONE, SR_KEMIP_NONE, diff --git a/src/modules/keepalive/keepalive_mod.c b/src/modules/keepalive/keepalive_mod.c index bcf021d46..d9434876d 100644 --- a/src/modules/keepalive/keepalive_mod.c +++ b/src/modules/keepalive/keepalive_mod.c @@ -188,8 +188,10 @@ static int w_add_destination(sip_msg_t *msg, char *uri, char *owner) */ static int ki_add_destination(sip_msg_t *msg, str *uri, str *owner) { - if(ka_alloc_destinations_list() < 0) + if(ka_destinations_list == NULL) { + LM_ERR("destinations list not initialized\n"); return -1; + } return ka_add_dest(uri, owner, 0, ka_ping_interval, 0, 0, 0); } diff --git a/src/modules/lost/README b/src/modules/lost/README index 1cbd906d2..81a4fa483 100644 --- a/src/modules/lost/README +++ b/src/modules/lost/README @@ -179,7 +179,7 @@ Chapter 1. Admin Guide Example 1.3. Set location_type parameter ... - modparam("http_client", "location_type, "civic geodetic locationURI") + modparam("lost", "location_type, "civic geodetic locationURI") ... 4. Functions @@ -221,7 +221,7 @@ $var(err)"); xlog("L_INFO", "HELD locationRequest: Result code $var(res)\nUrl: $var(url)\n$va r(pidf)"); ... -$var(res) = lost_held_query("heldsrv", "$var(pidf)", "$var(url)"", "$var(err)"); +$var(res) = lost_held_query("heldsrv", "$var(pidf)", "$var(url)", "$var(err)"); xlog("L_INFO", "HELD locationRequest: Result code $var(res)\nUrl: $var(url)\n$va r(pidf)\n"); ... diff --git a/src/modules/lost/doc/lost_admin.xml b/src/modules/lost/doc/lost_admin.xml index c8be8f668..c5d4f5ad6 100644 --- a/src/modules/lost/doc/lost_admin.xml +++ b/src/modules/lost/doc/lost_admin.xml @@ -168,7 +168,7 @@ Set <varname>location_type</varname> parameter ... - modparam("http_client", "location_type, "civic geodetic locationURI") + modparam("lost", "location_type, "civic geodetic locationURI") ... @@ -228,7 +228,7 @@ $var(id) = "sip:alice@atlanta"; $var(res) = lost_held_query("heldsrv", "$var(id)" , "$var(pidf)", "$var(url)", "$var(err)"); xlog("L_INFO", "HELD locationRequest: Result code $var(res)\nUrl: $var(url)\n$var(pidf)"); ... -$var(res) = lost_held_query("heldsrv", "$var(pidf)", "$var(url)"", "$var(err)"); +$var(res) = lost_held_query("heldsrv", "$var(pidf)", "$var(url)", "$var(err)"); xlog("L_INFO", "HELD locationRequest: Result code $var(res)\nUrl: $var(url)\n$var(pidf)\n"); ... diff --git a/src/modules/lost/functions.c b/src/modules/lost/functions.c index c94c7883f..481d73707 100644 --- a/src/modules/lost/functions.c +++ b/src/modules/lost/functions.c @@ -298,6 +298,8 @@ int lost_held_function(struct sip_msg *_m, char *_con, char *_pidf, char *_url, if(geo.len == 0) { LM_WARN("%s element not found\n", HELD_TYPE_URI); geo.s = NULL; + } else { + geo.s = lost_trim_content(geo.s, &geo.len); } } if(xmlStrcmp(cur_node->name, diff --git a/src/modules/misc_radius/radius.h b/src/modules/misc_radius/radius.h index 120bb80ca..c5e952571 100644 --- a/src/modules/misc_radius/radius.h +++ b/src/modules/misc_radius/radius.h @@ -42,6 +42,9 @@ #else #include #define DEFAULT_RADIUSCLIENT_CONF "" +#ifndef VENDOR +#define VENDOR(x) (((x) >> 16) & 0xffff) +#endif #endif diff --git a/src/modules/msrp/msrp_parser.c b/src/modules/msrp/msrp_parser.c index a6310cea9..4e5e67e13 100644 --- a/src/modules/msrp/msrp_parser.c +++ b/src/modules/msrp/msrp_parser.c @@ -491,10 +491,25 @@ int msrp_parse_uri(char *start, int len, msrp_uri_t *uri) } hook = &uri->host; hook->s = s; + if(*s == '[') + { + /* IPv6 */ + p = q_memchr(s, ']', e - s); + if(p == NULL) + { + goto error; + } + s = p + 1; + hook->len = s - hook->s; + } p = q_memchr(s, ':', e - s); if(p!=NULL) { - hook->len = p - hook->s; + if(hook->len == 0) + { + /* host len was not set yet */ + hook->len = p - hook->s; + } hook = &uri->port; s = p+1; if(s>=e) goto error; diff --git a/src/modules/msrp/msrp_vars.c b/src/modules/msrp/msrp_vars.c index fddabde18..8384ff091 100644 --- a/src/modules/msrp/msrp_vars.c +++ b/src/modules/msrp/msrp_vars.c @@ -283,7 +283,7 @@ int pv_get_msrp(sip_msg_t *msg, pv_param_t *param, pv_value_t *res) memcpy(p, "msrp://", 7); p+=7; } - strcpy(p, ip_addr2a(&mf->tcpinfo->rcv->src_ip)); + strcpy(p, ip_addr2strz(&mf->tcpinfo->rcv->src_ip)); strcat(p, ":"); strcat(p, int2str(mf->tcpinfo->rcv->src_port, NULL)); s.len = strlen(s.s); diff --git a/src/modules/nathelper/README b/src/modules/nathelper/README index 7398c702a..0fa395da2 100644 --- a/src/modules/nathelper/README +++ b/src/modules/nathelper/README @@ -525,16 +525,19 @@ if (search("User-Agent: Cisco ATA.*") {fix_nated_contact();}; * flags - the value may be a bitwise OR of the following flags: + 0x01 - adds “a=direction:active” SDP line; + 0x02 - rewrite media IP address (c=) with source address of - the message or the provided IP address (the provide IP address - take precedence over the source address). + the message or the provided IP address. (a=rtcp) param will be + rewritten if exists. (the provided IP address take precedence + over the source address). + 0x04 - adds “a=nortpproxy:yes” SDP line; + 0x08 - rewrite IP from origin description (o=) with source - address of the message or the provided IP address (the provide - IP address take precedence over the source address). + address of the message or the provided IP address. (a=rtcp) + param will be rewritten if exists. (the provided IP address + take precedence over the source address). * ip_address - IP to be used for rewriting SDP. If not specified, the received signalling IP will be used. The parameter allows pseudo-variables usage. NOTE: For the IP to be used, you need to - use 0x02 or 0x08 flags, otherwise it will have no effect. + use 0x02 or 0x08 flags, otherwise it will have no effect. Must be + IPv4 address family. This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, FAILURE_ROUTE, BRANCH_ROUTE. diff --git a/src/modules/nathelper/doc/nathelper_admin.xml b/src/modules/nathelper/doc/nathelper_admin.xml index c73baf21a..5096a676d 100644 --- a/src/modules/nathelper/doc/nathelper_admin.xml +++ b/src/modules/nathelper/doc/nathelper_admin.xml @@ -562,7 +562,7 @@ if (search("User-Agent: Cisco ATA.*") {fix_nated_contact();}; 0x02 - rewrite media &ip; address (c=) with source address of the message - or the provided IP address (the provide IP address take + or the provided IP address. (a=rtcp) param will be rewritten if exists. (the provided IP address take precedence over the source address). @@ -572,7 +572,7 @@ if (search("User-Agent: Cisco ATA.*") {fix_nated_contact();}; 0x08 - rewrite IP from origin description (o=) with source address of the message - or the provided IP address (the provide IP address take + or the provided IP address. (a=rtcp) param will be rewritten if exists. (the provided IP address take precedence over the source address). @@ -582,7 +582,7 @@ if (search("User-Agent: Cisco ATA.*") {fix_nated_contact();}; If not specified, the received signalling IP will be used. The parameter allows pseudo-variables usage. NOTE: For the IP to be used, you need to use 0x02 or 0x08 flags, otherwise it will have - no effect. + no effect. Must be IPv4 address family. diff --git a/src/modules/nathelper/nathelper.c b/src/modules/nathelper/nathelper.c index 396e8b532..12206ba15 100644 --- a/src/modules/nathelper/nathelper.c +++ b/src/modules/nathelper/nathelper.c @@ -116,7 +116,7 @@ static int pv_get_rr_count_f(struct sip_msg *, pv_param_t *, pv_value_t *); static int pv_get_rr_top_count_f(struct sip_msg *, pv_param_t *, pv_value_t *); static int fix_nated_sdp_f(struct sip_msg *, char *, char *); static int is_rfc1918_f(struct sip_msg *, char *, char *); -static int extract_mediaip(str *, str *, int *, char *); +static int nh_extract_mediaip(str *, str *, int *, char *, int); static int alter_mediaip(struct sip_msg *, str *, str *, int, str *, int, int); static int fix_nated_register_f(struct sip_msg *, char *, char *); static int fixup_fix_nated_register(void **param, int param_no); @@ -1611,7 +1611,7 @@ static int is_rfc1918_f(struct sip_msg *msg, char *str1, char *str2) /* replace ip addresses in SDP and return umber of replacements */ static inline int replace_sdp_ip( - struct sip_msg *msg, str *org_body, char *line, str *ip) + struct sip_msg *msg, str *org_body, char *line, str *ip, int linelen) { str body1, oldip, newip; str body = *org_body; @@ -1631,7 +1631,7 @@ static inline int replace_sdp_ip( } body1 = body; for(;;) { - if(extract_mediaip(&body1, &oldip, &pf, line) == -1) + if(nh_extract_mediaip(&body1, &oldip, &pf, line, linelen) == -1) break; if(pf != AF_INET) { LM_ERR("not an IPv4 address in '%s' SDP\n", line); @@ -1734,20 +1734,31 @@ static int ki_fix_nated_sdp_ip(sip_msg_t *msg, int level, str *ip) } } - if(level & FIX_MEDIP) { - /* Iterate all c= and replace ips in them. */ - ret = replace_sdp_ip(msg, &body, "c=", (ip && ip->len>0) ? ip : 0); - if(ret == -1) - return -1; - count += ret; - } + if(level & (FIX_MEDIP | FIX_ORGIP)) { - if(level & FIX_ORGIP) { - /* Iterate all o= and replace ips in them. */ - ret = replace_sdp_ip(msg, &body, "o=", (ip && ip->len>0) ? ip : 0); + /* Iterate all a=rtcp and replace ips in them. rfc3605 */ + ret = replace_sdp_ip(msg, &body, "a=rtcp", (ip && ip->len>0) ? ip : 0, 6); if(ret == -1) - return -1; - count += ret; + LM_DBG("a=rtcp parameter does not exist. nothing to do.\n"); + else + count += ret; + + if(level & FIX_MEDIP) { + /* Iterate all c= and replace ips in them. */ + ret = replace_sdp_ip(msg, &body, "c=", (ip && ip->len>0) ? ip : 0, 2); + if(ret == -1) + return -1; + count += ret; + } + + if(level & FIX_ORGIP) { + /* Iterate all o= and replace ips in them. */ + ret = replace_sdp_ip(msg, &body, "o=", (ip && ip->len>0) ? ip : 0, 2); + if(ret == -1) + return -1; + count += ret; + } + } return count > 0 ? 1 : 2; @@ -1775,22 +1786,23 @@ static int fix_nated_sdp_f(struct sip_msg *msg, char *str1, char *str2) return ki_fix_nated_sdp_ip(msg, level, &ip); } -static int extract_mediaip(str *body, str *mediaip, int *pf, char *line) +static int nh_extract_mediaip(str *body, str *mediaip, int *pf, char *line, + int linelen) { char *cp, *cp1; int len, nextisip; cp1 = NULL; for(cp = body->s; (len = body->s + body->len - cp) > 0;) { - cp1 = ser_memmem(cp, line, len, 2); + cp1 = ser_memmem(cp, line, len, linelen); if(cp1 == NULL || cp1[-1] == '\n' || cp1[-1] == '\r') break; - cp = cp1 + 2; + cp = cp1 + linelen; } if(cp1 == NULL) return -1; - mediaip->s = cp1 + 2; + mediaip->s = cp1 + linelen; mediaip->len = eat_line(mediaip->s, body->s + body->len - mediaip->s) - mediaip->s; trim_len(mediaip->len, mediaip->s, *mediaip); diff --git a/src/modules/ndb_redis/redis_client.c b/src/modules/ndb_redis/redis_client.c index 5ad063f89..bd97012c8 100644 --- a/src/modules/ndb_redis/redis_client.c +++ b/src/modules/ndb_redis/redis_client.c @@ -770,7 +770,7 @@ int redisc_exec_pipelined(redisc_server_t *rsrv) /* null reply, reconnect and try again */ if (rsrv->ctxRedis->err) { - LM_ERR("Redis error: %s\n", rsrv->ctxRedis->errstr); + LM_DBG("Redis error: %s\n", rsrv->ctxRedis->errstr); } if (redisc_create_pipelined_message(rsrv) == 0) { diff --git a/src/modules/nsq/defs.h b/src/modules/nsq/defs.h deleted file mode 100644 index abb7be907..000000000 --- a/src/modules/nsq/defs.h +++ /dev/null @@ -1,130 +0,0 @@ -/* - * NSQ module - * - * Copyright (C) 2010-2014 2600Hz - * - * This file is part of Kamailio, a free SIP server. - * - * 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 - * - * 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. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - * - * Contributor(s): - * Emmanuel Schmidbauer - * - */ - -#ifndef _NSQ_DEFS_H_ -#define _NSQ_DEFS_H_ - -#define BLF_MAX_DIALOGS 8 -#define BLF_JSON_PRES "Presentity" -#define BLF_JSON_PRES_USER "Presentity-User" -#define BLF_JSON_PRES_REALM "Presentity-Realm" -#define BLF_JSON_FROM "From" -#define BLF_JSON_FROM_USER "From-User" -#define BLF_JSON_FROM_REALM "From-Realm" -#define BLF_JSON_FROM_URI "From-URI" -#define BLF_JSON_TO "To" -#define BLF_JSON_TO_USER "To-User" -#define BLF_JSON_TO_REALM "To-Realm" -#define BLF_JSON_TO_URI "To-URI" -#define BLF_JSON_CALLID "Call-ID" -#define BLF_JSON_TOTAG "To-Tag" -#define BLF_JSON_FROMTAG "From-Tag" -#define BLF_JSON_STATE "State" -#define BLF_JSON_USER "User" -#define BLF_JSON_QUEUE "Queue" -#define BLF_JSON_EXPIRES "Expires" -#define BLF_JSON_APP_NAME "App-Name" -#define BLF_JSON_APP_VERSION "App-Version" -#define BLF_JSON_NODE "Node" -#define BLF_JSON_SERVERID "Server-ID" -#define BLF_JSON_EVENT_CATEGORY "Event-Category" -#define BLF_JSON_EVENT_NAME "Event-Name" -#define BLF_JSON_TYPE "Type" -#define BLF_JSON_MSG_ID "Msg-ID" -#define BLF_JSON_DIRECTION "Direction" - -#define BLF_JSON_CONTACT "Contact" -#define BLF_JSON_EVENT_PKG "Event-Package" -#define MWI_JSON_WAITING "Messages-Waiting" -#define MWI_JSON_VOICE_MESSAGE "MWI-Voice-Message" -#define MWI_JSON_NEW "Messages-New" -#define MWI_JSON_SAVED "Messages-Saved" -#define MWI_JSON_URGENT "Messages-Urgent" -#define MWI_JSON_URGENT_SAVED "Messages-Urgent-Saved" -#define MWI_JSON_ACCOUNT "Message-Account" -#define MWI_JSON_FROM "From" -#define MWI_JSON_TO "To" - -#define DIALOGINFO_BODY_BUFFER_SIZE 8192 -#define MWI_BODY_BUFFER_SIZE 2048 -#define PRESENCE_BODY_BUFFER_SIZE 4096 - -#define MWI_BODY_VOICE_MESSAGE "Messages-Waiting: %.*s\r\nMessage-Account: %.*s\r\nVoice-Message: %.*s\r\n" -#define MWI_BODY_NO_VOICE_MESSAGE "Messages-Waiting: %.*s\r\nMessage-Account: %.*s\r\n" -#define MWI_BODY "Messages-Waiting: %.*s\r\nMessage-Account: %.*s\r\nVoice-Message: %.*s/%.*s (%.*s/%.*s)\r\n" -#define PRESENCE_BODY "\ - \ -\ -\ -%s\ -\ -\ -%s\ -\ -%s\ -%s\ -\ -" - -#define DIALOGINFO_EMPTY_BODY "\ - \ -\ -terminated\ -\ -" - -#define LOCAL_TAG "local-tag=\"%.*s\"" -#define REMOTE_TAG "remote-tag=\"%.*s\"" - -#define DIALOGINFO_BODY "\ -\ -\ -%.*s\ -\ -%.*s\ -\ -\ -\ -%.*s\ -\ -\ -\ -" - -#define DIALOGINFO_BODY_2 "\ -\ -\ -%.*s\ -\ -%.*s\ -\ -\ -%.*s\ -\ -\ -" - -#endif /* _NSQ_DEFS_H_ */ diff --git a/src/modules/permissions/permissions.c b/src/modules/permissions/permissions.c index 18cf398f8..be22963d8 100644 --- a/src/modules/permissions/permissions.c +++ b/src/modules/permissions/permissions.c @@ -1058,6 +1058,11 @@ static sr_kemi_t sr_kemi_permissions_exports[] = { { SR_KEMIP_STR, SR_KEMIP_INT, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } }, + { str_init("permissions"), str_init("allow_trusted"), + SR_KEMIP_INT, ki_allow_trusted, + { SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE, + SR_KEMIP_NONE, SR_KEMIP_NONE, SR_KEMIP_NONE } + }, { {0, 0}, {0, 0}, 0, NULL, { 0, 0, 0, 0, 0, 0 } } }; diff --git a/src/modules/permissions/trusted.c b/src/modules/permissions/trusted.c index eed104158..2f9c7d42a 100644 --- a/src/modules/permissions/trusted.c +++ b/src/modules/permissions/trusted.c @@ -507,7 +507,7 @@ int allow_trusted(struct sip_msg* msg, char *src_ip, int proto, char *from_uri) * Checks based on request's source address, protocol, and From URI * if request can be trusted without authentication. */ -int allow_trusted_0(struct sip_msg* _msg, char* str1, char* str2) +int ki_allow_trusted(sip_msg_t* _msg) { str furi; char furi_string[MAX_URI_SIZE+1]; @@ -530,6 +530,15 @@ int allow_trusted_0(struct sip_msg* _msg, char* str1, char* str2) furi_string); } +/* + * Checks based on request's source address, protocol, and From URI + * if request can be trusted without authentication. + */ +int allow_trusted_0(struct sip_msg* _msg, char* str1, char* str2) +{ + return ki_allow_trusted(_msg); +} + /* * Checks based on source address and protocol given in pvar arguments and * provided uri, if request can be trusted without authentication. diff --git a/src/modules/permissions/trusted.h b/src/modules/permissions/trusted.h index 8a8ab2cc1..72da2d70e 100644 --- a/src/modules/permissions/trusted.h +++ b/src/modules/permissions/trusted.h @@ -55,6 +55,10 @@ int reload_trusted_table(void); */ void clean_trusted(void); +/* + * Check if request comes from trusted ip address with matching from URI + */ +int ki_allow_trusted(sip_msg_t* _msg); /* * Check if request comes from trusted ip address with matching from URI diff --git a/src/modules/phonenum/README b/src/modules/phonenum/README index ebe872869..096a3efa4 100644 --- a/src/modules/phonenum/README +++ b/src/modules/phonenum/README @@ -161,6 +161,13 @@ if(phonenum_match("1-484-555-8888", "src")) { letter, e.g: "DE", "US", "ES"). The function has to be called before accessing a key via: $phn(pvc=>key). + Note from libphonenumber library docs: country name code is the region + that is expected the number to be from. It is only used if the number + being parsed is not written in international format. The country code + for the number in this case would be stored as that of the region + supplied. If the number is guaranteed to start with a '+' followed by + the country calling code, then region 'ZZ'. + The parameters can be static strings or strings with variables. It can be used from ANY_ROUTE. diff --git a/src/modules/phonenum/doc/phonenum_admin.xml b/src/modules/phonenum/doc/phonenum_admin.xml index d30c2026e..f3a3e98ed 100644 --- a/src/modules/phonenum/doc/phonenum_admin.xml +++ b/src/modules/phonenum/doc/phonenum_admin.xml @@ -156,6 +156,14 @@ if(phonenum_match("1-484-555-8888", "src")) { (two letter, e.g: "DE", "US", "ES"). The function has to be called before accessing a key via: $phn(pvc=>key). + + Note from libphonenumber library docs: country name code is the region + that is expected the number to be from. It is only used if the number + being parsed is not written in international format. The country code + for the number in this case would be stored as that of the region + supplied. If the number is guaranteed to start with a '+' followed + by the country calling code, then region 'ZZ'. + The parameters can be static strings or strings with variables. diff --git a/src/modules/pipelimit/pl_statistics.c b/src/modules/pipelimit/pl_statistics.c index e1afa2ffb..0c6c52d38 100644 --- a/src/modules/pipelimit/pl_statistics.c +++ b/src/modules/pipelimit/pl_statistics.c @@ -137,10 +137,12 @@ int get_socket_list_from_proto_and_family(int **ipList, int protocol, int family struct socket_info *si; struct socket_info** list; - int num_ip_octets = family == AF_INET ? NUM_IP_OCTETS : NUM_IPV6_OCTETS; - int numberOfSockets = 0; + unsigned int num_ip_octets = 0; + unsigned int numberOfSockets = 0; int currentRow = 0; + num_ip_octets = (family == AF_INET) ? NUM_IP_OCTETS : NUM_IPV6_OCTETS; + /* I hate to use #ifdefs, but this is necessary because of the way * get_sock_info_list() is defined. */ #ifndef USE_TCP @@ -198,7 +200,7 @@ int get_socket_list_from_proto_and_family(int **ipList, int protocol, int family /* Extract out the IP Addresses and ports. */ for(si=list?*list:0; si; si=si->next){ - int i; + unsigned int i; /* We currently only support IPV4. */ if (si->address.af != family) { diff --git a/src/modules/pv/pv.c b/src/modules/pv/pv.c index 4d3d8b343..ab48a5464 100644 --- a/src/modules/pv/pv.c +++ b/src/modules/pv/pv.c @@ -96,10 +96,10 @@ static pv_export_t mod_pvs[] = { pv_parse_xavp_name, 0, 0, 0 }, { {"xavu", sizeof("xavu")-1}, /* xavu */ PVT_XAVU, pv_get_xavu, pv_set_xavu, - pv_parse_xavp_name, 0, 0, 0 }, + pv_parse_xavu_name, 0, 0, 0 }, { {"xavi", sizeof("xavi")-1}, /* xavi */ PVT_XAVI, pv_get_xavi, pv_set_xavi, - pv_parse_xavp_name, 0, 0, 0 }, + pv_parse_xavi_name, 0, 0, 0 }, {{"avp", (sizeof("avp")-1)}, PVT_AVP, pv_get_avp, pv_set_avp, pv_parse_avp_name, pv_parse_index, 0, 0}, {{"hdr", (sizeof("hdr")-1)}, PVT_HDR, pv_get_hdr, 0, pv_parse_hdr_name, @@ -1221,7 +1221,7 @@ static int w_xav_child_seti(sip_msg_t *msg, char *prname, char *pcname, return -1; } - return ki_xav_child_seti(msg, &rname, &cname, ival, _case); + return ki_xav_child_seti(msg, &rname, &cname, ival, _case); } static int w_xavp_child_seti(sip_msg_t *msg, char *prname, char *pcname, diff --git a/src/modules/pv/pv_time.c b/src/modules/pv/pv_time.c index 87b62b71e..4a9cc14dd 100644 --- a/src/modules/pv/pv_time.c +++ b/src/modules/pv/pv_time.c @@ -246,12 +246,16 @@ int pv_get_timenowf(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { str s; - char t_buf[26] = {0}; + static char t_buf[26] = {0}; time_t t; t = time(NULL); s.s = ctime_r(&t, t_buf); + if(s.s == NULL) { + return pv_get_null(msg, param, res); + } + s.s = t_buf; s.len = strlen(s.s)-1; return pv_get_strintval(msg, param, res, &s, (int)t); } @@ -271,7 +275,7 @@ int pv_get_timef(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { str s; - char t_buf[26] = {0}; + static char t_buf[26] = {0}; if(msg==NULL) return -1; @@ -279,6 +283,10 @@ int pv_get_timef(struct sip_msg *msg, pv_param_t *param, msg_set_time(msg); s.s = ctime_r(&msg->tval.tv_sec, t_buf); + if(s.s == NULL) { + return pv_get_null(msg, param, res); + } + s.s = t_buf; s.len = strlen(s.s)-1; return pv_get_strintval(msg, param, res, &s, (int)msg->tval.tv_sec); } diff --git a/src/modules/pv/pv_trans.c b/src/modules/pv/pv_trans.c index d07e55e71..3c547305a 100644 --- a/src/modules/pv/pv_trans.c +++ b/src/modules/pv/pv_trans.c @@ -909,6 +909,7 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype, if(!(val->flags&PV_VAL_STR)) val->rs.s = int2str(val->ri, &val->rs.len); + /* Set maximum prefix length */ max = val->rs.len; if(tp!=NULL) { @@ -947,7 +948,7 @@ int tr_eval_string(struct sip_msg *msg, tr_param_t *tp, int subtype, memset(val, 0, sizeof(pv_value_t)); val->flags = PV_VAL_STR; val->rs.s = _tr_buffer; - val->rs.len = j-1; + val->rs.len = (j>0)?(j-1):0; break; @@ -2687,7 +2688,7 @@ char* tr_parse_string(str* in, trans_t *t) while(*p && (*p==' ' || *p=='\t' || *p=='\n')) p++; if(*p!=TR_RBRACKET) { - LM_ERR("invalid ftime transformation: %.*s!!\n", + LM_ERR("invalid rm transformation: %.*s!!\n", in->len, in->s); goto error; } diff --git a/src/modules/pv/pv_xavp.c b/src/modules/pv/pv_xavp.c index 9510c405b..36127a248 100644 --- a/src/modules/pv/pv_xavp.c +++ b/src/modules/pv/pv_xavp.c @@ -234,7 +234,7 @@ int pv_set_xavp(struct sip_msg* msg, pv_param_t *param, xavp_rm_by_index(&xname->name, idx, NULL); return 0; } - + if(xname->next->index.type==PVT_EXTRA) { /* get the index */ @@ -352,7 +352,7 @@ int pv_set_xavp(struct sip_msg* msg, pv_param_t *param, return -1; return 0; } - + /* xavp with xavp list value */ if(xname->next->index.type==PVT_EXTRA) { @@ -389,7 +389,7 @@ int pv_set_xavp(struct sip_msg* msg, pv_param_t *param, if(avp->val.type!=SR_XTYPE_XAVP) return -1; - + if(xname->next->index.type==PVT_EXTRA) { if(idxf1==PV_IDX_ALL) { /* ignore: should iterate and set same value to all xavps @@ -416,7 +416,7 @@ int pv_set_xavp(struct sip_msg* msg, pv_param_t *param, /* add new xavp with xavp list */ if(xavp_add_value(&xname->next->name, &xval, &list)==NULL) return -1; - + /* build xavp value */ memset(&xval, 0, sizeof(sr_xval_t)); xval.type = SR_XTYPE_XAVP; @@ -895,7 +895,7 @@ int pv_set_xavu(struct sip_msg* msg, pv_param_t *param, xavu_rm_by_name(&xname->name, NULL); return 0; } - + avu = xavu_lookup(&xname->name, NULL); if(avu!=NULL && avu->val.type==SR_XTYPE_XAVP) { xavu_rm_by_name(&xname->next->name, &avu->val.v.xavp); diff --git a/src/modules/pv_headers/pvh_hash.c b/src/modules/pv_headers/pvh_hash.c index 89f93f77b..80297bcaa 100644 --- a/src/modules/pv_headers/pvh_hash.c +++ b/src/modules/pv_headers/pvh_hash.c @@ -85,6 +85,7 @@ int pvh_str_hash_add_key(struct str_hash_table *ht, str *key) err: pvh_str_free(&e->key); + pkg_free(e); return -1; } diff --git a/src/modules/pv_headers/pvh_xavp.c b/src/modules/pv_headers/pvh_xavp.c index ad5ba9dda..7cba75745 100644 --- a/src/modules/pv_headers/pvh_xavp.c +++ b/src/modules/pv_headers/pvh_xavp.c @@ -539,38 +539,33 @@ int pvh_get_header(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) sr_xavp_t *xavi = NULL; sr_xval_t *xval = NULL; pv_value_t tv; - str hname = STR_NULL; - int idx = 0; + str *hname = NULL; + int idx, idxf; int cnt = 0; - idx = param->pvi.u.ival; + if(pv_get_spec_name(msg, param, &tv) != 0 || (!(tv.flags & PV_VAL_STR))) { + LM_ERR("invalid header name, must be a string\n"); + return -1; + } + hname = &tv.rs; - if(param->pvn.type == PV_NAME_PVAR) { - if(pv_get_spec_value(msg, (pv_spec_p)(param->pvn.u.dname), &tv) != 0) { - LM_ERR("cannot get avp value\n"); - return -1; - } - if(!(tv.flags & PV_VAL_STR)) { - return pv_get_null(msg, param, res); - } - hname = tv.rs; - } else if(param->pvn.u.isname.type == AVP_NAME_STR) { - hname = param->pvn.u.isname.name.s; - } else { - return pv_get_null(msg, param, res); + /* get the index */ + if(pv_get_spec_index(msg, param, &idx, &idxf) != 0) { + LM_ERR("invalid index\n"); + return -1; } if(idx < 0) { - if((xavi = pvh_xavi_get_child(msg, &xavi_name, &hname)) == NULL) + if((xavi = pvh_xavi_get_child(msg, &xavi_name, hname)) == NULL) cnt = 0; else - cnt = xavi_count(&hname, &xavi); + cnt = xavi_count(hname, &xavi); idx = idx + cnt; if(idx < 0) - pv_get_null(msg, param, res); + return pv_get_null(msg, param, res); } - xval = pvh_xavi_get_value(msg, &xavi_name, &hname, idx); + xval = pvh_xavi_get_value(msg, &xavi_name, hname, idx); if(xval == NULL || !xval->v.s.s) return pv_get_null(msg, param, res); diff --git a/src/modules/regex/regex_mod.c b/src/modules/regex/regex_mod.c index 475c3542e..2bc521040 100644 --- a/src/modules/regex/regex_mod.c +++ b/src/modules/regex/regex_mod.c @@ -246,6 +246,7 @@ static int load_pcres(int action) int pcre_erroffset; int num_pcres_tmp = 0; pcre **pcres_tmp = NULL; + int llen; /* Get the lock */ lock_get(reload_lock); @@ -301,31 +302,37 @@ static int load_pcres(int action) } /* Start the regular expression with '(' */ patterns[i][0] = '('; + patterns[i][1] = '\0'; memset(line, 0, FILE_MAX_LINE); continue; } + llen = strlen(line); /* Check if the patter size is too big (aprox) */ - if (strlen(patterns[i]) + strlen(line) >= group_max_size - 4) { + if (strlen(patterns[i]) + llen >= group_max_size - 4) { LM_ERR("pattern max file exceeded\n"); fclose(f); goto err; } /* Append ')' at the end of the line */ - if (line[strlen(line) - 1] == '\n') { - line[strlen(line)] = line[strlen(line) - 1]; - line[strlen(line) - 2] = ')'; + if (line[llen - 1] == '\n') { + line[llen - 1] = ')'; + line[llen] = '\n'; + line[llen + 1] = '\0'; } else { /* This is the last char in the file and it's not \n */ - line[strlen(line)] = ')'; + line[llen] = ')'; + line[llen + 1] = '\0'; } /* Append '(' at the beginning of the line */ - memcpy(patterns[i]+strlen(patterns[i]), "(", 1); + llen = strlen(patterns[i]); + memcpy(patterns[i]+llen, "(", 1); + llen++; - /* Append the line to the current pattern */ - memcpy(patterns[i]+strlen(patterns[i]), line, strlen(line)); + /* Append the line to the current pattern (including the ending 0) */ + memcpy(patterns[i] + llen, line, strlen(line) + 1); memset(line, 0, FILE_MAX_LINE); } diff --git a/src/modules/registrar/README b/src/modules/registrar/README index fe9c969ce..7df142cb0 100644 --- a/src/modules/registrar/README +++ b/src/modules/registrar/README @@ -254,21 +254,22 @@ Chapter 1. Admin Guide If path support is enabled in the registrar module, a call to save(...) stores the values of the Path Header(s) along with the contact into usrloc. There are three modes regarding the reply to a REGISTER - including one or more Path HFs: + including one or more Path header fields: * off - stores the value of the Path headers into usrloc without passing it back to the UAC in the reply. * lazy - stores the Path header and passes it back to the UAC if - Path-support is indicated by the “path” param in the Supported HF. + Path-support is indicated by the “path” param in the Supported + header field. * strict - rejects the registration with “420 Bad Extension” if there's a Path header but no support for it is indicated by the UAC. Otherwise it's stored and passed back to the UAC. A call to lookup(...) always uses the path header if found, and inserts - it as Route HF either in front of the first Route HF, or after the last - Via HF if no Route is present. It also sets the destination uri to the - first Path uri, thus overwriting the received-uri, because NAT has to - be handled at the outbound-proxy of the UAC (the first hop after - client's NAT). + it as Route header field either in front of the first Route header + field, or after the last Via header field if no Route is present. It + also sets the destination uri to the first Path uri, thus overwriting + the received-uri, because NAT has to be handled at the outbound-proxy + of the UAC (the first hop after client's NAT). The whole process is transparent to the user, so no config changes are required beside setting the registrar-parameters “use_path” and @@ -341,10 +342,10 @@ Chapter 1. Admin Guide 3.1. default_expires (integer) - If the processed message contains neither Expires HFs nor expires - contact parameters, this value will be used for newly created 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 + If the processed message contains neither Expires header fields nor + expires contact parameters, this value will be used for newly created + 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 @@ -955,18 +956,19 @@ kamcmd cfg.set_now_int registrar use_expired_contacts 0 4.1. save(domain, [, flags [, uri]]) The function processes a REGISTER message. It can add, remove or modify - location records (in usrloc) depending on Contact and Expires HFs in - the REGISTER message. On success and when called from the + location records (in usrloc) depending on Contact and Expires header + fields 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 the location database. On an error, an error message will - be sent with a short description in reason phrase. + currently in the location database. As a side effect, also branch flags + are stored in usrloc. On an error, an error message will be sent with a + short description in reason phrase. Meaning of the parameters is as follows: * domain - Logical domain within the registrar. If a database is used then this must be name of the table which stores the contacts. * flags (optional) - the value may be a bitwise OR of the following flags: - + 0x01 - save the contacts only in memory cache without no DB + + 0x01 - save the contacts only in memory cache with no DB operation; + 0x02 - do not generate a SIP reply to the current REGISTER request. When used in ONREPLY_ROUTE, this parameter is @@ -1007,7 +1009,8 @@ save("location", "0x00", "sip:test@kamailio.org"); no such contacts, -1 will be returned. If there are such contacts, Request-URI will be overwritten with the contact that has the highest q value and optionally the rest will be appended to the message - (depending on append_branches parameter value). + (depending on append_branches parameter value). As a side effect, also + branch flags are restored from usrloc. If the method_filtering option is enabled and request is initial request without to-tag, the lookup function will return only the diff --git a/src/modules/registrar/doc/registrar_admin.xml b/src/modules/registrar/doc/registrar_admin.xml index e3140965d..266f7b35e 100644 --- a/src/modules/registrar/doc/registrar_admin.xml +++ b/src/modules/registrar/doc/registrar_admin.xml @@ -28,7 +28,7 @@ If path support is enabled in the registrar module, a call to save(...) stores the values of the Path Header(s) along with the contact into usrloc. There are three modes regarding the reply to a REGISTER including - one or more Path HFs: + one or more Path header fields: @@ -42,7 +42,7 @@ lazy - stores the Path header and passes it back to the UAC if Path-support is indicated - by the path param in the Supported HF. + by the path param in the Supported header field. @@ -56,8 +56,8 @@ A call to lookup(...) always uses the path header if - found, and inserts it as Route HF either in front of - the first Route HF, or after the last Via HF if no + found, and inserts it as Route header field either in front of + the first Route header field, or after the last Via header field if no Route is present. It also sets the destination uri to the first Path uri, thus overwriting the received-uri, because NAT has to be handled at the outbound-proxy of @@ -131,7 +131,7 @@ <varname>default_expires</varname> (integer) If the processed message contains neither Expires - HFs nor expires contact parameters, this value + header fields nor expires contact parameters, this value will be used for newly created 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 @@ -1151,10 +1151,11 @@ kamcmd cfg.set_now_int registrar use_expired_contacts 0 The function processes a REGISTER message. It can add, remove or - modify location records (in usrloc) depending on Contact and Expires HFs in the + modify location records (in usrloc) depending on Contact and Expires header fields 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 - the location database. On an error, an error message will be sent with a short + the location database. As a side effect, also branch flags are + stored in usrloc. On an error, an error message will be sent with a short description in reason phrase. Meaning of the parameters is as follows: @@ -1174,7 +1175,7 @@ kamcmd cfg.set_now_int registrar use_expired_contacts 0 0x01 - save the contacts only - in memory cache without no DB operation; + in memory cache with no DB operation; @@ -1255,6 +1256,7 @@ save("location", "0x00", "sip:test@kamailio.org"); Request-URI will be overwritten with the contact that has the highest q value and optionally the rest will be appended to the message (depending on append_branches parameter value). + As a side effect, also branch flags are restored from usrloc. If the method_filtering option is enabled and diff --git a/src/modules/rr/README b/src/modules/rr/README index 9f3917c48..0ac781243 100644 --- a/src/modules/rr/README +++ b/src/modules/rr/README @@ -370,7 +370,8 @@ modparam("rr", "ignore_sips", 1) 4.9. sockname_mode (int) If set to 1, the Record-Route URI is built to contain socket name in - 'sn' parameter. + 'sn' parameter and then it is used to lookup the local socket for Route + header processing. Default value is 0. @@ -502,8 +503,8 @@ remove_record_route(); 5.5. record_route_preset(string [,string2]) - This function will put the string into Record-Route, don't use unless - you know what you are doing. + This function will put the string params into Record-Route, avoid to + use it unless you know what you are doing. Meaning of the parameters is as follows: * string - String to be inserted into the first header field; it may @@ -515,6 +516,13 @@ remove_record_route(); the outbound interface and the 'string2' param is pointing to the inbound interface. + Note: The value of parameters must not contain the SIP protocol scheme + (sip: or sips:), one is added based on routing requirements. Thus the + value has to be like "address:port;parameters", the port and parameters + are optional. If the second parameter is provided, do not forget to add + the parameter "r2=on" so the proxy processes both corresponding Route + headers at once. + When the “outbound” module was loaded before this module this function will determine whether outbound is required for the request and generate and add a flow-token as the username part of the @@ -559,9 +567,9 @@ record_route_advertised_address("1.2.3.4:5080"); Adds a parameter to the Record-Route URI (param must be in “;name=value” format. The function may be called also before or after - the record_route() or record_route_advertised_address() calls (see - Section 5.3, “record_route([sparams])” or Section 5.6, - “record_route_advertised_address(address)”)). + the record_route(), record_route_advertised_address(), and + record_route_preset() calls (see Section 5.3, “record_route([sparams])” + or Section 5.6, “record_route_advertised_address(address)”)). Meaning of the parameters is as follows: * param - String containing the URI parameter to be added. It must diff --git a/src/modules/rr/doc/rr_admin.xml b/src/modules/rr/doc/rr_admin.xml index fb7b4d03c..b623c9d75 100644 --- a/src/modules/rr/doc/rr_admin.xml +++ b/src/modules/rr/doc/rr_admin.xml @@ -317,7 +317,8 @@ modparam("rr", "ignore_sips", 1) <varname>sockname_mode</varname> (int) If set to 1, the Record-Route URI is built to contain socket name in 'sn' - parameter. + parameter and then it is used to lookup the local socket for Route header + processing. @@ -507,8 +508,8 @@ remove_record_route(); <function moreinfo="none">record_route_preset(string [,string2])</function> - This function will put the string into Record-Route, don't use - unless you know what you are doing. + This function will put the string params into Record-Route, avoid + to use it unless you know what you are doing. Meaning of the parameters is as follows: @@ -528,6 +529,13 @@ remove_record_route(); to the outbound interface and the 'string2' param is pointing to the inbound interface. + Note: The value of parameters must not contain the SIP protocol + scheme (sip: or sips:), one is added based on routing requirements. Thus + the value has to be like "address:port;parameters", the port and + parameters are optional. If the second parameter is provided, do not + forget to add the parameter "r2=on" so the proxy processes both + corresponding Route headers at once. + When the outbound module was loaded before this module this function will determine whether outbound is required for the request and generate and add a flow-token as the username part of the @@ -593,7 +601,8 @@ record_route_advertised_address("1.2.3.4:5080"); Adds a parameter to the Record-Route URI (param must be in ;name=value format. The function may be called also - before or after the record_route() or record_route_advertised_address() + before or after the record_route(), + record_route_advertised_address(), and record_route_preset() calls (see or )). diff --git a/src/modules/rr/loose.c b/src/modules/rr/loose.c index 5efc50977..0ba6ad5e5 100644 --- a/src/modules/rr/loose.c +++ b/src/modules/rr/loose.c @@ -761,9 +761,9 @@ static inline void rr_do_force_send_socket(sip_msg_t *_m, sip_uri_t *puri, return; } for (pit = plist; pit; pit=pit->next) { - if (pit->name.len==SOCKNAME_PARAM_LEN - && strncasecmp(pit->name.s, SOCKNAME_PARAM, - SOCKNAME_PARAM_LEN)==0) { + if (pit->name.len==SOCKNAME_ATTR_LEN + && strncasecmp(pit->name.s, SOCKNAME_ATTR, + SOCKNAME_ATTR_LEN)==0) { if(pit->body.len>0) { si = ksr_get_socket_by_name(&pit->body); if(si != NULL) { diff --git a/src/modules/rr/record.c b/src/modules/rr/record.c index 0b7435690..f757f4676 100644 --- a/src/modules/rr/record.c +++ b/src/modules/rr/record.c @@ -504,11 +504,14 @@ int record_route_preset(struct sip_msg* _m, str* _data) str user = {NULL, 0}; struct to_body* from = NULL; struct lump* l; - char* hdr, *p; - int hdr_len; + struct lump* l2; + char *p; + str hdr = STR_NULL; int use_ob = rr_obb.use_outbound ? rr_obb.use_outbound(_m) : 0; char *rr_prefix; int rr_prefix_len; + str suffix = STR_NULL; + str term = STR_NULL; int sips = 0; int ret = 0; @@ -549,38 +552,53 @@ int record_route_preset(struct sip_msg* _m, str* _data) from = get_from(_m); } + if (rr_param_buf.len && rr_param_msg!=_m->id) { + /* rr_params were set for a different message -> reset buffer */ + rr_param_buf.len = 0; + } + l = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, HDR_RECORDROUTE_T); - if (!l) { - LM_ERR("failed to create lump anchor\n"); + l2 = anchor_lump(_m, _m->headers->name.s - _m->buf, 0, 0); + if (!l || !l2) { + LM_ERR("failed to create lump anchors\n"); ret = -3; goto error; } - hdr_len = rr_prefix_len; + hdr.len = rr_prefix_len; if (user.len) - hdr_len += user.len + 1; /* @ */ - hdr_len += _data->len; + hdr.len += user.len + 1; /* @ */ + hdr.len += _data->len; if (append_fromtag && from->tag_value.len) { - hdr_len += RR_FROMTAG_LEN + from->tag_value.len; + hdr.len += RR_FROMTAG_LEN + from->tag_value.len; + } + + if (rr_param_buf.len > 0) { + hdr.len += rr_param_buf.len; } if (enable_full_lr) { - hdr_len += RR_LR_FULL_LEN; + suffix.len = RR_LR_FULL_LEN; } else { - hdr_len += RR_LR_LEN; + suffix.len = RR_LR_LEN; } - hdr_len += RR_TERM_LEN; + term.len = RR_TERM_LEN; - hdr = pkg_malloc(hdr_len); - if (!hdr) { + hdr.s = pkg_malloc(hdr.len); + suffix.s = pkg_malloc(suffix.len); + term.s = pkg_malloc(term.len); + if (!hdr.s || !suffix.s || !term.s) { LM_ERR("no pkg memory left\n"); + if(hdr.s) pkg_free(hdr.s); + if(suffix.s) pkg_free(suffix.s); + if(term.s) pkg_free(term.s); ret = -4; goto error; } - p = hdr; + p = hdr.s; memcpy(p, rr_prefix, rr_prefix_len); p += rr_prefix_len; @@ -601,22 +619,42 @@ int record_route_preset(struct sip_msg* _m, str* _data) p += from->tag_value.len; } + if (rr_param_buf.len > 0) { + memcpy(p, rr_param_buf.s, rr_param_buf.len); + p += rr_param_buf.len; + } + + if (enable_full_lr) { - memcpy(p, RR_LR_FULL, RR_LR_FULL_LEN); - p += RR_LR_FULL_LEN; + memcpy(suffix.s, RR_LR_FULL, RR_LR_FULL_LEN); } else { - memcpy(p, RR_LR, RR_LR_LEN); - p += RR_LR_LEN; + memcpy(suffix.s, RR_LR, RR_LR_LEN); } - memcpy(p, RR_TERM, RR_TERM_LEN); + memcpy(term.s, RR_TERM, RR_TERM_LEN); - if (!insert_new_lump_after(l, hdr, hdr_len, 0)) { + if (!insert_new_lump_after(l, hdr.s, hdr.len, 0)) { LM_ERR("failed to insert new lump\n"); - pkg_free(hdr); + pkg_free(hdr.s); + pkg_free(suffix.s); + pkg_free(term.s); ret = -5; goto error; } + + l2 = insert_new_lump_before(l2, suffix.s, suffix.len, HDR_RECORDROUTE_T); + if (l2 == NULL) { + pkg_free(suffix.s); + pkg_free(term.s); + ret = -6; + goto error; + } + if (!(l2 = insert_new_lump_before(l2, term.s, term.len, 0))) { + pkg_free(term.s); + ret = -7; + goto error; + } + LM_DBG("inserted preset record route\n"); ret = 1; error: @@ -812,6 +850,11 @@ int record_route_advertised_address(struct sip_msg* _m, str* _data) tag = 0; } + if (rr_param_buf.len && rr_param_msg!=_m->id) { + /* rr_params were set for a different message -> reset buffer */ + rr_param_buf.len = 0; + } + if(rr_ignore_sips==0) { sips = rr_is_sips(_m); } @@ -938,3 +981,14 @@ int add_rr_param(struct sip_msg* msg, str* rr_param) error: return -1; } + +/*! + * \brief Reset Record-Route parameters buffer + * \param msg SIP message + * \return 0 on success, -1 on failure + */ +void reset_rr_param(void) +{ + rr_param_buf.len = 0; + return; +} diff --git a/src/modules/rr/record.h b/src/modules/rr/record.h index c76135863..fc3fb64d8 100644 --- a/src/modules/rr/record.h +++ b/src/modules/rr/record.h @@ -82,5 +82,6 @@ int add_rr_param(struct sip_msg* msg, str* rr_param); void init_custom_user(pv_spec_t *custom_user_avp); +void reset_rr_param(void); #endif /* RECORD_H */ diff --git a/src/modules/rr/rr_mod.c b/src/modules/rr/rr_mod.c index 71f5fcc18..12d2e052d 100644 --- a/src/modules/rr/rr_mod.c +++ b/src/modules/rr/rr_mod.c @@ -349,6 +349,8 @@ static int ki_record_route_preset(sip_msg_t *msg, str *addr1, str *addr2) return -1; done: + reset_rr_param(); + msg->msg_flags |= FL_RR_ADDED; return 1; diff --git a/src/modules/rtp_media_server/docker/rtp_media_server.sh b/src/modules/rtp_media_server/docker/rtp_media_server.sh index 02b842ad2..8f31f2062 100755 --- a/src/modules/rtp_media_server/docker/rtp_media_server.sh +++ b/src/modules/rtp_media_server/docker/rtp_media_server.sh @@ -4,7 +4,7 @@ CONTAINER=rtp_media_server IMAGE=rtp_media_server:latest docker stop ${CONTAINER} docker rm ${CONTAINER} -docker run -d --net=host --name=${CONTAINER} ${IMAGE} /bin/sh -c "tail -f /dev/null" +docker run -d --net=host --privileged --name=${CONTAINER} ${IMAGE} /bin/sh -c "tail -f /dev/null" echo "" echo "manual steps required to start Kamailio in the container:" @@ -13,3 +13,8 @@ echo " set the listen IP in /etc/kamailio.cfg" echo " docker exec -it rtp_media_server bash" echo " kamailio -m 64 -D -dd -f /etc/kamailio.cfg" echo "" + +# ulimit -c unlimited +# echo "/tmp/core.%e.sig%s.%p" > /proc/sys/kernel/core_pattern +# sysctl -w kernel.core_pattern=core +# apt-get update && apt-get install -i gdb diff --git a/src/modules/rtp_media_server/rms_dialog_info.c b/src/modules/rtp_media_server/rms_dialog_info.c index 24fe0bb0c..cbe579851 100644 --- a/src/modules/rtp_media_server/rms_dialog_info.c +++ b/src/modules/rtp_media_server/rms_dialog_info.c @@ -19,9 +19,12 @@ */ #include "rtp_media_server.h" + extern rms_dialog_info_t *rms_dialog_list; extern int in_rms_process; +gen_lock_t *dialog_list_mutex; + static void rms_action_free(rms_dialog_info_t *si) { rms_action_t *a, *tmp; @@ -45,8 +48,12 @@ rms_action_t *rms_action_new(rms_action_type_t t) return a; } -int init_rms_dialog_list() +int rms_dialog_list_init() { + dialog_list_mutex = lock_alloc(); + if(!dialog_list_mutex) + return 0; + dialog_list_mutex = lock_init(dialog_list_mutex); rms_dialog_list = shm_malloc(sizeof(rms_dialog_info_t)); if(!rms_dialog_list) return 0; @@ -54,6 +61,34 @@ int init_rms_dialog_list() return 1; } +void rms_dialog_list_free() +{ + lock_destroy(dialog_list_mutex); + lock_dealloc((void*)dialog_list_mutex); + shm_free(rms_dialog_list); +} + +char *rms_dialog_state_toa(rms_dialog_state_t state) { + if (state == 0) return "RMS_ST_DEFAULT"; + else if (state == 1) return "RMS_ST_CONNECTING"; + else if (state == 2) return "RMS_ST_CONNECTED"; + else if (state == 3) return "RMS_ST_CONNECTED_ACK"; + else if (state == 4) return "RMS_ST_DISCONNECTING"; + else if (state == 5) return "RMS_ST_DISCONNECTED"; + return "RMS_ST_UNKNOWN"; +} + +int rms_dialog_info_set_state(rms_dialog_info_t *di, rms_dialog_state_t state) +{ + if (state <= di->state) { + LM_ERR("[%s] >> [%s] (invalid state transition) call-id[%s]\n", rms_dialog_state_toa(di->state), rms_dialog_state_toa(state), di->callid.s); + } else { + LM_NOTICE("[%s] >> [%s] call-id[%s]\n", rms_dialog_state_toa(di->state), rms_dialog_state_toa(state), di->callid.s); + di->state = state; + } + return 1; +} + rms_dialog_info_t *rms_dialog_search(struct sip_msg *msg) // str *from_tag) { rms_dialog_info_t *si; @@ -87,9 +122,9 @@ rms_dialog_info_t *rms_dialog_search(struct sip_msg *msg) // str *from_tag) rms_dialog_info_t *rms_dialog_search_sync(struct sip_msg *msg) { - lock(&dialog_list_mutex); + lock(dialog_list_mutex); rms_dialog_info_t *si = rms_dialog_search(msg); - unlock(&dialog_list_mutex); + unlock(dialog_list_mutex); return si; } @@ -98,9 +133,9 @@ void rms_dialog_add(rms_dialog_info_t *si) if (in_rms_process) { clist_append(rms_dialog_list, si, next, prev); } else { - lock(&dialog_list_mutex); + lock(dialog_list_mutex); clist_append(rms_dialog_list, si, next, prev); - unlock(&dialog_list_mutex); + unlock(dialog_list_mutex); } } @@ -109,9 +144,9 @@ void rms_dialog_rm(rms_dialog_info_t *si) if (in_rms_process) { clist_append(rms_dialog_list, si, next, prev); } else { - lock(&dialog_list_mutex); + lock(dialog_list_mutex); clist_rm(si, next, prev); - unlock(&dialog_list_mutex); + unlock(dialog_list_mutex); } } diff --git a/src/modules/rtp_media_server/rms_dialog_info.h b/src/modules/rtp_media_server/rms_dialog_info.h index 88ed643ee..e8bb3cf30 100644 --- a/src/modules/rtp_media_server/rms_dialog_info.h +++ b/src/modules/rtp_media_server/rms_dialog_info.h @@ -58,7 +58,8 @@ typedef struct rms_action int rms_check_msg(struct sip_msg *msg); rms_action_t *rms_action_new(rms_action_type_t t); -int init_rms_dialog_list(); +int rms_dialog_list_init(); +void rms_dialog_list_free(); rms_dialog_info_t *rms_dialog_search(struct sip_msg *msg); rms_dialog_info_t *rms_dialog_search_sync(struct sip_msg *msg); void rms_dialog_add(rms_dialog_info_t *di); @@ -69,6 +70,7 @@ rms_dialog_info_t *rms_dialog_new_bleg(struct sip_msg *msg); int rms_dialogs_dump_f(struct sip_msg *msg, char *param1, char *param2); rms_dialog_info_t *rms_get_dialog_list(void); + typedef struct ms_res { AudioStream *audio_stream; @@ -79,10 +81,13 @@ typedef enum rms_dialog_state { RMS_ST_DEFAULT, RMS_ST_CONNECTING, RMS_ST_CONNECTED, + RMS_ST_CONNECTED_ACK, RMS_ST_DISCONNECTING, RMS_ST_DISCONNECTED, } rms_dialog_state_t; +int rms_dialog_info_set_state(rms_dialog_info_t *di, rms_dialog_state_t state); + typedef struct rms_dialog_info { struct rms_dialog_info *next; diff --git a/src/modules/rtp_media_server/rtp_media_server.c b/src/modules/rtp_media_server/rtp_media_server.c index 8f2b2592a..6a1fbca63 100644 --- a/src/modules/rtp_media_server/rtp_media_server.c +++ b/src/modules/rtp_media_server/rtp_media_server.c @@ -36,6 +36,8 @@ static char *rms_answer_default_route = "rms:start"; int in_rms_process; rms_t *rms; +struct tm_binds tmb; + static rms_dialog_info_t *rms_dialog_create_leg(rms_dialog_info_t *di, struct sip_msg *msg); static int fixup_rms_action_play(void **param, int param_no); static int fixup_rms_bridge(void **param, int param_no); @@ -173,7 +175,7 @@ static int mod_init(void) rms->udp_last_port = 50000 + kam_rand() % 10000; rms_media_init(); - if(!init_rms_dialog_list()) { + if(!rms_dialog_list_init()) { LM_ERR("can't initialize rms_dialog_list !\n"); return -1; } @@ -223,7 +225,9 @@ static rms_dialog_info_t *rms_stop(rms_dialog_info_t *di) } rms_dialog_info_t *tmp = di->prev; - di->state = RMS_ST_DISCONNECTED; + // not yet, we need the confirmation. + // rms_dialog_info_set_state(di, RMS_ST_DISCONNECTED); + // keep it for a little while to deal with retransmissions ... //clist_rm(di, next, prev); //rms_dialog_free(di); @@ -267,7 +271,7 @@ static rms_dialog_info_t *rms_dialog_action_check(rms_dialog_info_t *di) // rms_stop(di->bridged_di); di = rms_stop(di); a->type = RMS_NONE; - // di->state = RMS_SSTATE_DISCONNECTED; + // rms_dialog_info_set_state(di, RMS_ST_DISCONNECTED); return di; } else if(a->type == RMS_PLAY) { LM_INFO("dialog action RMS_PLAY [%s]\n", di->callid.s); @@ -312,14 +316,14 @@ static void rms_dialog_manage_loop() { in_rms_process = 1; while(1) { - lock(&dialog_list_mutex); + lock(dialog_list_mutex); rms_dialog_info_t *di; clist_foreach(rms_dialog_list, di, next) { di = rms_dialog_action_check(di); //LM_INFO("next ... si[%p]\n", di); } - unlock(&dialog_list_mutex); + unlock(dialog_list_mutex); usleep(10000); } } @@ -426,7 +430,7 @@ static int rms_answer_call( return 0; } LM_INFO("answered\n"); - di->state = RMS_ST_CONNECTED; + rms_dialog_info_set_state(di, RMS_ST_CONNECTED); } else { LM_INFO("no request found\n"); } @@ -471,7 +475,7 @@ static void bridge_cb(struct cell *ptrans, int ntype, struct tmcb_params *pcbp) if(ntype == TMCB_ON_FAILURE) { LM_NOTICE("FAILURE [%d]\n", pcbp->code); rms_action_t *a = (rms_action_t *)*pcbp->param; - a->di->state = RMS_ST_DISCONNECTED; + rms_dialog_info_set_state(a->di, RMS_ST_DISCONNECTED); if(a->cell->uas.request) { str *reason = &pcbp->rpl->first_line.u.reply.reason; if(!tmb.t_reply_with_body(a->cell, pcbp->code, reason, NULL, NULL, @@ -487,6 +491,8 @@ static void bridge_cb(struct cell *ptrans, int ntype, struct tmcb_params *pcbp) return; } else if(ntype == TMCB_LOCAL_COMPLETED) { LM_NOTICE("COMPLETED [%d]\n", pcbp->code); + if (pcbp->code >= 300) + return; } else if(ntype == TMCB_LOCAL_RESPONSE_IN){ LM_NOTICE("RESPONSE [%d]\n", pcbp->code); if (pcbp->code != 180 && pcbp->code != 183) @@ -751,9 +757,9 @@ static void rms_action_add(rms_dialog_info_t *di, rms_action_t *a) static void rms_action_add_sync(rms_dialog_info_t *di, rms_action_t *a) { - lock(&dialog_list_mutex); + lock(dialog_list_mutex); rms_action_add(di, a); - unlock(&dialog_list_mutex); + unlock(dialog_list_mutex); } // Called when receiving BYE @@ -890,7 +896,13 @@ static int rms_bridge_f(struct sip_msg *msg, char *_target, char *_route) if(!rms_str_dup(&a->param, &target, 1)) { goto error; } - + if (a->param.s[a->param.len-1] != ';') { + a->param.s = shm_realloc(a->param.s, a->param.len + 2); + a->param.s[a->param.len]=';'; + a->param.len++; + a->param.s[a->param.len]= '\0'; + LM_NOTICE("remote >>> target[%.*s]\n", a->param.len, a->param.s); + } a->route.len = route.len; a->route.s = route.s; @@ -1054,14 +1066,17 @@ static int rms_sip_request_f(struct sip_msg *msg) } if(di && strncmp(method->s, "BYE", 3) == 0) { + if(di->state == RMS_ST_DISCONNECTING) + return -1; if(di->state == RMS_ST_CONNECTED) - di->state = RMS_ST_DISCONNECTING; + rms_dialog_info_set_state(di, RMS_ST_DISCONNECTING); rms_action_t *a = rms_action_new(RMS_STOP); if(!a) return -1; rms_action_add_sync(di, a); if(di->bridged_di) { // bridged LM_NOTICE("BYE in brigde mode\n"); + rms_sip_forward(di, msg, method); } else { // connected localy LM_NOTICE("BYE in local mode\n"); rms_disconnect(msg); @@ -1073,7 +1088,6 @@ static int rms_sip_request_f(struct sip_msg *msg) LM_NOTICE("initial INVITE\n"); return 1; } else { - LM_NOTICE("in dialog message, state [%d]\n", di->state); if (di->state == RMS_ST_DISCONNECTING) { return -1; // ignore in dialog message in this state } else if (di->state == RMS_ST_DISCONNECTED) { diff --git a/src/modules/rtp_media_server/rtp_media_server.h b/src/modules/rtp_media_server/rtp_media_server.h index bf22660b1..c0d709466 100644 --- a/src/modules/rtp_media_server/rtp_media_server.h +++ b/src/modules/rtp_media_server/rtp_media_server.h @@ -39,7 +39,7 @@ #include "rms_media.h" #include "rms_dialog_info.h" -ser_lock_t dialog_list_mutex; +extern gen_lock_t *dialog_list_mutex; @@ -51,7 +51,7 @@ typedef struct rms char *local_ip; } rms_t; -struct tm_binds tmb; +extern struct tm_binds tmb; #endif diff --git a/src/modules/rtpengine/rtpengine.c b/src/modules/rtpengine/rtpengine.c index 95726fa4a..d15bebb35 100644 --- a/src/modules/rtpengine/rtpengine.c +++ b/src/modules/rtpengine/rtpengine.c @@ -290,6 +290,9 @@ static pv_spec_t *media_duration_pvar = NULL; #define RTPENGINE_SESS_LIMIT_MSG "Parallel session limit reached" #define RTPENGINE_SESS_LIMIT_MSG_LEN (sizeof(RTPENGINE_SESS_LIMIT_MSG)-1) +#define RTPENGINE_SESS_OUT_OF_PORTS_MSG "Ran out of ports" +#define RTPENGINE_SESS_OUT_OF_PORTS_MSG_LEN (sizeof(RTPENGINE_SESS_OUT_OF_PORTS_MSG)-1) + char* force_send_ip_str=""; int force_send_ip_af = AF_UNSPEC; @@ -1009,7 +1012,14 @@ int add_rtpengine_socks(struct rtpp_set *rtpp_list, char *rtpengine, /* Check the rn_address is 'hostname:port' */ /* Check the rn_address port is valid */ - p1 = strchr(pnode->rn_address, ':'); + if(pnode->rn_umode == 6) { + p1 = strstr(pnode->rn_address, "]:"); + if(p1 != NULL) { + p1++; + } + } else { + p1 = strchr(pnode->rn_address, ':'); + } if (p1 != NULL) { p1++; } @@ -2616,6 +2626,13 @@ select_node: LM_WARN("proxy %.*s: %.*s", node->rn_url.len, node->rn_url.s , error.len, error.s); goto select_node; } + if ((RTPENGINE_SESS_OUT_OF_PORTS_MSG_LEN == error.len) && + (strncmp(error.s, RTPENGINE_SESS_OUT_OF_PORTS_MSG, RTPENGINE_SESS_OUT_OF_PORTS_MSG_LEN) == 0)) + { + LM_WARN("proxy %.*s: %.*s", node->rn_url.len, node->rn_url.s , error.len, error.s); + goto select_node; + } + LM_ERR("proxy replied with error: %.*s\n", error.len, error.s); } goto error; diff --git a/src/modules/rtpproxy/rtpproxy.c b/src/modules/rtpproxy/rtpproxy.c index 8aef20019..23c8357e4 100644 --- a/src/modules/rtpproxy/rtpproxy.c +++ b/src/modules/rtpproxy/rtpproxy.c @@ -114,7 +114,7 @@ static str DEFAULT_RTPP_SET_ID_STR = str_init("0"); #define PTL_CPROTOVER "20081102" #define CPORT "22222" -static int extract_mediaip(str *, str *, int *, char *); +static int rp_extract_mediaip(str *, str *, int *, char *); static int alter_mediaip(struct sip_msg *, str *, str *, int, str *, int, int); static int alter_mediaport(struct sip_msg *, str *, str *, str *, int); static int alter_rtcp(struct sip_msg *msg, str *body, str *oldport, str *newport); @@ -958,7 +958,7 @@ replace_sdp_ip(struct sip_msg* msg, str *org_body, char *line, str *ip) } body1 = body; for(;;) { - if (extract_mediaip(&body1, &oldip, &pf,line) == -1) + if (rp_extract_mediaip(&body1, &oldip, &pf,line) == -1) break; if (pf != AF_INET) { LM_ERR("not an IPv4 address in '%s' SDP\n",line); @@ -988,7 +988,7 @@ replace_sdp_ip(struct sip_msg* msg, str *org_body, char *line, str *ip) } static int -extract_mediaip(str *body, str *mediaip, int *pf, char *line) +rp_extract_mediaip(str *body, str *mediaip, int *pf, char *line) { char *cp, *cp1; int len, nextisip; diff --git a/src/modules/sanity/sanity.c b/src/modules/sanity/sanity.c index 04ad2b86d..842d39419 100644 --- a/src/modules/sanity/sanity.c +++ b/src/modules/sanity/sanity.c @@ -299,8 +299,21 @@ int check_ruri_scheme(sip_msg_t* msg) { return SANITY_CHECK_PASSED; } +#define SANITY_HDR_DUPCHECK(_hf, _hdr_flags, _hdr_type, _hdr_flag, _hdr_name) \ + do { \ + if((_hf)->type == _hdr_type) { \ + if(_hdr_flags & _hdr_flag) { \ + LM_DBG("duplicated %s header\n", _hdr_name); \ + return SANITY_CHECK_FAILED; \ + } \ + _hdr_flags |= _hdr_flag; \ + } \ + } while(0) + /* check for the presence of the minimal required headers */ int check_required_headers(sip_msg_t* msg) { + hdr_field_t* hf; + hdr_flags_t hdr_flags = 0; LM_DBG("check_required_headers entered\n"); @@ -309,6 +322,20 @@ int check_required_headers(sip_msg_t* msg) { LM_DBG("check_required_headers failed\n"); return SANITY_CHECK_FAILED; } + if (parse_headers(msg, HDR_EOH_F, 0) != 0) { + LM_ERR("failed to parse headers\n"); + if (sanity_reply(msg, 400, "Bad Headers") < 0) { + LM_WARN("failed to send 400 reply\n"); + } + return SANITY_CHECK_FAILED; + } + for (hf=msg->headers; hf; hf=hf->next) { + SANITY_HDR_DUPCHECK(hf, hdr_flags, HDR_FROM_T, HDR_FROM_F, "From"); + SANITY_HDR_DUPCHECK(hf, hdr_flags, HDR_TO_T, HDR_TO_F, "To"); + SANITY_HDR_DUPCHECK(hf, hdr_flags, HDR_CALLID_T, HDR_CALLID_F, "Call-Id"); + SANITY_HDR_DUPCHECK(hf, hdr_flags, HDR_CSEQ_T, HDR_CSEQ_F, "CSeq"); + } + /* TODO: check for other required headers according to request type */ LM_DBG("check_required_headers passed\n"); diff --git a/src/modules/sca/NOTES b/src/modules/sca/NOTES index b5c9ebaf5..fa8ab926f 100644 --- a/src/modules/sca/NOTES +++ b/src/modules/sca/NOTES @@ -113,7 +113,7 @@ Revisiting possibility of using TMCB_ tm module hooks. * Register a pv in the module, set it to a known value in the TMCB_E2EACK_IN callback, have the script check the value of the pv, and invoke an exported sca_update function if the pv is set - the the known value. + to the known value. Pros: fits sip-router script-based logic model well, does not rely on a timer (eliminates races). diff --git a/src/modules/sctp/sctp_server.c b/src/modules/sctp/sctp_server.c index 669050397..fff7a0b6b 100644 --- a/src/modules/sctp/sctp_server.c +++ b/src/modules/sctp/sctp_server.c @@ -2258,6 +2258,7 @@ static int sctp_handle_notification(struct socket_info *si, { union sctp_notification *snp; char su_buf[SU2A_MAX_STR_SIZE]; + struct sockaddr_storage sa_storage; #define SNOT DBG #define ERR_LEN_TOO_SMALL(length, val, bind_addr, from_su, text) \ @@ -2311,8 +2312,9 @@ static int sctp_handle_notification(struct socket_info *si, sctp_paddr_change_state2s(snp->sn_paddr_change.spc_state), snp->sn_paddr_change.spc_state, &snp->sn_paddr_change.spc_aaddr); - strcpy(su_buf, su2a((union sockaddr_union *)&snp->sn_paddr_change - .spc_aaddr, + memcpy(&sa_storage, &snp->sn_paddr_change.spc_aaddr, + sizeof(snp->sn_paddr_change.spc_aaddr)); + strcpy(su_buf, su2a((union sockaddr_union *)&sa_storage, sizeof(snp->sn_paddr_change.spc_aaddr))); SNOT("sctp notification from %s on %.*s:%d: SCTP_PEER_ADDR_CHANGE" ": %s: %s: assoc_id %d \n", diff --git a/src/modules/secsipid/Makefile b/src/modules/secsipid/Makefile index ec8ad0798..2b97061d3 100644 --- a/src/modules/secsipid/Makefile +++ b/src/modules/secsipid/Makefile @@ -7,8 +7,23 @@ include ../../Makefile.defs auto_gen= NAME=secsipid.so -DEFS+= -I. -LIBS+= -L. -lsecsipid +ifeq ($(CROSS_COMPILE),) + BUILDER = $(shell which pkg-config) +ifneq ($(BUILDER),) + PKGLIBSECSIPID = $(shell $(BUILDER) --exists secsipid-1 > /dev/null 2>&1 ; echo $$? ) +ifneq ($(PKGLIBSECSIPID),0) + BUILDER = +endif +endif +endif + +ifeq ($(BUILDER),) + DEFS+= -I. + LIBS = -L. -lsecsipid +else + DEFS+= $(shell pkg-config --cflags secsipid-1) + LIBS = $(shell pkg-config --libs secsipid-1) +endif ifeq ($(OS), darwin) LIBS+= -framework CoreFoundation -framework Security -lpthread diff --git a/src/modules/secsipid/README b/src/modules/secsipid/README index f2a4bc98e..d822544ba 100644 --- a/src/modules/secsipid/README +++ b/src/modules/secsipid/README @@ -70,10 +70,12 @@ Chapter 1. Admin Guide 1. Overview - The module implements secure SIP identity specifications - STIR and - SHAKEN IETF extensions for SIP (RFC8224, RFC 8588). + The module implements secure SIP identity specifications - STIR (Secure + Telephony Identity Revisited) and SHAKEN (Signature-based Handling of + Asserted information using toKENs) IETF extensions for SIP (RFC8224, + RFC8588). - It exports the functions to check and generate Identity header. + It exports the functions to check and generate SIP Identity header. 2. Dependencies @@ -133,7 +135,7 @@ modparam("secsipid", "timeout", 2) downloading the key using the URL from "info" parameter of the Identity header, using the value od "timeout" parameter to limit the download time. The validity of the JWT body in the Identity header is also - checjed against the "expire" parameter. + checked against the "expire" parameter. The parameters can contain pseudo-variables. @@ -173,7 +175,7 @@ request_route { request_route { ... secsipid_add_identity("$fU", "$rU", "A", "", - "http://kamailio.org/stir/$rd/cert.pem", "/secsipid/$rd/key.pem"); + "https://kamailio.org/stir/$rd/cert.pem", "/secsipid/$rd/key.pem"); ... } ... diff --git a/src/modules/secsipid/doc/secsipid_admin.xml b/src/modules/secsipid/doc/secsipid_admin.xml index ac5884679..1b057696f 100644 --- a/src/modules/secsipid/doc/secsipid_admin.xml +++ b/src/modules/secsipid/doc/secsipid_admin.xml @@ -16,11 +16,13 @@
Overview - The module implements secure SIP identity specifications - STIR and SHAKEN - IETF extensions for SIP (RFC8224, RFC 8588). + The module implements secure SIP identity specifications - STIR + (Secure Telephony Identity Revisited) and SHAKEN + (Signature-based Handling of Asserted information using toKENs) + IETF extensions for SIP (RFC8224, RFC8588). - It exports the functions to check and generate Identity header. + It exports the functions to check and generate SIP Identity header.
@@ -110,7 +112,7 @@ modparam("secsipid", "timeout", 2) the function is downloading the key using the URL from "info" parameter of the Identity header, using the value od "timeout" parameter to limit the download time. The validity of the JWT - body in the Identity header is also checjed against the "expire" + body in the Identity header is also checked against the "expire" parameter. @@ -164,7 +166,7 @@ request_route { request_route { ... secsipid_add_identity("$fU", "$rU", "A", "", - "http://kamailio.org/stir/$rd/cert.pem", "/secsipid/$rd/key.pem"); + "https://kamailio.org/stir/$rd/cert.pem", "/secsipid/$rd/key.pem"); ... } ... diff --git a/src/modules/secsipid/secsipid_mod.c b/src/modules/secsipid/secsipid_mod.c index d3ad1c896..efdb5ff50 100644 --- a/src/modules/secsipid/secsipid_mod.c +++ b/src/modules/secsipid/secsipid_mod.c @@ -25,14 +25,14 @@ #include #include +#include + #include "../../core/sr_module.h" #include "../../core/dprint.h" #include "../../core/mod_fix.h" #include "../../core/data_lump.h" #include "../../core/kemi.h" -#include "secsipid.h" - MODULE_VERSION static int secsipid_expire = 300; diff --git a/src/modules/siptrace/README b/src/modules/siptrace/README index d9130a312..c48eca60d 100644 --- a/src/modules/siptrace/README +++ b/src/modules/siptrace/README @@ -514,7 +514,7 @@ modparam("siptrace", "trace_init_mode", 1) * 0 - no automatic mirroring or storing of SIP traffic. * 1 (1st bit set) - mirror the traffic to HEP server. * 2 (2nd bit set) - store the traffic to database server. - * 4 (3rd bit set) - mirro the traffic to the SIP URI specified by + * 4 (3rd bit set) - mirror the traffic to the SIP URI specified by duplicate_uri. The trace_on parameter still has to be set, allowing also to control diff --git a/src/modules/siptrace/doc/siptrace_admin.xml b/src/modules/siptrace/doc/siptrace_admin.xml index 7d5b0d34e..7840e156a 100644 --- a/src/modules/siptrace/doc/siptrace_admin.xml +++ b/src/modules/siptrace/doc/siptrace_admin.xml @@ -587,7 +587,7 @@ modparam("siptrace", "trace_init_mode", 1) - 4 (3rd bit set) - mirro the traffic to the SIP URI specified by + 4 (3rd bit set) - mirror the traffic to the SIP URI specified by duplicate_uri. diff --git a/src/modules/siptrace/siptrace.c b/src/modules/siptrace/siptrace.c index 1368e954a..30f23c592 100644 --- a/src/modules/siptrace/siptrace.c +++ b/src/modules/siptrace/siptrace.c @@ -91,6 +91,7 @@ static int w_sip_trace1(struct sip_msg *, char *dest, char *p2); static int w_sip_trace2(struct sip_msg *, char *dest, char *correlation_id); static int w_sip_trace3(struct sip_msg *, char *dest, char *correlation_id, char *trace_type); static int fixup_siptrace(void **param, int param_no); +static int fixup_free_siptrace(void **param, int param_no); static int w_sip_trace_mode(sip_msg_t *msg, char *pmode, char *p2); static int siptrace_parse_uri(str* duri, dest_info_t* dst); @@ -200,9 +201,9 @@ static cmd_export_t cmds[] = { ANY_ROUTE}, {"sip_trace", (cmd_function)w_sip_trace1, 1, fixup_siptrace, 0, ANY_ROUTE}, - {"sip_trace", (cmd_function)w_sip_trace2, 2, fixup_siptrace, 0, + {"sip_trace", (cmd_function)w_sip_trace2, 2, fixup_siptrace, fixup_free_siptrace, ANY_ROUTE}, - {"sip_trace", (cmd_function)w_sip_trace3, 3, fixup_siptrace, 0, + {"sip_trace", (cmd_function)w_sip_trace3, 3, fixup_siptrace, fixup_free_siptrace, ANY_ROUTE}, {"hlog", (cmd_function)w_hlog1, 1, fixup_spve_null, 0, ANY_ROUTE}, @@ -779,6 +780,21 @@ static int fixup_siptrace(void **param, int param_no) return 0; } +static int fixup_free_siptrace(void **param, int param_no) +{ + if (param_no == 1 || param_no == 2) { + /* correlation id */ + return fixup_free_spve_all(param, param_no); + } if (param_no == 3) { + /* tracing type; string only */ + if (*param) { + pkg_free(*param); + } + } + + return 0; +} + /** * diff --git a/src/modules/siputils/contact_ops.c b/src/modules/siputils/contact_ops.c index a299db32e..f21d7705b 100644 --- a/src/modules/siputils/contact_ops.c +++ b/src/modules/siputils/contact_ops.c @@ -773,6 +773,7 @@ int ki_contact_param_decode(sip_msg_t *msg, str *nparam) } if(pit==NULL || pit->body.len<=0) { free_params(params); + params = NULL; continue; } @@ -816,6 +817,8 @@ int ki_contact_param_decode(sip_msg_t *msg, str *nparam) pkg_free(nval.s); return -2; } + free_params(params); + params = NULL; } return 1; @@ -974,6 +977,7 @@ int ki_contact_param_rm(sip_msg_t *msg, str *nparam) } if(pit==NULL) { free_params(params); + params = NULL; continue; } rms.s = pit->name.s; @@ -984,6 +988,7 @@ int ki_contact_param_rm(sip_msg_t *msg, str *nparam) LM_ERR("failed to find start of the parameter delimiter [%.*s]\n", c->uri.len, c->uri.s); free_params(params); + params = NULL; continue; } if(pit->body.len>0) { @@ -1004,6 +1009,7 @@ int ki_contact_param_rm(sip_msg_t *msg, str *nparam) continue; } free_params(params); + params = NULL; } return 1; diff --git a/src/modules/sl/sl_stats.c b/src/modules/sl/sl_stats.c index dd683eda5..079786aad 100644 --- a/src/modules/sl/sl_stats.c +++ b/src/modules/sl/sl_stats.c @@ -73,7 +73,7 @@ static void rpc_stats(rpc_t* rpc, void* c) "202", total.err[RT_202], "2xx", total.err[RT_2xx]); - rpc->struct_add(st, "ddd", + rpc->struct_add(st, "dddd", "300", total.err[RT_300], "301", total.err[RT_301], "302", total.err[RT_302], diff --git a/src/modules/smsops/smsops_impl.c b/src/modules/smsops/smsops_impl.c index b284d83c6..e956656d1 100644 --- a/src/modules/smsops/smsops_impl.c +++ b/src/modules/smsops/smsops_impl.c @@ -195,7 +195,7 @@ static int ascii_to_gsm(str sms, char * output_buffer, int buffer_size) { } } - if (i <= sms.len) + if (i < sms.len) output_buffer[output_buffer_length++] = (sms.s[i] & BITMASK_7BITS) >> (carry_on_bits - 1); return output_buffer_length; @@ -606,6 +606,15 @@ int decode_3gpp_sms(struct sip_msg *msg) { udh_read += (1 /* IE ID */ + 1 /* IE Len */ + ie->data.len /* IE data */); } + // TS 23.040, Sec. 9.2.3.16 + // Coding: 7 Bit + if (rp_data->pdu.coding == 0x00) { + int udh_bit_len = (1 + udh_len) * 8; // add 1 octet for the udh length + udh_bit_len += (7 - (udh_bit_len % 7)); + len -= (udh_bit_len / 7); + }else{ + len -= (1 + udh_len); // add 1 octet for the udh length + } } blen = 2 + len*4; @@ -618,6 +627,7 @@ int decode_3gpp_sms(struct sip_msg *msg) { // Coding: 7 Bit if (rp_data->pdu.coding == 0x00) { // We don't care about the extra used bytes here. + rp_data->pdu.payload.sm.len = len; rp_data->pdu.payload.sm.len = gsm_to_ascii(&body.s[p], len, rp_data->pdu.payload.sm, fill_bits); } else { // Length is worst-case 2 * len (UCS2 is 2 Bytes, UTF8 is worst-case 4 Bytes) diff --git a/src/modules/textops/README b/src/modules/textops/README index bd67b0898..74543b05d 100644 --- a/src/modules/textops/README +++ b/src/modules/textops/README @@ -741,10 +741,13 @@ if (has_body("multipart/mixed")) { 4.23. append_to_reply(txt) - Append txt as header to the reply. + Append txt as header to the reply that is going to be generated by + Kamailio (e.g., via sl_send_reply(...)). Meaning of the parameters is as follows: - * txt - String which may contains pseudo-variables. + * txt - String which may contains pseudo-variables. Note that the + value has to be ended with "\r\n" (end of header characters + sequence). This function can be used from REQUEST_ROUTE, BRANCH_ROUTE, FAILURE_ROUTE, ERROR_ROUTE. @@ -757,12 +760,14 @@ append_to_reply("Foo: $rm at $Ts\r\n"); 4.24. append_hf(txt[, hdr]) - Appends 'txt' as header after first header field or after last 'hdr' - header field. + Appends 'txt' as header at the end of the all headers, or after last + header named 'hdr' if the second parameter is provided. Meaning of the parameters is as follows: * txt - Header field to be appended. The value can contain - pseudo-variables which will be replaced at run time. + pseudo-variables which will be replaced at run time. Note that the + value has to be ended with "\r\n" (end of header characters + sequence). * hdr - Header name after which the 'txt' is appended. This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, @@ -776,12 +781,14 @@ append_hf("From-username: $fU\r\n", "Call-ID"); 4.25. insert_hf(txt[, hdr]) - Inserts 'txt' as header before the first header field or before first - 'hdr' header field if 'hdr' is given. + Inserts 'txt' as header before the first header field, or before first + header named 'hdr'if the second parameter is provided. Meaning of the parameters is as follows: * txt - Header field to be inserted. The value can contain - pseudo-variables which will be replaced at run time. + pseudo-variables which will be replaced at run time. Note that the + value has to be ended with "\r\n" (end of header characters + sequence). * hdr - Header name before which the 'txt' is inserted. This function can be used from REQUEST_ROUTE, ONREPLY_ROUTE, diff --git a/src/modules/textops/doc/textops_admin.xml b/src/modules/textops/doc/textops_admin.xml index a8685510a..44540841d 100644 --- a/src/modules/textops/doc/textops_admin.xml +++ b/src/modules/textops/doc/textops_admin.xml @@ -872,13 +872,15 @@ if (has_body("multipart/mixed")) { append_to_reply(txt) - Append txt as header to the reply. + Append txt as header to the reply that is going to be generated by + &kamailio; (e.g., via sl_send_reply(...)). Meaning of the parameters is as follows: txt - String which may contains - pseudo-variables. + pseudo-variables. Note that the value has to be ended with "\r\n" + (end of header characters sequence). @@ -902,15 +904,16 @@ append_to_reply("Foo: $rm at $Ts\r\n"); append_hf(txt[, hdr]) - Appends 'txt' as header after first header field or after - last 'hdr' header field. + Appends 'txt' as header at the end of the all headers, or after + last header named 'hdr' if the second parameter is provided. Meaning of the parameters is as follows: txt - Header field to be appended. The value can contain pseudo-variables which will be replaced at run - time. + time. Note that the value has to be ended with "\r\n" (end of header + characters sequence). @@ -939,15 +942,16 @@ append_hf("From-username: $fU\r\n", "Call-ID"); insert_hf(txt[, hdr]) - Inserts 'txt' as header before the first header field or before - first 'hdr' header field if 'hdr' is given. + Inserts 'txt' as header before the first header field, or before + first header named 'hdr'if the second parameter is provided. Meaning of the parameters is as follows: txt - Header field to be inserted. The value can contain pseudo-variables which will be replaced at run - time. + time. Note that the value has to be ended with "\r\n" (end of header + characters sequence). diff --git a/src/modules/textops/textops.c b/src/modules/textops/textops.c index 6dcbeedb0..7f11999cc 100644 --- a/src/modules/textops/textops.c +++ b/src/modules/textops/textops.c @@ -3361,7 +3361,7 @@ int add_hf_helper(struct sip_msg* msg, str *str1, str *str2, gparam_p hfval, int mode, gparam_p hfanc) { struct lump* anchor; - struct hdr_field *hf; + struct hdr_field *hf, *append_hf; char *s; int len; str s0; @@ -3372,6 +3372,7 @@ int add_hf_helper(struct sip_msg* msg, str *str1, str *str2, } hf = 0; + append_hf = 0; if(hfanc!=NULL) { for (hf=msg->headers; hf; hf=hf->next) { if(hfanc->type==GPARAM_TYPE_INT) @@ -3384,20 +3385,25 @@ int add_hf_helper(struct sip_msg* msg, str *str1, str *str2, if (cmp_hdrname_str(&hf->name,&hfanc->v.str)!=0) continue; } - break; + if (mode == 0) { /* append */ + append_hf = hf; + continue; + } else { /* insert */ + break; + } } } if(mode == 0) { /* append */ - if(hf==0) { /* after last header */ + if(append_hf==0) { /* after last header */ anchor = anchor_lump(msg, msg->unparsed - msg->buf, 0, 0); - } else { /* after hf */ - anchor = anchor_lump(msg, hf->name.s + hf->len - msg->buf, 0, 0); + } else { /* after last hf */ + anchor = anchor_lump(msg, append_hf->name.s + append_hf->len - msg->buf, 0, 0); } } else { /* insert */ if(hf==0) { /* before first header */ anchor = anchor_lump(msg, msg->headers->name.s - msg->buf, 0, 0); - } else { /* before hf */ + } else { /* before first hf */ anchor = anchor_lump(msg, hf->name.s - msg->buf, 0, 0); } } diff --git a/src/modules/tls/tls_domain.c b/src/modules/tls/tls_domain.c index 2930bde2b..a8859c4a3 100644 --- a/src/modules/tls/tls_domain.c +++ b/src/modules/tls/tls_domain.c @@ -27,8 +27,6 @@ #include #include #include -#include -#include #ifndef OPENSSL_NO_ENGINE #include @@ -63,11 +61,9 @@ static void setup_ecdh(SSL_CTX *ctx) { EC_KEY *ecdh; -#if OPENSSL_VERSION_NUMBER < 0x010100000L if (SSLeay() < 0x1000005fL) { return; } -#endif ecdh = EC_KEY_new_by_curve_name(NID_X9_62_prime256v1); SSL_CTX_set_options(ctx, SSL_OP_SINGLE_ECDH_USE); diff --git a/src/modules/tls/tls_init.c b/src/modules/tls/tls_init.c index f10d0c034..b9288cbd9 100644 --- a/src/modules/tls/tls_init.c +++ b/src/modules/tls/tls_init.c @@ -627,13 +627,14 @@ int tls_h_mod_pre_init_f(void) return 0; } LM_DBG("preparing tls env for modules initialization\n"); -#if OPENSSL_VERSION_NUMBER < 0x010100000L || defined(LIBRESSL_VERSION_NUMBER) +#if OPENSSL_VERSION_NUMBER >= 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER) + LM_DBG("preparing tls env for modules initialization (libssl >=1.1)\n"); + OPENSSL_init_ssl(0, NULL); +#else LM_DBG("preparing tls env for modules initialization (libssl <=1.0)\n"); SSL_library_init(); - SSL_load_error_strings(); -#else - LM_DBG("preparing tls env for modules initialization (libssl >=1.1)\n"); #endif + SSL_load_error_strings(); tls_mod_preinitialized=1; return 0; } @@ -645,7 +646,6 @@ int tls_h_mod_init_f(void) { /*struct socket_info* si;*/ long ssl_version; - const char *ssl_version_txt; #if OPENSSL_VERSION_NUMBER < 0x010100000L && !defined(LIBRESSL_VERSION_NUMBER) int lib_kerberos; int lib_zlib; @@ -668,15 +668,7 @@ int tls_h_mod_init_f(void) #if OPENSSL_VERSION_NUMBER < 0x00907000L LM_WARN("You are using an old version of OpenSSL (< 0.9.7). Upgrade!\n"); #endif - -#if OPENSSL_VERSION_NUMBER < 0x010100000L ssl_version=SSLeay(); - ssl_version_txt=SSLeay_version(SSLEAY_VERSION); -#else - ssl_version=OpenSSL_version_num(); - ssl_version_txt=OpenSSL_version(OPENSSL_VERSION); -#endif - /* check if version have the same major minor and fix level * (e.g. 0.9.8a & 0.9.8c are ok, but 0.9.8 and 0.9.9x are not) * - values is represented as 0xMMNNFFPPS: major minor fix patch status @@ -688,7 +680,7 @@ int tls_h_mod_init_f(void) " compiled \"%s\" (0x%08lx).\n" " Please make sure a compatible version is used" " (tls_force_run in kamailio.cfg will override this check)\n", - ssl_version_txt, ssl_version, + SSLeay_version(SSLEAY_VERSION), ssl_version, OPENSSL_VERSION_TEXT, (long)OPENSSL_VERSION_NUMBER); if (cfg_get(tls, tls_cfg, force_run)) LM_WARN("tls_force_run turned on, ignoring " @@ -865,7 +857,6 @@ int tls_check_sockets(tls_domains_cfg_t* cfg) void tls_h_mod_destroy_f(void) { LM_DBG("tls module final tls destroy\n"); -#if OPENSSL_VERSION_NUMBER < 0x010100000L || defined(LIBRESSL_VERSION_NUMBER) if(tls_mod_preinitialized > 0) ERR_free_strings(); /* TODO: free all the ctx'es */ @@ -878,5 +869,4 @@ void tls_h_mod_destroy_f(void) LM_DBG("executing openssl v1.1+ cleanup\n"); OPENSSL_cleanup(); #endif -#endif } diff --git a/src/modules/tls/tls_locking.c b/src/modules/tls/tls_locking.c index 21078e82d..4e5bbcc5e 100644 --- a/src/modules/tls/tls_locking.c +++ b/src/modules/tls/tls_locking.c @@ -140,8 +140,6 @@ unsigned long sr_ssl_id_f() /* returns -1 on error, 0 on success */ int tls_init_locks() { -/* OpenSSL is no longer supporting to set locking callbacks since 1.1.0 */ -#if OPENSSL_VERSION_NUMBER < 0x10100000L /* init "static" tls locks */ n_static_locks=CRYPTO_num_locks(); if (n_static_locks<0){ @@ -169,10 +167,13 @@ int tls_init_locks() CRYPTO_set_locking_callback(locking_f); } +/* OpenSSL is thread-safe since 1.1.0 */ +#if OPENSSL_VERSION_NUMBER < 0x10100000L /* set "dynamic" locks callbacks */ CRYPTO_set_dynlock_create_callback(dyn_create_f); CRYPTO_set_dynlock_lock_callback(dyn_lock_f); CRYPTO_set_dynlock_destroy_callback(dyn_destroy_f); +#endif /* starting with v1.0.0 openssl does not use anymore getpid(), but address * of errno which can point to same virtual address in a multi-process @@ -190,8 +191,4 @@ int tls_init_locks() error: tls_destroy_locks(); return -1; - -#else - return 0; -#endif } diff --git a/src/modules/tls/tls_mod.c b/src/modules/tls/tls_mod.c index 0b9fd39fc..cd4b0f4f0 100644 --- a/src/modules/tls/tls_mod.c +++ b/src/modules/tls/tls_mod.c @@ -385,6 +385,7 @@ static int mod_init(void) if (tls_check_sockets(*tls_domains_cfg) < 0) goto error; + LM_INFO("use OpenSSL version: %08x\n", (uint32_t)(OPENSSL_VERSION_NUMBER)); #ifndef OPENSSL_NO_ECDH LM_INFO("With ECDH-Support!\n"); #endif @@ -494,7 +495,7 @@ static int ki_is_peer_verified(sip_msg_t* msg) c = tcpconn_get(msg->rcv.proto_reserved1, 0, 0, 0, cfg_get(tls, tls_cfg, con_lifetime)); if (!c) { - LM_ERR("connection no longer exits\n"); + LM_ERR("connection no longer exists\n"); return -1; } diff --git a/src/modules/tm/README b/src/modules/tm/README index 509b5f639..26740a533 100644 --- a/src/modules/tm/README +++ b/src/modules/tm/README @@ -77,6 +77,7 @@ Daniel-Constantin Mierla 3.48. relay_100 (str) 3.49. rich_redirect (int) 3.50. exec_time_check (int) + 3.51. reply_relay_mode (int) 4. Functions @@ -143,12 +144,13 @@ Daniel-Constantin Mierla 5.1. tm.list 5.2. tm.t_uac_start 5.3. tm.t_uac_wait - 5.4. tm.cancel - 5.5. tm.hash_stats - 5.6. tm.reply - 5.7. tm.reply_callid - 5.8. tm.clean - 5.9. tm.stats + 5.4. tm.t_uac_wait + 5.5. tm.cancel + 5.6. tm.hash_stats + 5.7. tm.reply + 5.8. tm.reply_callid + 5.9. tm.clean + 5.10. tm.stats 6. Event Routes @@ -226,57 +228,58 @@ Daniel-Constantin Mierla 1.48. Set relay_100 parameter 1.49. rich_redirect example 1.50. Set exec_time_check parameter - 1.51. t_relay usage - 1.52. t_relay_to_udp usage - 1.53. t_on_failure usage - 1.54. t_on_branch_failure usage - 1.55. t_on_reply usage - 1.56. t_on_branch usage - 1.57. t_newtran usage - 1.58. t_reply usage - 1.59. t_send_reply usage - 1.60. t_lookup_request usage - 1.61. t_retransmit_reply usage - 1.62. t_release usage - 1.63. t_forward_nonack usage - 1.64. t_set_fr usage - 1.65. t_reset_fr usage - 1.66. t_set_max_lifetime usage - 1.67. t_reset_max_lifetime usage - 1.68. t_set_retr usage - 1.69. t_reset_retr usage - 1.70. t_set_auto_inv_100 usage - 1.71. t_branch_timeout usage - 1.72. t_branch_replied usage - 1.73. t_any_timeout usage - 1.74. t_any_replied usage - 1.75. t_grep_status usage - 1.76. t_is_canceled usage - 1.77. t_is_expired usage - 1.78. t_relay_cancel usage - 1.79. t_lookup_cancel usage - 1.80. t_drop_replies() usage - 1.81. t_save_lumps() usage - 1.82. t_load_contacts usage - 1.83. t_next_contacts usage - 1.84. t_next_contact_flow usage - 1.85. t_check_status usage - 1.86. t_check_trans usage - 1.87. t_set_disable_6xx usage - 1.88. t_set_disable_failover usage - 1.89. t_set_disable_internal_reply usage - 1.90. t_replicate usage - 1.91. t_relay_to usage - 1.92. t_set_no_e2e_cancel_reason usage - 1.93. t_replicate usage - 1.94. t_use_uac_headers usage - 1.95. t_is_retr_async_reply usage - 1.96. t_uac_send usage - 1.97. t_get_status_code usage - 1.98. t_clean usage - 1.99. event_route[tm:branch-failure:id] usage - 1.100. event_route[tm:local-request] usage - 1.101. event_route[tm:local-response] usage + 1.51. Set reply_relay_mode parameter + 1.52. t_relay usage + 1.53. t_relay_to_udp usage + 1.54. t_on_failure usage + 1.55. t_on_branch_failure usage + 1.56. t_on_reply usage + 1.57. t_on_branch usage + 1.58. t_newtran usage + 1.59. t_reply usage + 1.60. t_send_reply usage + 1.61. t_lookup_request usage + 1.62. t_retransmit_reply usage + 1.63. t_release usage + 1.64. t_forward_nonack usage + 1.65. t_set_fr usage + 1.66. t_reset_fr usage + 1.67. t_set_max_lifetime usage + 1.68. t_reset_max_lifetime usage + 1.69. t_set_retr usage + 1.70. t_reset_retr usage + 1.71. t_set_auto_inv_100 usage + 1.72. t_branch_timeout usage + 1.73. t_branch_replied usage + 1.74. t_any_timeout usage + 1.75. t_any_replied usage + 1.76. t_grep_status usage + 1.77. t_is_canceled usage + 1.78. t_is_expired usage + 1.79. t_relay_cancel usage + 1.80. t_lookup_cancel usage + 1.81. t_drop_replies() usage + 1.82. t_save_lumps() usage + 1.83. t_load_contacts usage + 1.84. t_next_contacts usage + 1.85. t_next_contact_flow usage + 1.86. t_check_status usage + 1.87. t_check_trans usage + 1.88. t_set_disable_6xx usage + 1.89. t_set_disable_failover usage + 1.90. t_set_disable_internal_reply usage + 1.91. t_replicate usage + 1.92. t_relay_to usage + 1.93. t_set_no_e2e_cancel_reason usage + 1.94. t_replicate usage + 1.95. t_use_uac_headers usage + 1.96. t_is_retr_async_reply usage + 1.97. t_uac_send usage + 1.98. t_get_status_code usage + 1.99. t_clean usage + 1.100. event_route[tm:branch-failure:id] usage + 1.101. event_route[tm:local-request] usage + 1.102. event_route[tm:local-response] usage Chapter 1. Admin Guide @@ -336,6 +339,7 @@ Chapter 1. Admin Guide 3.48. relay_100 (str) 3.49. rich_redirect (int) 3.50. exec_time_check (int) + 3.51. reply_relay_mode (int) 4. Functions @@ -400,12 +404,13 @@ Chapter 1. Admin Guide 5.1. tm.list 5.2. tm.t_uac_start 5.3. tm.t_uac_wait - 5.4. tm.cancel - 5.5. tm.hash_stats - 5.6. tm.reply - 5.7. tm.reply_callid - 5.8. tm.clean - 5.9. tm.stats + 5.4. tm.t_uac_wait + 5.5. tm.cancel + 5.6. tm.hash_stats + 5.7. tm.reply + 5.8. tm.reply_callid + 5.9. tm.clean + 5.10. tm.stats 6. Event Routes @@ -710,6 +715,7 @@ failure_route["serial"] 3.48. relay_100 (str) 3.49. rich_redirect (int) 3.50. exec_time_check (int) + 3.51. reply_relay_mode (int) 3.1. fr_timer (integer) @@ -1706,6 +1712,25 @@ modparam("tm", "rich_redirect", 3) modparam("tm", "exec_time_check", 0) ... +3.51. reply_relay_mode (int) + + If set to 1, a received 200ok response that was suspeneded is no longer + forwarded in the transactional context if another final response was + forward while 200ok was suspended. Forwarding the 200ok, even it was + received first, results in overwritting the transaction response buffer + that can impact matching of incoming ACKs. + + Set it to 0 in order to disable this behaviour and attempt to forward + suspended 200ok in the transaction context. This was the behaviour + before the commit 18410da0. + + Default value is 1. + + Example 1.51. Set reply_relay_mode parameter +... +modparam("tm", "reply_relay_mode", 0) +... + 4. Functions 4.1. t_relay([host, port]) @@ -1783,7 +1808,7 @@ modparam("tm", "exec_time_check", 0) Returns a negative value on failure -- you may still want to send a negative reply upstream statelessly not to leave upstream UAC in lurch. - Example 1.51. t_relay usage + Example 1.52. t_relay usage ... if (!t_relay()) { @@ -1810,7 +1835,7 @@ if (!t_relay()) derived from the message uri (using sip specific DNS lookups), but with the protocol corresponding to the function name. - Example 1.52. t_relay_to_udp usage + Example 1.53. t_relay_to_udp usage ... if (src_ip==10.0.0.0/8) t_relay_to_udp("1.2.3.4", "5060"); # sent to 1.2.3.4:5060 over udp @@ -1850,7 +1875,7 @@ else Meaning of the parameters is as follows: * failure_route - Failure route block to be called. - Example 1.53. t_on_failure usage + Example 1.54. t_on_failure usage ... route { t_on_failure("1"); @@ -1886,7 +1911,7 @@ failure_route[1] { * branch_failure_route - Name of the branch_failure route block to be called (it is prefixed internally with 'tm:branch-failure:'). - Example 1.54. t_on_branch_failure usage + Example 1.55. t_on_branch_failure usage ... route { t_on_branch_failure("myroute"); @@ -1909,7 +1934,7 @@ event_route[tm:branch-failure:myroute] { Meaning of the parameters is as follows: * onreply_route - Onreply route block to be called. - Example 1.55. t_on_reply usage + Example 1.56. t_on_reply usage ... loadmodule "/usr/local/lib/ser/modules/nathelper.so" ... @@ -1941,7 +1966,7 @@ es'); Meaning of the parameters is as follows: * branch_route - branch route block to be called. - Example 1.56. t_on_branch usage + Example 1.57. t_on_branch usage ... route { t_on_branch("1"); @@ -1966,7 +1991,7 @@ branch_route[1] { structure. Use the tmx module function t_flush_flags() to synchronize the modified message flags to the already created transaction. - Example 1.57. t_newtran usage + Example 1.58. t_newtran usage ... if (t_newtran()) { xlog("the transaction has been created\n"); @@ -1998,7 +2023,7 @@ if (t_newtran()) { * code - Reply code number. * reason_phrase - Reason string. - Example 1.58. t_reply usage + Example 1.59. t_reply usage ... t_reply("404", "Not found"); ... @@ -2016,7 +2041,7 @@ t_reply("404", "Not found"); * code - Reply code number. * reason - Reason string. - Example 1.59. t_send_reply usage + Example 1.60. t_send_reply usage ... t_send_reply("404", "Not found"); ... @@ -2029,7 +2054,7 @@ t_send_reply("404", "Not found"); none was found. However this is safely (atomically) done using t_newtran. - Example 1.60. t_lookup_request usage + Example 1.61. t_lookup_request usage ... if (t_lookup_request()) { ... @@ -2040,7 +2065,7 @@ if (t_lookup_request()) { Retransmits a reply sent previously by UAS transaction. - Example 1.61. t_retransmit_reply usage + Example 1.62. t_retransmit_reply usage ... t_retransmit_reply(); ... @@ -2050,7 +2075,7 @@ t_retransmit_reply(); Remove transaction from memory (it will be first put on a wait timer to absorb delayed messages). - Example 1.62. t_release usage + Example 1.63. t_release usage ... t_release(); ... @@ -2064,7 +2089,7 @@ t_release(); * ip - IP address where the message should be sent. * port - Port number. - Example 1.63. t_forward_nonack usage + Example 1.64. t_forward_nonack usage ... t_forward_nonack("1.2.3.4", "5060"); ... @@ -2103,7 +2128,7 @@ t_forward_nonack("1.2.3.4", "5060"); See also: fr_timer, fr_inv_timer, t_reset_fr(). - Example 1.64. t_set_fr usage + Example 1.65. t_set_fr usage ... route { t_set_fr(10000); # set only fr invite timeout to 10s @@ -2130,7 +2155,7 @@ branch_route[1] { See also: fr_timer, fr_inv_timer, t_set_fr. - Example 1.65. t_reset_fr usage + Example 1.66. t_reset_fr usage ... route { ... @@ -2156,7 +2181,7 @@ route { See also: max_inv_lifetime, max_noninv_lifetime, t_reset_max_lifetime. - Example 1.66. t_set_max_lifetime usage + Example 1.67. t_set_max_lifetime usage ... route { if (src_ip=1.2.3.4) @@ -2169,7 +2194,7 @@ route { 4.24. t_reset_max_lifetime() - Resets the the maximum lifetime for the current INVITE or non-INVITE + Resets the maximum lifetime for the current INVITE or non-INVITE transaction to the default value (set using the tm module parameter max_inv_lifetime or max_noninv_lifetime). @@ -2178,7 +2203,7 @@ route { See also: max_inv_lifetime, max_noninv_lifetime, t_set_max_lifetime. - Example 1.67. t_reset_max_lifetime usage + Example 1.68. t_reset_max_lifetime usage ... route { ... @@ -2213,7 +2238,7 @@ route { See also: retr_timer1, retr_timer2, t_reset_retr(). - Example 1.68. t_set_retr usage + Example 1.69. t_set_retr usage ... route { t_set_retr(250, 0); # set only T1 to 250 ms @@ -2240,7 +2265,7 @@ branch_route[1] { See also: retr_timer1, retr_timer2, t_set_retr. - Example 1.69. t_reset_retr usage + Example 1.70. t_reset_retr usage ... route { ... @@ -2256,7 +2281,7 @@ route { See also: auto_inv_100. - Example 1.70. t_set_auto_inv_100 usage + Example 1.71. t_set_auto_inv_100 usage ... route { ... @@ -2271,7 +2296,7 @@ route { timeout. It can be used from FAILURE_ROUTE and BRANCH_FAILURE_ROUTE event route. - Example 1.71. t_branch_timeout usage + Example 1.72. t_branch_timeout usage ... failure_route[0]{ if (t_branch_timeout()){ @@ -2287,7 +2312,7 @@ failure_route[0]{ taken into account). It can be used from failure_route and branch-failure event route. - Example 1.72. t_branch_replied usage + Example 1.73. t_branch_replied usage ... failure_route[0]{ if (t_branch_timeout()){ @@ -2304,7 +2329,7 @@ failure_route[0]{ Returns true if at least one of the current transactions branches did timeout. - Example 1.73. t_any_timeout usage + Example 1.74. t_any_timeout usage ... failure_route[0]{ if (!t_branch_timeout()){ @@ -2321,7 +2346,7 @@ failure_route[0]{ receive some reply in the past. If called from a failure or onreply route, the "current" reply is not taken into account. - Example 1.74. t_any_replied usage + Example 1.75. t_any_replied usage ... onreply_route[0]{ if (!t_any_replied()){ @@ -2335,7 +2360,7 @@ onreply_route[0]{ Returns true if "code" is the final reply received (or locally generated) in at least one of the current transactions branches. - Example 1.75. t_grep_status usage + Example 1.76. t_grep_status usage ... onreply_route[0]{ if (t_grep_status("486")){ @@ -2348,7 +2373,7 @@ onreply_route[0]{ Returns true if the current transaction was canceled. - Example 1.76. t_is_canceled usage + Example 1.77. t_is_canceled usage ... failure_route[0]{ if (t_is_canceled()){ @@ -2362,7 +2387,7 @@ failure_route[0]{ Returns true if the current transaction has already been expired, i.e. the max_inv_lifetime/max_noninv_lifetime interval has already elapsed. - Example 1.77. t_is_expired usage + Example 1.78. t_is_expired usage ... failure_route[0]{ if (t_is_expired()){ @@ -2383,7 +2408,7 @@ failure_route[0]{ CANCELs were successfully sent to the pending branches, true if the INVITE was not found, and false in case of any error. - Example 1.78. t_relay_cancel usage + Example 1.79. t_relay_cancel usage if (method == CANCEL) { if (!t_relay_cancel()) { # implicit drop if relaying was successful, # nothing to do @@ -2410,7 +2435,7 @@ if (method == CANCEL) { overwritten with the flags of the INVITE. isflagset() can be used to check the flags of the previously forwarded INVITE in this case. - Example 1.79. t_lookup_cancel usage + Example 1.80. t_lookup_cancel usage if (method == CANCEL) { if (t_lookup_cancel()) { log("INVITE transaction exists"); @@ -2440,7 +2465,7 @@ if (method == CANCEL) { Dropping replies works only if a new branch is added to the transaction, or it is explicitly replied in the script! - Example 1.80. t_drop_replies() usage + Example 1.81. t_drop_replies() usage ... failure_route[0]{ if (t_check_status("5[0-9][0-9]")){ @@ -2471,7 +2496,7 @@ failure_route[0]{ The transaction must be created by t_newtran() before calling t_save_lumps(). - Example 1.81. t_save_lumps() usage + Example 1.82. t_save_lumps() usage route { ... t_newtran(); @@ -2545,7 +2570,7 @@ failure_route[1] { This function can be used from REQUEST_ROUTE and FAILURE_ROUTE. - Example 1.82. t_load_contacts usage + Example 1.83. t_load_contacts usage ... if (!t_load_contacts()) { sl_send_reply("500", "Server Internal Error - Cannot load contacts"); @@ -2586,7 +2611,7 @@ if (!t_load_contacts()) { contact_flows_avp are not anymore set. Based on that test, you can then use t_set_fr() function to set timers according to your needs. - Example 1.83. t_next_contacts usage + Example 1.84. t_next_contacts usage ... # First call after t_load_contacts() when transaction does not exist yet # and contacts should be available @@ -2624,7 +2649,7 @@ if (!t_next_contacts()) { syslog). This function can be used from a BRANCH_FAILURE_ROUTE event route. - Example 1.84. t_next_contact_flow usage + Example 1.85. t_next_contact_flow usage ... event_route[tm:branch-failure:outbound] { @@ -2647,7 +2672,7 @@ event_route[tm:branch-failure:outbound] This function can be used from ANY_ROUTE . - Example 1.85. t_check_status usage + Example 1.86. t_check_status usage ... if (t_check_status("(487)|(408)")) { log("487 or 408 negative reply\n"); @@ -2701,7 +2726,7 @@ Note See also: t_lookup_request(), t_lookup_cancel(). - Example 1.86. t_check_trans usage + Example 1.87. t_check_trans usage if ( method == "CANCEL" && !t_check_trans()) sl_reply("403", "cancel out of the blue forbidden"); # note: in this example t_check_trans() can be replaced by t_lookup_cancel() @@ -2716,7 +2741,7 @@ if ( method == "CANCEL" && !t_check_trans()) See also: disable_6xx_block. - Example 1.87. t_set_disable_6xx usage + Example 1.88. t_set_disable_6xx usage ... route { ... @@ -2731,7 +2756,7 @@ route { See also: use_dns_failover. - Example 1.88. t_set_disable_failover usage + Example 1.89. t_set_disable_failover usage ... route { ... @@ -2744,7 +2769,7 @@ route { Turn off/on sending internally a SIP reply in case of relay errors. - Example 1.89. t_set_disable_internal_reply usage + Example 1.90. t_set_disable_internal_reply usage ... t_set_disable_internal_reply(1); # turn off sending internal reply on error if(!t_relay()) { @@ -2777,7 +2802,7 @@ if(!t_relay()) { * hostport - address in "host:port" format. It can be given via an AVP. - Example 1.90. t_replicate usage + Example 1.91. t_replicate usage ... # sent to 1.2.3.4:5060 over tcp t_replicate("sip:1.2.3.4:5060;transport=tcp"); @@ -2811,7 +2836,7 @@ t_replicate_to_udp("1.2.3.4", "5060"); + 0x02 - do not generate reply on internal error. + 0x04 - disable dns failover. - Example 1.91. t_relay_to usage + Example 1.92. t_relay_to usage ... # sent to 1.2.3.4:5060 over tcp t_relay_to("tcp:1.2.3.4:5060"); @@ -2837,7 +2862,7 @@ t_relay_to("0x01"); See also: e2e_cancel_reason. - Example 1.92. t_set_no_e2e_cancel_reason usage + Example 1.93. t_set_no_e2e_cancel_reason usage ... route { ... @@ -2860,7 +2885,7 @@ opying * onreply_route - the function returns true if an onreply route is set to be executed. - Example 1.93. t_replicate usage + Example 1.94. t_replicate usage ... if(!t_is_set("failure_route")) LM_DBG("no failure route will be executed for current transaction\n"); @@ -2874,7 +2899,7 @@ if(!t_is_set("failure_route")) It returns true. - Example 1.94. t_use_uac_headers usage + Example 1.95. t_use_uac_headers usage ... t_use_uac_headers(); ... @@ -2893,7 +2918,7 @@ t_use_uac_headers(); returns true if the transaction is currently reply suspended or false if not. - Example 1.95. t_is_retr_async_reply usage + Example 1.96. t_is_retr_async_reply usage ... if (t_is_retr_async_reply()) { xlog("L_DBG", "Dropping retransmitted reply which is still currently sus @@ -2918,7 +2943,7 @@ pended\n"); Content-Type header must exist. * body - SIP message body (can be empty). - Example 1.96. t_uac_send usage + Example 1.97. t_uac_send usage ... t_uac_send("OPTIONS", "sip:alice@kamailio.org", "", "", "From: bob@kamailio.org;tag=2w3e\r\nTo: bob@kamailio.org", ""); @@ -2929,7 +2954,7 @@ t_uac_send("OPTIONS", "sip:alice@kamailio.org", "", "", Return the status code for transaction - the most relevant SIP reply status code, or -1 in case of error or no status code was set. - Example 1.97. t_get_status_code usage + Example 1.98. t_get_status_code usage ... $var(ts) = t_get_status_code(); if($var(ts) == 500) { ... } @@ -2940,7 +2965,7 @@ if($var(ts) == 500) { ... } Cleans active but very old transactions. Returns true (1). Can be called from any route. - Example 1.98. t_clean usage + Example 1.99. t_clean usage ... t_clean(); ... @@ -2950,12 +2975,13 @@ t_clean(); 5.1. tm.list 5.2. tm.t_uac_start 5.3. tm.t_uac_wait - 5.4. tm.cancel - 5.5. tm.hash_stats - 5.6. tm.reply - 5.7. tm.reply_callid - 5.8. tm.clean - 5.9. tm.stats + 5.4. tm.t_uac_wait + 5.5. tm.cancel + 5.6. tm.hash_stats + 5.7. tm.reply + 5.8. tm.reply_callid + 5.9. tm.clean + 5.10. tm.stats 5.1. tm.list @@ -2981,10 +3007,17 @@ t_clean(); 5.3. tm.t_uac_wait - Similar to tm.t_uac_start, but waits for the SIP response and tries to - provide its details via RPC response. + Similar to tm.t_uac_start, but waits asynchronously for the SIP + response and tries to provide its details via RPC response. + +5.4. tm.t_uac_wait + + Similar to tm.t_uac_start, but blocks waiting for the SIP response and + returns the SIP reply code and reason text via RPC response. It waits + up to 80 seconds, if no reply is received, it returns a RPC fault 500 + code. While waiting, the RPC process cannot handle other RPC commands. -5.4. tm.cancel +5.5. tm.cancel Generates and sends a CANCEL for an existing local SIP request. @@ -2992,14 +3025,14 @@ t_clean(); * callid - callid of the INVITE request to be cancelled. * cseq - cseq of the INVITE request to be cancelled. -5.5. tm.hash_stats +5.6. tm.hash_stats Gets information about the load of TM internal hash table. Parameters: * none -5.6. tm.reply +5.7. tm.reply Generates and sends a reply for an existing inbound SIP transaction. @@ -3013,7 +3046,7 @@ t_clean(); * body - (optional, may not be present) reply body (if present, requires the “Content-Type” and “Content-length” headers) -5.7. tm.reply_callid +5.8. tm.reply_callid Generates and sends a reply for an existing inbound SIP transaction. @@ -3028,14 +3061,14 @@ t_clean(); * body - (optional, may not be present) reply body (if present, requires the “Content-Type” and “Content-length” headers) -5.8. tm.clean +5.9. tm.clean Trigger an hard clean of expired transactions. Parameters: * none -5.9. tm.stats +5.10. tm.stats Gets information about current and past TM transaction handling. @@ -3058,7 +3091,7 @@ t_clean(); enabled with the t_on_branch_failure function. This event_route uses the BRANCH_FAILURE_ROUTE route type. - Example 1.99. event_route[tm:branch-failure:id] usage + Example 1.100. event_route[tm:branch-failure:id] usage ... request_route { ... @@ -3084,7 +3117,7 @@ event_route[tm:branch-failure:myroute] { The request can still be updated, i.e., changes are possible to R-URI ($ru), destination URI ($du) or the send socket ($fs). - Example 1.100. event_route[tm:local-request] usage + Example 1.101. event_route[tm:local-request] usage ... event_route [tm:local-request] { xlog("L_INFO", "Routing locally generated $rm to $ru\n"); @@ -3097,7 +3130,7 @@ event_route [tm:local-request] { Executed after the tm module sent a local generated, transaction stateful response. - Example 1.101. event_route[tm:local-response] usage + Example 1.102. event_route[tm:local-response] usage ... event_route[tm:local-response] { xlog("tm:local-response replied locally\n"); diff --git a/src/modules/tm/doc/functions.xml b/src/modules/tm/doc/functions.xml index acfc590ff..f9c9837fb 100644 --- a/src/modules/tm/doc/functions.xml +++ b/src/modules/tm/doc/functions.xml @@ -668,7 +668,7 @@ route { t_reset_max_lifetime() - Resets the the maximum lifetime for the current INVITE or non-INVITE + Resets the maximum lifetime for the current INVITE or non-INVITE transaction to the default value (set using the tm module parameter max_inv_lifetime or max_noninv_lifetime). diff --git a/src/modules/tm/doc/params.xml b/src/modules/tm/doc/params.xml index 47b39d241..0b4a4445c 100644 --- a/src/modules/tm/doc/params.xml +++ b/src/modules/tm/doc/params.xml @@ -1547,6 +1547,35 @@ modparam("tm", "rich_redirect", 3) ... modparam("tm", "exec_time_check", 0) ... + + +
+ +
+ <varname>reply_relay_mode</varname> (int) + + If set to 1, a received 200ok response that was suspeneded is no + longer forwarded in the transactional context if another final + response was forward while 200ok was suspended. Forwarding the 200ok, + even it was received first, results in overwritting the transaction + response buffer that can impact matching of incoming ACKs. + + + Set it to 0 in order to disable this behaviour and attempt to forward + suspended 200ok in the transaction context. This was the behaviour + before the commit 18410da0. + + + + Default value is 1. + + + + Set <varname>reply_relay_mode</varname> parameter + +... +modparam("tm", "reply_relay_mode", 0) +...
diff --git a/src/modules/tm/doc/rpc.xml b/src/modules/tm/doc/rpc.xml index 3304b390d..18eeccd97 100644 --- a/src/modules/tm/doc/rpc.xml +++ b/src/modules/tm/doc/rpc.xml @@ -65,8 +65,20 @@ tm.t_uac_wait - Similar to tm.t_uac_start, but waits for the SIP response and tries to - provide its details via RPC response. + Similar to tm.t_uac_start, but waits asynchronously for the SIP response + and tries to provide its details via RPC response. + +
+ +
+ + <function moreinfo="none">tm.t_uac_wait</function> + + + Similar to tm.t_uac_start, but blocks waiting for the SIP response and + returns the SIP reply code and reason text via RPC response. It waits + up to 80 seconds, if no reply is received, it returns a RPC fault 500 + code. While waiting, the RPC process cannot handle other RPC commands.
diff --git a/src/modules/tm/lw_parser.c b/src/modules/tm/lw_parser.c index fa8cd5350..d13ec5831 100644 --- a/src/modules/tm/lw_parser.c +++ b/src/modules/tm/lw_parser.c @@ -31,6 +31,16 @@ #define READ(val) \ (*(val + 0) + (*(val + 1) << 8) + (*(val + 2) << 16) + (*(val + 3) << 24)) +#define LW_HNAME_SET(_p, _end, _hnlen, _type, _htype) \ + do { \ + if(_end - _p > _hnlen) { \ + if(_p[_hnlen] == ':' || _p[_hnlen] == ' ') { \ + *_type = _htype; \ + _p += _hnlen; \ + } \ + } \ + } while(0) + /* * lightweight header field name parser * used by build_local_reparse() function in order to construct ACK or CANCEL request @@ -50,122 +60,111 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) p = begin; val = LOWER_DWORD(READ(p)); + *type = HDR_OTHER_T; switch(val) { case _cseq_: /* Cseq */ - *type = HDR_CSEQ_T; - p += 4; + LW_HNAME_SET(p, end, 4, type, HDR_CSEQ_T); break; case _via1_: /* Via */ case _via2_: - *type = HDR_VIA_T; - p += 3; + LW_HNAME_SET(p, end, 3, type, HDR_VIA_T); break; case _from_: /* From */ - *type = HDR_FROM_T; - p += 4; + LW_HNAME_SET(p, end, 4, type, HDR_FROM_T); break; case _to12_: /* To */ - *type = HDR_TO_T; - p += 2; + LW_HNAME_SET(p, end, 2, type, HDR_TO_T); break; case _requ_: /* Require */ - p += 4; - val = LOWER_DWORD(READ(p)); + if(end - begin < 8) { + return begin; + } + + val = LOWER_DWORD(READ(p + 4)); switch(val) { case _ire1_: case _ire2_: - p += 3; - *type = HDR_REQUIRE_T; + LW_HNAME_SET(p, end, 7, type, HDR_REQUIRE_T); break; default: - p -= 4; *type = HDR_OTHER_T; break; } break; case _prox_: /* Proxy-Require */ + if(end - begin < 14) { + return begin; + } if((LOWER_DWORD(READ(p + 4)) == _y_re_) && (LOWER_DWORD(READ(p + 8)) == _quir_) && (LOWER_BYTE(*(p + 12)) == 'e')) { - - p += 13; - *type = HDR_PROXYREQUIRE_T; - break; - - } else { - *type = HDR_OTHER_T; + LW_HNAME_SET(p, end, 13, type, HDR_PROXYREQUIRE_T); break; } + break; case _cont_: /* Content-Length */ + if(end - begin < 15) { + return begin; + } if((LOWER_DWORD(READ(p + 4)) == _ent__) && (LOWER_DWORD(READ(p + 8)) == _leng_) && (LOWER_BYTE(*(p + 12)) == 't') && (LOWER_BYTE(*(p + 13)) == 'h')) { - - p += 14; - *type = HDR_CONTENTLENGTH_T; - break; - } else { - *type = HDR_OTHER_T; + LW_HNAME_SET(p, end, 14, type, HDR_CONTENTLENGTH_T); break; } + break; case _call_: /* Call-Id */ + if(end - begin < 8) { + return begin; + } - p += 4; - val = LOWER_DWORD(READ(p)); + val = LOWER_DWORD(READ(p + 4)); switch(val) { - case __id1_: case __id2_: - p += 3; - *type = HDR_CALLID_T; - break; - - default: - p -= 4; - *type = HDR_OTHER_T; + LW_HNAME_SET(p, end, 7, type, HDR_CALLID_T); break; } break; case _rout_: /* Route */ + if(end - begin < 6) { + return begin; + } if(LOWER_BYTE(*(p + 4)) == 'e') { - p += 5; - *type = HDR_ROUTE_T; - break; - } else { - *type = HDR_OTHER_T; + LW_HNAME_SET(p, end, 5, type, HDR_ROUTE_T); break; } + break; case _max__: /* Max-Forwards */ + if(end - begin < 13) { + return begin; + } if((LOWER_DWORD(READ(p + 4)) == _forw_) && (LOWER_DWORD(READ(p + 8)) == _ards_)) { - - p += 12; - *type = HDR_MAXFORWARDS_T; - break; - } else { - *type = HDR_OTHER_T; + LW_HNAME_SET(p, end, 12, type, HDR_MAXFORWARDS_T); break; } + break; default: /* compact headers */ @@ -177,7 +176,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) *type = HDR_VIA_T; break; } - *type = HDR_OTHER_T; break; case 'f': /* From */ @@ -186,7 +184,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) *type = HDR_FROM_T; break; } - *type = HDR_OTHER_T; break; case 't': /* To */ @@ -200,7 +197,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) *type = HDR_TO_T; break; } - *type = HDR_OTHER_T; break; case 'l': /* Content-Length */ @@ -209,7 +205,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) *type = HDR_CONTENTLENGTH_T; break; } - *type = HDR_OTHER_T; break; case 'i': /* Call-Id */ @@ -218,11 +213,6 @@ char *lw_get_hf_name(char *begin, char *end, enum _hdr_types_t *type) *type = HDR_CALLID_T; break; } - *type = HDR_OTHER_T; - break; - - default: - *type = HDR_OTHER_T; break; } } diff --git a/src/modules/tm/rpc_uac.c b/src/modules/tm/rpc_uac.c index cc50274f0..4ca2274c9 100644 --- a/src/modules/tm/rpc_uac.c +++ b/src/modules/tm/rpc_uac.c @@ -23,17 +23,204 @@ #include "../../core/ut.h" #include "../../core/parser/parse_from.h" #include "../../core/str_list.h" +#include "../../core/timer_proc.h" +#include "../../core/utils/sruid.h" #include "ut.h" #include "dlg.h" #include "uac.h" #include "callid.h" - /* RPC substitution char (used in rpc_t_uac headers) */ #define SUBST_CHAR '!' +#define TM_RPC_RESPONSE_LIFETIME 300 +#define TM_RPC_RESPONSE_TIMERSTEP 10 + +void tm_rpc_response_list_clean(unsigned int ticks, void *param); + +typedef struct tm_rpc_response { + str ruid; + int flags; + int rcode; + str rtext; + time_t rtime; + struct tm_rpc_response *next; +} tm_rpc_response_t; + +typedef struct tm_rpc_response_list { + gen_lock_t rlock; + tm_rpc_response_t *rlist; +} tm_rpc_response_list_t; + +static tm_rpc_response_list_t *_tm_rpc_response_list = NULL; + +static sruid_t _tm_rpc_sruid; + +/** + * + */ +int tm_rpc_response_list_init(void) +{ + if(_tm_rpc_response_list != NULL) { + return 0; + } + if(sruid_init(&_tm_rpc_sruid, '-', "tmrp", SRUID_INC)<0) { + LM_ERR("failed to init sruid\n"); + return -1; + } + if(sr_wtimer_add(tm_rpc_response_list_clean, 0, + TM_RPC_RESPONSE_TIMERSTEP)<0) { + LM_ERR("failed to register timer routine\n"); + return -1; + } + _tm_rpc_response_list = shm_malloc(sizeof(tm_rpc_response_list_t)); + if(_tm_rpc_response_list == NULL) { + SHM_MEM_ERROR; + return -1; + } + + memset(_tm_rpc_response_list, 0, sizeof(tm_rpc_response_list_t)); + + lock_init(&_tm_rpc_response_list->rlock); + + return 0; +} + +/** + * + */ +int tm_rpc_response_list_destroy(void) +{ + tm_rpc_response_t *rl0 = NULL; + tm_rpc_response_t *rl1 = NULL; + + if(_tm_rpc_response_list == NULL) { + return 0; + } + + rl1 = _tm_rpc_response_list->rlist; + + while(rl1!=NULL) { + rl0 = rl1; + rl1 = rl1->next; + shm_free(rl0); + } + lock_destroy(&_tm_rpc_response_list->rlock); + shm_free(_tm_rpc_response_list); + _tm_rpc_response_list = NULL; + + return 0; +} + +/** + * + */ +int tm_rpc_response_list_add(str *ruid, int rcode, str *rtext) +{ + size_t rsize = 0; + tm_rpc_response_t *ri = NULL; + if(_tm_rpc_response_list == NULL) { + LM_ERR("rpc response list not initialized\n"); + return -1; + } + + rsize = sizeof(tm_rpc_response_t) + ruid->len + 2 + + ((rtext!=NULL)?rtext->len:0); + + ri = (tm_rpc_response_t*)shm_malloc(rsize); + if(ri==NULL) { + SHM_MEM_ERROR; + return -1; + } + memset(ri, 0, rsize); + + ri->ruid.s = (char*)ri + sizeof(tm_rpc_response_t); + ri->ruid.len = ruid->len; + memcpy(ri->ruid.s, ruid->s, ruid->len); + ri->rtime = time(NULL); + ri->rcode = rcode; + if(rtext!=NULL) { + ri->rtext.s = ri->ruid.s + ri->ruid.len + 1; + ri->rtext.len = rtext->len; + memcpy(ri->rtext.s, rtext->s, rtext->len); + } + lock_get(&_tm_rpc_response_list->rlock); + ri->next = _tm_rpc_response_list->rlist; + _tm_rpc_response_list->rlist = ri; + lock_release(&_tm_rpc_response_list->rlock); + + return 0; +} + +/** + * + */ +tm_rpc_response_t *tm_rpc_response_list_get(str *ruid) +{ + tm_rpc_response_t *ri0 = NULL; + tm_rpc_response_t *ri1 = NULL; + + if(_tm_rpc_response_list == NULL) { + LM_ERR("rpc response list not initialized\n"); + return NULL; + } + + lock_get(&_tm_rpc_response_list->rlock); + ri1 = _tm_rpc_response_list->rlist; + while(ri1!=NULL) { + if(ri1->ruid.len==ruid->len + && memcmp(ri1->ruid.s, ruid->s, ruid->len)==0) { + if(ri0 == NULL) { + _tm_rpc_response_list->rlist = ri1->next; + } else { + ri0->next = ri1->next; + } + lock_release(&_tm_rpc_response_list->rlock); + return ri1; + } + ri0 = ri1; + ri1 = ri1->next; + } + lock_release(&_tm_rpc_response_list->rlock); + return NULL; +} + +/** + * + */ +void tm_rpc_response_list_clean(unsigned int ticks, void *param) +{ + tm_rpc_response_t *ri0 = NULL; + tm_rpc_response_t *ri1 = NULL; + time_t tnow; + + if(_tm_rpc_response_list == NULL) { + return; + } + tnow = time(NULL); + lock_get(&_tm_rpc_response_list->rlock); + ri1 = _tm_rpc_response_list->rlist; + while(ri1!=NULL) { + if(ri1->rtime < tnow - TM_RPC_RESPONSE_LIFETIME) { + LM_DBG("freeing item [%.*s]\n", ri1->ruid.len, ri1->ruid.s); + if(ri0 == NULL) { + _tm_rpc_response_list->rlist = ri1->next; + shm_free(ri1); + ri1 = _tm_rpc_response_list->rlist; + } else { + ri0->next = ri1->next; + shm_free(ri1); + ri1 = ri0->next; + } + } else { + ri0 = ri1; + ri1 = ri1->next; + } + } + lock_release(&_tm_rpc_response_list->rlock); +} /** make sure the rpc user created the msg properly. * Make sure that the FIFO user created the message @@ -393,6 +580,25 @@ static void rpc_uac_callback(struct cell* t, int type, struct tmcb_params* ps) } +/* t_uac callback */ +static void rpc_uac_block_callback(struct cell* t, int type, + struct tmcb_params* ps) +{ + str *ruid; + str rtext; + + ruid = (str*)(*ps->param); + *ps->param=0; + if (ps->rpl==FAKED_REPLY) { + rtext.s = error_text(ps->code); + rtext.len = strlen(rtext.s); + } else { + rtext = ps->rpl->first_line.u.reply.reason; + } + tm_rpc_response_list_add(ruid, ps->code, &rtext); + shm_free(ruid); +} + /** rpc t_uac version- * It expects the following list of strings as parameters: @@ -433,11 +639,15 @@ static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait) dlg_t dlg; uac_req_t uac_req; rpc_delayed_ctx_t* dctx; + str *ruid = NULL; + tm_rpc_response_t *ritem = NULL; + int rcount = 0; + void* th = NULL; body.s=0; body.len=0; dctx=0; - if (reply_wait && (rpc->capabilities == 0 || + if (reply_wait==1 && (rpc->capabilities == 0 || !(rpc->capabilities(c) & RPC_DELAYED_REPLY))) { rpc->fault(c, 600, "Reply wait/async mode not supported" " by this rpc transport"); @@ -538,7 +748,7 @@ static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait) if(hfb.s!=NULL && hfb.len>0) uac_req.headers=&hfb; uac_req.body=body.len?&body:0; uac_req.dialog=&dlg; - if (reply_wait){ + if (reply_wait==1){ dctx=rpc->delayed_ctx_new(c); if (dctx==0){ rpc->fault(c, 500, "internal error: failed to create context"); @@ -551,22 +761,57 @@ static void rpc_t_uac(rpc_t* rpc, void* c, int reply_wait) want to still send a reply */ rpc=&dctx->rpc; c=dctx->reply_ctx; + } else if (reply_wait==2) { + sruid_next(&_tm_rpc_sruid); + uac_req.cb = rpc_uac_block_callback; + ruid = shm_str_dup_block(&_tm_rpc_sruid.uid); + uac_req.cbp = ruid; + uac_req.cb_flags = TMCB_LOCAL_COMPLETED; } + ret = t_uac(&uac_req); if (ret <= 0) { err_ret = err2reason_phrase(ret, &sip_error, err_buf, sizeof(err_buf), "RPC/UAC") ; - if (err_ret > 0 ) - { + if (err_ret > 0 ) { rpc->fault(c, sip_error, "%s", err_buf); } else { rpc->fault(c, 500, "RPC/UAC error"); } - if (dctx) + if (dctx) { rpc->delayed_ctx_close(dctx); + } + if(ruid) { + shm_free(ruid); + } goto error01; } + + if(reply_wait==2) { + while(ritem==NULL && rcount<800) { + sleep_us(100000); + rcount++; + ritem = tm_rpc_response_list_get(&_tm_rpc_sruid.uid); + } + if(ritem == NULL) { + rpc->fault(c, 500, "No response"); + } else { + /* add structure node */ + if (rpc->add(c, "{", &th) < 0) { + rpc->fault(c, 500, "Structure error"); + } else { + if(rpc->struct_add(th, "dS", + "code", ritem->rcode, + "text", &ritem->rtext)<0) { + rpc->fault(c, 500, "Fields error"); + return; + } + } + shm_free(ritem); + } + } + error01: if (hfb.s) pkg_free(hfb.s); error: @@ -590,10 +835,18 @@ void rpc_t_uac_wait(rpc_t* rpc, void* c) rpc_t_uac(rpc, c, 1); } +/** t_uac with blocking for reply waiting. + * @see rpc_t_uac. + */ +void rpc_t_uac_wait_block(rpc_t* rpc, void* c) +{ + rpc_t_uac(rpc, c, 2); +} + static int t_uac_check_msg(struct sip_msg* msg, str* method, str* body, - int* fromtag, int *cseq_is, int* cseq, + str *fromtag, int *cseq_is, int* cseq, str* callid) { struct to_body* parsed_from; @@ -628,7 +881,13 @@ static int t_uac_check_msg(struct sip_msg* msg, } parsed_from = (struct to_body*)msg->from->parsed; - *fromtag = parsed_from->tag_value.s && parsed_from->tag_value.len; + if(parsed_from->tag_value.s && parsed_from->tag_value.len) { + fromtag->s = parsed_from->tag_value.s; + fromtag->len = parsed_from->tag_value.len; + } else { + fromtag->s = NULL; + fromtag->len = 0; + } *cseq = 0; if (msg->cseq && (parsed_cseq = get_cseq(msg))) { @@ -676,7 +935,8 @@ int t_uac_send(str *method, str *ruri, str *nexthop, str *send_socket, struct socket_info* ssock; str saddr; int sport, sproto; - int ret, fromtag, cseq_is, cseq; + int ret, cseq_is, cseq; + str fromtag; dlg_t dlg; uac_req_t uac_req; @@ -749,7 +1009,9 @@ int t_uac_send(str *method, str *ruri, str *nexthop, str *send_socket, */ /* Generate fromtag if not present */ - if (!fromtag) { + if (fromtag.s && fromtag.len) { + dlg.id.loc_tag = fromtag; + } else { generate_fromtag(&dlg.id.loc_tag, &dlg.id.call_id, ruri); } @@ -758,8 +1020,11 @@ int t_uac_send(str *method, str *ruri, str *nexthop, str *send_socket, else dlg.loc_seq.value = DEFAULT_CSEQ; dlg.loc_seq.is_set = 1; - dlg.loc_uri = faked_msg.from->body; - dlg.rem_uri = faked_msg.to->body; + dlg.loc_uri = get_from(&faked_msg)->uri; + dlg.rem_uri = get_to(&faked_msg)->uri; + if(get_to(&faked_msg)->tag_value.len > 0) { + dlg.id.rem_tag = get_to(&faked_msg)->tag_value; + } dlg.rem_target = *ruri; dlg.dst_uri = *nexthop; dlg.send_sock=ssock; diff --git a/src/modules/tm/rpc_uac.h b/src/modules/tm/rpc_uac.h index 1f4c4e2c4..7cea70ab6 100644 --- a/src/modules/tm/rpc_uac.h +++ b/src/modules/tm/rpc_uac.h @@ -21,8 +21,12 @@ #include "../../core/rpc.h" +int tm_rpc_response_list_init(void); +int tm_rpc_response_list_destroy(void); + void rpc_t_uac_start(rpc_t* rpc, void* c); void rpc_t_uac_wait(rpc_t* rpc, void* c); +void rpc_t_uac_wait_block(rpc_t* rpc, void* c); int t_uac_send(str *method, str *ruri, str *nexthop, str *send_socket, str *headers, str *body); diff --git a/src/modules/tm/t_msgbuilder.c b/src/modules/tm/t_msgbuilder.c index bd75b271b..cda84b6f5 100644 --- a/src/modules/tm/t_msgbuilder.c +++ b/src/modules/tm/t_msgbuilder.c @@ -268,6 +268,7 @@ char *build_local_reparse(tm_cell_t *Trans,unsigned int branch, struct hdr_field *reas1, *reas_last, *hdr; int hadded = 0; sr_cfgenv_t *cenv = NULL; + hdr_flags_t hdr_flags = 0; invite_buf = Trans->uac[branch].request.buffer; invite_len = Trans->uac[branch].request.buffer_len; @@ -361,6 +362,11 @@ char *build_local_reparse(tm_cell_t *Trans,unsigned int branch, switch(hf_type) { case HDR_CSEQ_T: /* find the method name and replace it */ + if(hdr_flags & HDR_CSEQ_F) { + LM_DBG("duplicate CSeq header\n"); + goto errorhdr; + } + hdr_flags |= HDR_CSEQ_F; while ((s < invite_buf_end) && ((*s == ':') || (*s == ' ') || (*s == '\t') || ((*s >= '0') && (*s <= '9'))) @@ -381,6 +387,12 @@ char *build_local_reparse(tm_cell_t *Trans,unsigned int branch, break; case HDR_TO_T: + if(hdr_flags & HDR_TO_F) { + LM_DBG("duplicate To header\n"); + goto errorhdr; + } + hdr_flags |= HDR_TO_F; + if (to_len == 0) { /* there is no To tag required, just copy paste * the header */ @@ -395,7 +407,25 @@ char *build_local_reparse(tm_cell_t *Trans,unsigned int branch, break; case HDR_FROM_T: + /* copy hf */ + if(hdr_flags & HDR_FROM_F) { + LM_DBG("duplicate From header\n"); + goto errorhdr; + } + hdr_flags |= HDR_FROM_F; + s = lw_next_line(s, invite_buf_end); + append_str(d, s1, s - s1); + break; case HDR_CALLID_T: + /* copy hf */ + if(hdr_flags & HDR_CALLID_F) { + LM_DBG("duplicate Call-Id header\n"); + goto errorhdr; + } + hdr_flags |= HDR_CALLID_F; + s = lw_next_line(s, invite_buf_end); + append_str(d, s1, s - s1); + break; case HDR_ROUTE_T: case HDR_MAXFORWARDS_T: /* copy hf */ @@ -495,6 +525,7 @@ char *build_local_reparse(tm_cell_t *Trans,unsigned int branch, /* HDR_EOH_T was not found in the buffer, the message is corrupt */ LM_ERR("HDR_EOH_T was not found\n"); +errorhdr: shm_free(cancel_buf); error: LM_ERR("cannot build %.*s request\n", method_len, method); diff --git a/src/modules/tm/t_reply.c b/src/modules/tm/t_reply.c index 328c6743d..728560f11 100644 --- a/src/modules/tm/t_reply.c +++ b/src/modules/tm/t_reply.c @@ -109,6 +109,10 @@ extern int tm_remap_503_500; /* send path and flags in 3xx class reply */ int tm_rich_redirect = 0; +/* control if reply should be relayed + * when transaction reply status is RPS_PUSHED_AFTER_COMPLETION */ +extern int tm_reply_relay_mode; + /* how to deal with winning branch reply selection in failure_route * can be overwritten per transaction with t_drop_replies(...) * Values: @@ -1249,17 +1253,19 @@ inline static short int get_prio(unsigned int resp, struct sip_msg *rpl) int t_pick_branch(int inc_branch, int inc_code, struct cell *t, int *res_code) { int best_b, best_s, b; - sip_msg_t *rpl; + sip_msg_t *rpl, *best_rpl; best_b=-1; best_s=0; + best_rpl=NULL; for ( b=0; bnr_of_outgoings ; b++ ) { rpl = t->uac[b].reply; /* "fake" for the currently processed branch */ if (b==inc_branch) { - if (get_prio(inc_code, rpl) t_send_branch "faked" reply, skip over it */ if ( rpl && - get_prio(t->uac[b].last_received, rpl)uac[b].last_received, rpl)uac[b].last_received; + best_rpl=rpl; } } /* find lowest branch */ @@ -2041,40 +2048,43 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch, goto error02; } - /* attempt to copy the message to UAS's shmem: - * - copy to-tag for ACK matching as well - * - allocate little a bit more for provisional as - * larger messages are likely to follow and we will be - * able to reuse the memory frag - */ - if (res_len<=0) { - LM_ERR("invalid new buffer len\n"); - goto error03; - } - uas_rb->buffer = (char*)shm_resize( uas_rb->buffer, res_len + - (msg_status<200 ? REPLY_OVERBUFFER_LEN : 0)); - if (!uas_rb->buffer) { - LM_ERR("cannot alloc reply shmem\n"); - goto error03; - } - uas_rb->rbtype = relayed_code; - uas_rb->buffer_len = res_len; - memcpy( uas_rb->buffer, buf, res_len ); - if (relayed_msg==FAKED_REPLY) { /* to-tags for local replies */ - update_local_tags(t, &bm, uas_rb->buffer, buf); - t_stats_rpl_generated(); - } + if (tm_reply_relay_mode == 0 + || reply_status != RPS_PUSHED_AFTER_COMPLETION) { + /* attempt to copy the message to UAS's shmem: + * - copy to-tag for ACK matching as well + * - allocate little a bit more for provisional as + * larger messages are likely to follow and we will be + * able to reuse the memory frag + */ + if (res_len<=0) { + LM_ERR("invalid new buffer len\n"); + goto error03; + } + uas_rb->buffer = (char*)shm_resize( uas_rb->buffer, res_len + + (msg_status<200 ? REPLY_OVERBUFFER_LEN : 0)); + if (!uas_rb->buffer) { + LM_ERR("cannot alloc reply shmem\n"); + goto error03; + } + uas_rb->rbtype = relayed_code; + uas_rb->buffer_len = res_len; + memcpy( uas_rb->buffer, buf, res_len ); + if (relayed_msg==FAKED_REPLY) { /* to-tags for local replies */ + update_local_tags(t, &bm, uas_rb->buffer, buf); + t_stats_rpl_generated(); + } - /* update the status ... */ - t->uas.status = relayed_code; - t->relayed_reply_branch = relay; + /* update the status ... */ + t->uas.status = relayed_code; + t->relayed_reply_branch = relay; - if ( unlikely(is_invite(t) && relayed_msg!=FAKED_REPLY - && relayed_code>=200 && relayed_code < 300 - && has_tran_tmcbs( t, - TMCB_RESPONSE_OUT|TMCB_RESPONSE_READY - |TMCB_E2EACK_IN|TMCB_E2EACK_RETR_IN))) { - totag_retr=update_totag_set(t, relayed_msg); + if ( unlikely(is_invite(t) && relayed_msg!=FAKED_REPLY + && relayed_code>=200 && relayed_code < 300 + && has_tran_tmcbs( t, + TMCB_RESPONSE_OUT|TMCB_RESPONSE_READY + |TMCB_E2EACK_IN|TMCB_E2EACK_RETR_IN))) { + totag_retr=update_totag_set(t, relayed_msg); + } } } /* if relay ... */ @@ -2099,7 +2109,9 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch, } if (likely(uas_rb->dst.send_sock)) { if (onsend_route_enabled(SIP_REPLY) && p_msg - && (p_msg != FAKED_REPLY)) { + && (p_msg != FAKED_REPLY) + && (tm_reply_relay_mode == 0 + || reply_status != RPS_PUSHED_AFTER_COMPLETION)) { if (run_onsend(p_msg, &uas_rb->dst, buf, res_len)==0){ su2ip_addr(&ip, &(uas_rb->dst.to)); LM_ERR("reply to %s:%d(%d) dropped" @@ -2115,7 +2127,9 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch, if (SEND_PR_BUFFER( uas_rb, buf, res_len ) >= 0){ LM_DBG("reply buffer sent out\n"); if (unlikely(!totag_retr - && has_tran_tmcbs(t, TMCB_RESPONSE_OUT))){ + && has_tran_tmcbs(t, TMCB_RESPONSE_OUT) + && (tm_reply_relay_mode == 0 + || reply_status != RPS_PUSHED_AFTER_COMPLETION))){ LOCK_REPLIES( t ); if(relayed_code==uas_rb->rbtype) { run_trans_callbacks_with_buf( TMCB_RESPONSE_OUT, uas_rb, @@ -2127,7 +2141,9 @@ enum rps relay_reply( struct cell *t, struct sip_msg *p_msg, int branch, } UNLOCK_REPLIES( t ); } - if (unlikely(has_tran_tmcbs(t, TMCB_RESPONSE_SENT))){ + if (unlikely(has_tran_tmcbs(t, TMCB_RESPONSE_SENT) + && (tm_reply_relay_mode == 0 + || reply_status != RPS_PUSHED_AFTER_COMPLETION))){ INIT_TMCB_ONSEND_PARAMS(onsend_params, t->uas.request, relayed_msg, uas_rb, &uas_rb->dst, buf, res_len, diff --git a/src/modules/tm/t_serial.c b/src/modules/tm/t_serial.c index d27a64824..e7e9c8eed 100644 --- a/src/modules/tm/t_serial.c +++ b/src/modules/tm/t_serial.c @@ -337,7 +337,7 @@ int ki_t_load_contacts_mode(struct sip_msg* msg, int mode) } /* Check if anything needs to be done */ - LM_DBG("nr_branches is %d\n", nr_branches); + LM_DBG("nr_branches is %d - new uri mode %d\n", nr_branches, ruri_is_new); if ((nr_branches == 0) || ((nr_branches == 1) && !ruri_is_new)) { LM_DBG("nothing to do - only one contact!\n"); @@ -459,11 +459,20 @@ int ki_t_load_contacts_mode(struct sip_msg* msg, int mode) prev = (struct contact *)0; curr = contacts; - while (curr && - ((curr->q_index < next->q_index) || - ((curr->q_index == next->q_index) && (next->path.len == 0)))) { - prev = curr; - curr = curr->next; + if (mode == T_LOAD_PROPORTIONAL) { + while (curr && + ((curr->q_index < next->q_index) || + ((curr->q_index == next->q_index) && (next->path.len == 0)))) { + prev = curr; + curr = curr->next; + } + } else { + while (curr && + ((curr->q < next->q) || + ((curr->q == next->q) && (next->path.len == 0)))) { + prev = curr; + curr = curr->next; + } } if (!curr) { next->next = (struct contact *)0; diff --git a/src/modules/tm/tm.c b/src/modules/tm/tm.c index 99c932b41..af2e52f22 100644 --- a/src/modules/tm/tm.c +++ b/src/modules/tm/tm.c @@ -222,6 +222,10 @@ str on_sl_reply_name = {NULL, 0}; int tm_remap_503_500 = 1; str _tm_event_callback_lres_sent = {NULL, 0}; +/* control if reply should be relayed + * when transaction reply status is RPS_PUSHED_AFTER_COMPLETION */ +int tm_reply_relay_mode = 1; + unsigned long tm_exec_time_check = 0; /* microseconds */ int tm_exec_time_check_param = 5000; /* milliseconds */ @@ -480,6 +484,7 @@ static param_export_t params[]={ {"rich_redirect" , PARAM_INT, &tm_rich_redirect }, {"event_callback_lres_sent", PARAM_STR, &_tm_event_callback_lres_sent }, {"exec_time_check" , PARAM_INT, &tm_exec_time_check_param }, + {"reply_relay_mode", PARAM_INT, &tm_reply_relay_mode }, {0,0,0} }; @@ -723,6 +728,11 @@ static int mod_init(void) return -1; } + if(tm_rpc_response_list_init()<0) { + LM_ERR("failed to init rpc\n"); + return -1; + } + if(on_sl_reply_name.s!=NULL && on_sl_reply_name.len>0) { keng = sr_kemi_eng_get(); if(keng==NULL) { @@ -2767,6 +2777,13 @@ static const char* rpc_t_uac_wait_doc[2] = { 0 }; +static const char* rpc_t_uac_wait_block_doc[2] = { + "starts a tm uac and waits for the final reply in blocking mode, using a" + " list of string parameters: method, ruri, dst_uri send_sock, headers" + " (CRLF separated) and body (optional)", + 0 +}; + static const char* tm_rpc_list_doc[2] = { "List transactions.", 0 @@ -2787,6 +2804,7 @@ static rpc_export_t tm_rpc[] = { {"tm.hash_stats", tm_rpc_hash_stats, tm_rpc_hash_stats_doc, 0}, {"tm.t_uac_start", rpc_t_uac_start, rpc_t_uac_start_doc, 0 }, {"tm.t_uac_wait", rpc_t_uac_wait, rpc_t_uac_wait_doc, RET_ARRAY}, + {"tm.t_uac_wait_block", rpc_t_uac_wait_block, rpc_t_uac_wait_block_doc, 0}, {"tm.list", tm_rpc_list, tm_rpc_list_doc, RET_ARRAY}, {"tm.clean", tm_rpc_clean, tm_rpc_clean_doc, 0}, {0, 0, 0, 0} diff --git a/src/modules/tmrec/README b/src/modules/tmrec/README index 7da2a2e38..1939721ac 100644 --- a/src/modules/tmrec/README +++ b/src/modules/tmrec/README @@ -306,11 +306,11 @@ if(is_leap_year("2010")) Example 1.4. time_period_match usage ... -if(time_period_match("wd{2-6} hr{8-16}, wd{1-5} hr{17} min{0-29}")) +if(time_period_match("wd{2-6} hr{8-16}, wd{2-6} hr{17} min{0-29}")) xdbg("Monday to Friday, 8:00 to 17:30\n"); -if(time_period_match("weekday { sat sun }, weekday {mo-fr} hr {17-8},wd{mo-wed}h -r{15 16 9}")) +if(time_period_match("wday { sat sun }, wday {mo-fr} hr {17-8},wd{mo-wed}hr{15 1 +6 9}")) xdbg("We're closed - open only Monday to Wednesday 10:00-15:00, Thursday and Friday 9:00-17:00"); ... diff --git a/src/modules/tmrec/doc/tmrec_admin.xml b/src/modules/tmrec/doc/tmrec_admin.xml index 2a3193c9d..1bea2e9d7 100644 --- a/src/modules/tmrec/doc/tmrec_admin.xml +++ b/src/modules/tmrec/doc/tmrec_admin.xml @@ -409,10 +409,10 @@ if(is_leap_year("2010")) <function>time_period_match</function> usage ... -if(time_period_match("wd{2-6} hr{8-16}, wd{1-5} hr{17} min{0-29}")) +if(time_period_match("wd{2-6} hr{8-16}, wd{2-6} hr{17} min{0-29}")) xdbg("Monday to Friday, 8:00 to 17:30\n"); -if(time_period_match("weekday { sat sun }, weekday {mo-fr} hr {17-8},wd{mo-wed}hr{15 16 9}")) +if(time_period_match("wday { sat sun }, wday {mo-fr} hr {17-8},wd{mo-wed}hr{15 16 9}")) xdbg("We're closed - open only Monday to Wednesday 10:00-15:00, Thursday and Friday 9:00-17:00"); ... diff --git a/src/modules/tmx/t_var.c b/src/modules/tmx/t_var.c index 15938fcd9..3e977c987 100644 --- a/src/modules/tmx/t_var.c +++ b/src/modules/tmx/t_var.c @@ -305,6 +305,11 @@ int pv_get_t_var_req(struct sip_msg *msg, pv_param_t *param, { pv_spec_t *pv=NULL; + if(!is_route_type(CORE_ONREPLY_ROUTE|TM_ONREPLY_ROUTE)) { + LM_DBG("used in unsupported route block - type %d\n", get_route_type()); + return pv_get_null(msg, param, res); + } + if(pv_t_update_req(msg)) return pv_get_null(msg, param, res); @@ -320,6 +325,11 @@ int pv_get_t_var_rpl(struct sip_msg *msg, pv_param_t *param, { pv_spec_t *pv=NULL; + if(!is_route_type(FAILURE_ROUTE|BRANCH_FAILURE_ROUTE)) { + LM_DBG("used in unsupported route block - type %d\n", get_route_type()); + return pv_get_null(msg, param, res); + } + if(pv_t_update_rpl(msg)) return pv_get_null(msg, param, res); @@ -335,6 +345,11 @@ int pv_get_t_var_branch(struct sip_msg *msg, pv_param_t *param, { pv_spec_t *pv=NULL; + if(!is_route_type(FAILURE_ROUTE|BRANCH_FAILURE_ROUTE|TM_ONREPLY_ROUTE)) { + LM_DBG("used in unsupported route block - type %d\n", get_route_type()); + return pv_get_null(msg, param, res); + } + if(pv_t_update_rpl(msg)) return pv_get_null(msg, param, res); @@ -350,6 +365,11 @@ int pv_get_t_var_inv(struct sip_msg *msg, pv_param_t *param, { pv_spec_t *pv=NULL; + if(!is_route_type(REQUEST_ROUTE)) { + LM_DBG("used in unsupported route block - type %d\n", get_route_type()); + return pv_get_null(msg, param, res); + } + if(pv_t_update_inv(msg)) return pv_get_null(msg, param, res); @@ -785,14 +805,24 @@ int pv_get_t_branch(struct sip_msg *msg, pv_param_t *param, " in MODE_ONFAILURE\n", branch); return pv_get_null(msg, param, res); } - res->ri = t->uac[branch].branch_flags; - res->flags = PV_VAL_INT; - LM_DBG("branch flags is [%u]\n", res->ri); + break; + case TM_ONREPLY_ROUTE: + tcx = _tmx_tmb.tm_ctx_get(); + if(tcx == NULL) { + LM_ERR("no reply branch\n"); + return pv_get_null(msg, param, res); + } + branch = tcx->branch_index; break; default: LM_ERR("unsupported route_type %d\n", get_route_type()); return pv_get_null(msg, param, res); } + if(branch<0 || branch>=t->nr_of_outgoings) { + return pv_get_null(msg, param, res); + } + LM_DBG("branch flags is [%u]\n", t->uac[branch].branch_flags); + return pv_get_uintval(msg, param, res, t->uac[branch].branch_flags); break; case 6: /* $T_branch(uri) */ if (get_route_type() != TM_ONREPLY_ROUTE) { diff --git a/src/modules/topos/README b/src/modules/topos/README index fd4108765..ab4020931 100644 --- a/src/modules/topos/README +++ b/src/modules/topos/README @@ -86,17 +86,21 @@ Chapter 1. Admin Guide 1. Overview - This module offers topology hiding by stripping the SIP routing headers - that show topology details. The script interpreter gets the SIP - messages with full content, so all existing functionality is preserved. + This module offers topology hiding for INVITE-based dialogs, by + stripping the SIP routing headers that show topology details . The + script interpreter gets the SIP messages with full content, so all + existing functionality is preserved. The module is transparent for the configuration writer. It only needs - to be loaded (tune the parameters if needed). + to be loaded (tune the module parameters if needed). It also works for SIP MESSAGE or other requests that do not create a - call dialog -- record_route() must be used for them as well, the - headers are not going to be in the messages sent to the network, they - are needed to know local addresses used to communicate with each side. + dialog -- record_route() must be used for them as well, the headers are + not going to be in the messages sent to the network, they are needed to + know local addresses used to communicate with each side. At this moment + it is not designed to work for presence (SUBSCRIBE-based) dialogs. The + REGISTER and PUBLISH requests are skipped from processing by this + module, expected to be terminated on a local SIP server. 2. Dependencies diff --git a/src/modules/topos/doc/topos_admin.xml b/src/modules/topos/doc/topos_admin.xml index 8b3e2a051..fa4f97b4d 100644 --- a/src/modules/topos/doc/topos_admin.xml +++ b/src/modules/topos/doc/topos_admin.xml @@ -16,20 +16,23 @@
Overview - This module offers topology hiding by stripping the SIP routing - headers that show topology details. + This module offers topology hiding for INVITE-based dialogs, by stripping + the SIP routing headers that show topology details . The script interpreter gets the SIP messages with full content, so all existing functionality is preserved. The module is transparent for the configuration writer. It only needs to be - loaded (tune the parameters if needed). + loaded (tune the module parameters if needed). It also works for SIP MESSAGE or other requests that do not create - a call dialog -- record_route() must be used for them as well, the + a dialog -- record_route() must be used for them as well, the headers are not going to be in the messages sent to the network, they are needed to know local addresses used to communicate with each side. + At this moment it is not designed to work for presence (SUBSCRIBE-based) + dialogs. The REGISTER and PUBLISH requests are skipped from processing + by this module, expected to be terminated on a local SIP server.
diff --git a/src/modules/topos/tps_storage.c b/src/modules/topos/tps_storage.c index 9cdd9ff3d..c08304d1e 100644 --- a/src/modules/topos/tps_storage.c +++ b/src/modules/topos/tps_storage.c @@ -1226,7 +1226,7 @@ int tps_db_update_branch(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd, nr_keys = 0; nr_ucols = 0; - db_keys[nr_keys]=&td_col_a_uuid; + db_keys[nr_keys]=&tt_col_a_uuid; db_ops[nr_keys]=OP_EQ; db_vals[nr_keys].type = DB1_STR; db_vals[nr_keys].nul = 0; @@ -1249,8 +1249,7 @@ int tps_db_update_branch(sip_msg_t *msg, tps_data_t *md, tps_data_t *sd, } if((mode & TPS_DBU_RPLATTRS) && msg->first_line.type==SIP_REPLY) { - if(sd->b_tag.len<=0 - && msg->first_line.u.reply.statuscode>=180 + if(msg->first_line.u.reply.statuscode>=180 && msg->first_line.u.reply.statuscode<200) { db_ucols[nr_ucols] = &tt_col_y_rr; diff --git a/src/modules/uac/README b/src/modules/uac/README index a018d29a1..b0210f2cf 100644 --- a/src/modules/uac/README +++ b/src/modules/uac/README @@ -87,6 +87,7 @@ Ramona-Elena Modroiu 8.6. uac.reg_refresh 8.7. uac.reg_active 8.8. uac.reg_add + 8.9. uac.reg_remove 9. Remote Registration @@ -137,7 +138,8 @@ Ramona-Elena Modroiu 1.43. uac.reg_refresh usage 1.44. uac.reg_active usage 1.45. uac.reg_add usage - 1.46. lookup remote registrations usage + 1.46. uac.reg_remove usage + 1.47. lookup remote registrations usage Chapter 1. Admin Guide @@ -207,6 +209,7 @@ Chapter 1. Admin Guide 8.6. uac.reg_refresh 8.7. uac.reg_active 8.8. uac.reg_add + 8.9. uac.reg_remove 9. Remote Registration @@ -803,9 +806,9 @@ failure_route[TRUNKAUTH] { $avp(auser) = "test"; $avp(apass) = "test"; # $avp(apass) = "36d0a02793542b4961e8348347236dbf"; - uac_auth(); - # uac_auth("1"); - t_relay(); + if (uac_auth()) { + t_relay(); + } exit; } } @@ -995,6 +998,7 @@ event_route[uac:reply] { 8.6. uac.reg_refresh 8.7. uac.reg_active 8.8. uac.reg_add + 8.9. uac.reg_remove 8.1. uac.reg_dump @@ -1119,6 +1123,15 @@ event_route[uac:reply] { kamcmd uac.reg_add ... ... +8.9. uac.reg_remove + + Remove a UAC remote registration record by l_uuid. + + Example 1.46. uac.reg_remove usage +... + kamcmd uac.reg_remove my_l_uuid +... + 9. Remote Registration The module can register contact addresses to remote REGISTRAR servers. @@ -1165,7 +1178,7 @@ event_route[uac:reply] { if the call is coming from a remote SIP provider and can change the R-URI to local username@domain. Afterwards you can run location lookup. - Example 1.46. lookup remote registrations usage + Example 1.47. lookup remote registrations usage ... if(uac_reg_lookup("$rU", "$ru")) { xlog("request from a remote SIP provider [$ou => $ru]\n"); diff --git a/src/modules/uac/auth.c b/src/modules/uac/auth.c index 5359300e5..22e096f64 100644 --- a/src/modules/uac/auth.c +++ b/src/modules/uac/auth.c @@ -447,7 +447,7 @@ int uac_auth_mode(sip_msg_t *msg, int mode) /* found? */ if (crd==0) { - LM_DBG("no credential for realm \"%.*s\"\n", + LM_INFO("no credential for realm \"%.*s\"\n", auth.realm.len, auth.realm.s); goto error; } diff --git a/src/modules/uac/doc/uac_admin.xml b/src/modules/uac/doc/uac_admin.xml index 7029449ac..866566add 100644 --- a/src/modules/uac/doc/uac_admin.xml +++ b/src/modules/uac/doc/uac_admin.xml @@ -873,9 +873,9 @@ failure_route[TRUNKAUTH] { $avp(auser) = "test"; $avp(apass) = "test"; # $avp(apass) = "36d0a02793542b4961e8348347236dbf"; - uac_auth(); - # uac_auth("1"); - t_relay(); + if (uac_auth()) { + t_relay(); + } exit; } } @@ -1370,7 +1370,25 @@ event_route[uac:reply] { ... -
+ + +
+ + <function moreinfo="none">uac.reg_remove</function> + + + Remove a UAC remote registration record by l_uuid. + + + + <function>uac.reg_remove</function> usage + +... + kamcmd uac.reg_remove my_l_uuid +... + + +
diff --git a/src/modules/uac/replace.c b/src/modules/uac/replace.c index c64af5299..3a476a3d8 100644 --- a/src/modules/uac/replace.c +++ b/src/modules/uac/replace.c @@ -942,26 +942,6 @@ static void replace_callback(struct dlg_cell *dlg, int type, old_uri.len, old_uri.s, new_display->len, new_display->s, new_uri->len, new_uri->s); - /* duplicate the decoded value */ - p = pkg_malloc( new_uri->len); - if (!p) { - PKG_MEM_ERROR; - return; - } - memcpy( p, new_uri->s, new_uri->len); - - /* build del/add lumps */ - l = del_lump( msg, old_uri.s-msg->buf, old_uri.len, 0); - if (l==0) { - LM_ERR("del lump failed\n"); - goto free; - } - - if (insert_new_lump_after( l, p, new_uri->len, 0)==0) { - LM_ERR("insert new lump failed\n"); - goto free; - } - /* deal with display name */ l = 0; /* first remove the existing display */ @@ -972,8 +952,8 @@ static void replace_callback(struct dlg_cell *dlg, int type, l = del_lump(msg, body->display.s-msg->buf, body->display.len, 0); if (l==0) { LM_ERR("display del lump failed\n"); - goto free; - } + return; + } } if (new_display->s && new_display->len > 0) { LM_DBG("inserting display [%.*s]\n", @@ -982,20 +962,40 @@ static void replace_callback(struct dlg_cell *dlg, int type, buf.s = pkg_malloc(new_display->len + 2); if (buf.s==0) { PKG_MEM_ERROR; - goto free; + return; } memcpy( buf.s, new_display->s, new_display->len); buf.len = new_display->len; if (l==0 && (l=get_display_anchor(msg, hdr, body, &buf)) == 0) { LM_ERR("failed to insert anchor\n"); - goto free2; + goto free1; } if (insert_new_lump_after(l, buf.s, buf.len, 0) == 0) { LM_ERR("insert new display lump failed\n"); - goto free2; + goto free1; } } + /* uri update - duplicate the decoded value */ + p = pkg_malloc( new_uri->len); + if (!p) { + PKG_MEM_ERROR; + goto free1; + } + memcpy( p, new_uri->s, new_uri->len); + + /* build del/add lumps */ + l = del_lump( msg, old_uri.s-msg->buf, old_uri.len, 0); + if (l==0) { + LM_ERR("del lump failed\n"); + goto free2; + } + + if (insert_new_lump_after( l, p, new_uri->len, 0)==0) { + LM_ERR("insert new lump failed\n"); + goto free2; + } + /* register tm callback to change replies, * but only if not registered earlier */ if (!(msg->msg_flags & (FL_USE_UAC_FROM|FL_USE_UAC_TO)) && @@ -1009,10 +1009,10 @@ static void replace_callback(struct dlg_cell *dlg, int type, return; free2: - pkg_free(buf.s); - -free: pkg_free(p); + +free1: + pkg_free(buf.s); } diff --git a/src/modules/usrloc/README b/src/modules/usrloc/README index ac3a6b7bb..d07504283 100644 --- a/src/modules/usrloc/README +++ b/src/modules/usrloc/README @@ -94,8 +94,9 @@ Carsten Bock 3.52. ka_from (str) 3.53. ka_domain (str) 3.54. ka_filter (int) - 3.55. ka_loglevel (int) - 3.56. ka_logmsg (str) + 3.55. ka_timeout (int) + 3.56. ka_loglevel (int) + 3.57. ka_logmsg (str) 4. RPC Commands @@ -197,8 +198,9 @@ Carsten Bock 1.52. ka_from parameter usage 1.53. ka_domain parameter usage 1.54. ka_filter parameter usage - 1.55. ka_loglevel parameter usage - 1.56. ka_logmsg parameter usage + 1.55. Set ka_timeout parameter + 1.56. ka_loglevel parameter usage + 1.57. ka_logmsg parameter usage Chapter 1. Admin Guide @@ -269,8 +271,9 @@ Chapter 1. Admin Guide 3.52. ka_from (str) 3.53. ka_domain (str) 3.54. ka_filter (int) - 3.55. ka_loglevel (int) - 3.56. ka_logmsg (str) + 3.55. ka_timeout (int) + 3.56. ka_loglevel (int) + 3.57. ka_logmsg (str) 4. RPC Commands @@ -404,8 +407,9 @@ Chapter 1. Admin Guide 3.52. ka_from (str) 3.53. ka_domain (str) 3.54. ka_filter (int) - 3.55. ka_loglevel (int) - 3.56. ka_logmsg (str) + 3.55. ka_timeout (int) + 3.56. ka_loglevel (int) + 3.57. ka_logmsg (str) 3.1. nat_bflag (int) @@ -683,8 +687,8 @@ modparam("usrloc", "desc_time_order", 1) 3.25. timer_interval (int) Number of seconds between two timer runs. The module uses a timer to - delete expired contacts, synchronize with database and other tasks, - that need to be run periodically. + delete expired contacts, synchronize with database, send keepalives and + other tasks, that need to be run periodically. Default value is 60. @@ -1163,19 +1167,38 @@ modparam("usrloc", "ka_domain", "mydomain.com") modparam("usrloc", "ka_filter", 1) ... -3.55. ka_loglevel (int) +3.55. ka_timeout (int) + + The parameter sets the interval in seconds after which a contact is + removed from location table if it does not reply to SIP keepalives + (usually OPTIONS ping requests). + + The features is available only for contacts that are stored in memory + (not working for db only mode of the usrloc module). + + Keepalives are sent stateless, not using TM module. The value of this + parameter has to be few times higher than timer interval. + + Default value is “0” (feature disabled). + + Example 1.55. Set ka_timeout parameter +... +modparam("usrloc", "ka_timeout", 120) +... + +3.56. ka_loglevel (int) The level to print the log message when the keepalive response is received. It should be a value between -5 (L_ALERT) and 3 (L_DBG). Default value is “255” (disabled). - Example 1.55. ka_loglevel parameter usage + Example 1.56. ka_loglevel parameter usage ... modparam("usrloc", "ka_loglevel", 1) ... -3.56. ka_logmsg (str) +3.57. ka_logmsg (str) The formatted log specification to be added to the message printed when the keepalive is received and roundtrip time is computed. The log @@ -1187,7 +1210,7 @@ modparam("usrloc", "ka_loglevel", 1) Default value is “ to-uri: [$tu] remote-addr: [$sas]”. - Example 1.56. ka_logmsg parameter usage + Example 1.57. ka_logmsg parameter usage ... modparam("usrloc", "ka_logmsg", " to-uri: [$tu] remote-addr: [$sas]") ... diff --git a/src/modules/usrloc/dlist.c b/src/modules/usrloc/dlist.c index 96a95fe3c..44ce3c637 100644 --- a/src/modules/usrloc/dlist.c +++ b/src/modules/usrloc/dlist.c @@ -236,7 +236,7 @@ int ul_ka_db_records(int partidx) continue; } ur.aor.len = strlen(p); - if(ur.aor.len >= ULKA_AORBUF_SIZE) { + if(ur.aor.len >= ULKA_AORBUF_SIZE - 1) { LM_DBG("long username ->skipping\n"); continue; } diff --git a/src/modules/usrloc/doc/usrloc_admin.xml b/src/modules/usrloc/doc/usrloc_admin.xml index 396d89828..4b624fb81 100644 --- a/src/modules/usrloc/doc/usrloc_admin.xml +++ b/src/modules/usrloc/doc/usrloc_admin.xml @@ -604,8 +604,8 @@ modparam("usrloc", "desc_time_order", 1) <varname>timer_interval</varname> (int) Number of seconds between two timer runs. The module uses a timer to - delete expired contacts, synchronize with database and other tasks, - that need to be run periodically. + delete expired contacts, synchronize with database, send keepalives + and other tasks, that need to be run periodically. @@ -1424,6 +1424,36 @@ modparam("usrloc", "ka_filter", 1)
+
+ <varname>ka_timeout</varname> (int) + + The parameter sets the interval in seconds after which a + contact is removed from location table if it does not reply to SIP + keepalives (usually OPTIONS ping requests). + + + The features is available only for contacts that are stored in memory + (not working for db only mode of the usrloc module). + + + Keepalives are sent stateless, not using TM module. The value of this + parameter has to be few times higher than timer interval. + + + + Default value is 0 (feature disabled). + + + + Set <varname>ka_timeout</varname> parameter + +... +modparam("usrloc", "ka_timeout", 120) +... + + +
+
<varname>ka_loglevel</varname> (int) diff --git a/src/modules/usrloc/ucontact.c b/src/modules/usrloc/ucontact.c index 256d9530c..95ed8d530 100644 --- a/src/modules/usrloc/ucontact.c +++ b/src/modules/usrloc/ucontact.c @@ -26,8 +26,8 @@ * - Module: \ref usrloc */ -#include "ucontact.h" -#include /* memcpy */ +#include +#include #include "../../core/mem/shm_mem.h" #include "../../core/ut.h" #include "../../core/ip_addr.h" @@ -129,7 +129,7 @@ ucontact_t* new_ucontact(str* _dom, str* _aor, str* _contact, ucontact_info_t* _ c->methods = _ci->methods; c->reg_id = _ci->reg_id; c->last_modified = _ci->last_modified; - c->last_keepalive = _ci->last_modified; + c->last_keepalive = time(NULL); c->tcpconn_id = _ci->tcpconn_id; c->server_id = _ci->server_id; c->keepalive = (_ci->cflags & ul_nat_bflag)?1:0; @@ -295,7 +295,7 @@ int mem_update_ucontact(ucontact_t* _c, ucontact_info_t* _ci) _c->cseq = _ci->cseq; _c->methods = _ci->methods; _c->last_modified = _ci->last_modified; - _c->last_keepalive = _ci->last_modified; + _c->last_keepalive = time(NULL); _c->flags = _ci->flags; _c->cflags = _ci->cflags; _c->server_id = _ci->server_id; diff --git a/src/modules/usrloc/ul_keepalive.c b/src/modules/usrloc/ul_keepalive.c index 6d93717db..a69a76d8b 100644 --- a/src/modules/usrloc/ul_keepalive.c +++ b/src/modules/usrloc/ul_keepalive.c @@ -40,6 +40,8 @@ #include "ul_keepalive.h" +extern int ul_keepalive_timeout; + static int ul_ka_send(str *kamsg, dest_info_t *kadst); /** @@ -102,11 +104,13 @@ int ul_ka_urecord(urecord_t *ur) int aortype = 0; int i; struct timeval tv; + time_t tnow = 0; if (ul_ka_mode == ULKA_NONE) { return 0; } LM_DBG("keepalive for aor: %.*s\n", ur->aor.len, ur->aor.s); + tnow = time(NULL); for(i=0; iaor.len; i++) { if(ur->aor.s[i] == '@') { @@ -131,6 +135,20 @@ int ul_ka_urecord(urecord_t *ur) continue; } } + + if(ul_keepalive_timeout>0 && uc->last_keepalive>0) { + if(uc->last_keepalive+ul_keepalive_timeout < tnow) { + /* set contact as expired in 10s */ + LM_DBG("set expired contact on keepalive (%u + %u < %u)" + " - aor: %.*s c: %.*s\n", (unsigned int)uc->last_keepalive, + (unsigned int)ul_keepalive_timeout, (unsigned int)tnow, + ur->aor.len, ur->aor.s, uc->c.len, uc->c.s); + if(uc->expires > tnow + 10) { + uc->expires = tnow + 10; + continue; + } + } + } if(uc->received.len > 0) { sdst = uc->received; } else { @@ -235,6 +253,11 @@ static int ul_ka_send(str *kamsg, dest_info_t *kadst) } #ifdef USE_TCP + else if(kadst->proto == PROTO_WS || kadst->proto == PROTO_WSS) { + /*ws-wss*/ + kadst->id=0; + return wss_send(kadst, kamsg->s, kamsg->len); + } else if(kadst->proto == PROTO_TCP) { /*tcp*/ kadst->id=0; diff --git a/src/modules/usrloc/usrloc_mod.c b/src/modules/usrloc/usrloc_mod.c index 7aecb318a..860fb715b 100644 --- a/src/modules/usrloc/usrloc_mod.c +++ b/src/modules/usrloc/usrloc_mod.c @@ -258,6 +258,7 @@ static param_export_t params[] = { {"ka_domain", PARAM_STR, &ul_ka_domain}, {"ka_method", PARAM_STR, &ul_ka_method}, {"ka_filter", PARAM_INT, &ul_ka_filter}, + {"ka_timeout", PARAM_INT, &ul_keepalive_timeout}, {"ka_loglevel", PARAM_INT, &ul_ka_loglevel}, {"ka_logmsg", PARAM_STR, &ul_ka_logmsg}, {0, 0, 0} diff --git a/src/modules/websocket/README b/src/modules/websocket/README index 8de6f92bb..7ac759b20 100644 --- a/src/modules/websocket/README +++ b/src/modules/websocket/README @@ -672,8 +672,8 @@ kamcmd ws.enable 7.1. websocket:closed When defined, the module calls event_route[websocket:closed] when a - connection closes. The connection may be identified using the the $si - and $sp pseudo-variables. + connection closes. The connection may be identified using the $si and + $sp pseudo-variables. Example 1.16. event_route[websocket:closed] usage ... diff --git a/src/modules/websocket/doc/websocket_admin.xml b/src/modules/websocket/doc/websocket_admin.xml index 35e0e626a..7cc6e0906 100644 --- a/src/modules/websocket/doc/websocket_admin.xml +++ b/src/modules/websocket/doc/websocket_admin.xml @@ -695,7 +695,7 @@ ws_close(4000, "Because I say so"); When defined, the module calls event_route[websocket:closed] when a connection closes. The connection may be identified using the - the $si and $sp pseudo-variables. + $si and $sp pseudo-variables. <function moreinfo="none">event_route[websocket:closed]</function> usage diff --git a/src/modules/xcap_server/xcap_server.c b/src/modules/xcap_server/xcap_server.c index 1556aa14b..5c1ca9004 100644 --- a/src/modules/xcap_server/xcap_server.c +++ b/src/modules/xcap_server/xcap_server.c @@ -322,7 +322,7 @@ int xcaps_xpath_hack(str *buf, int type) start = buf->s; STR_VTOZ(buf->s[buf->len-1], c); - while((start < buf->s + buf->len - 8) && (p = strstr(start, match))!=NULL) { + while((start < buf->s + buf->len - 10) && (p = strstr(start, match))!=NULL) { memcpy(p, repl, 7); start = p + 7; } diff --git a/src/modules/xhttp/api.h b/src/modules/xhttp/api.h index df7f59205..e6a9311c1 100644 --- a/src/modules/xhttp/api.h +++ b/src/modules/xhttp/api.h @@ -18,21 +18,23 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ - + #ifndef _XHTTP_API_H_ #define _XHTTP_API_H_ #include "../../core/sr_module.h" -typedef int (*xhttp_reply_f)(sip_msg_t *msg, int code, str *reason, - str *ctype, str *body); +typedef int (*xhttp_reply_f)( + sip_msg_t *msg, int code, str *reason, str *ctype, str *body); +/* clang-format off */ typedef struct xhttp_api { xhttp_reply_f reply; } xhttp_api_t; +/* clang-format on */ -typedef int (*bind_xhttp_f)(xhttp_api_t* api); -int bind_xhttp(xhttp_api_t* api); +typedef int (*bind_xhttp_f)(xhttp_api_t *api); +int bind_xhttp(xhttp_api_t *api); /** * @brief Load the XHTTP API @@ -46,8 +48,7 @@ static inline int xhttp_load_api(xhttp_api_t *api) LM_ERR("cannot find bind_xhttp\n"); return -1; } - if(bindxhttp(api)<0) - { + if(bindxhttp(api) < 0) { LM_ERR("cannot bind xhttp api\n"); return -1; } diff --git a/src/modules/xhttp/xhttp_mod.c b/src/modules/xhttp/xhttp_mod.c index 78abf5503..ba5706684 100644 --- a/src/modules/xhttp/xhttp_mod.c +++ b/src/modules/xhttp/xhttp_mod.c @@ -48,20 +48,19 @@ MODULE_VERSION -static int xhttp_handler(sip_msg_t* msg); -static int w_xhttp_send_reply(sip_msg_t* msg, char* pcode, char* preason, - char *pctype, char* pbody); +static int xhttp_handler(sip_msg_t *msg); +static int w_xhttp_send_reply( + sip_msg_t *msg, char *pcode, char *preason, char *pctype, char *pbody); static int mod_init(void); -static int fixup_xhttp_reply(void** param, int param_no); +static int fixup_xhttp_reply(void **param, int param_no); -static int pv_get_huri(struct sip_msg *msg, pv_param_t *param, - pv_value_t *res); +static int pv_get_huri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res); -static int xhttp_route_no=DEFAULT_RT; -static char* xhttp_url_match = NULL; +static int xhttp_route_no = DEFAULT_RT; +static char *xhttp_url_match = NULL; static regex_t xhttp_url_match_regexp; -static char* xhttp_url_skip = NULL; +static char *xhttp_url_skip = NULL; static regex_t xhttp_url_skip_regexp; /** SL API structure */ @@ -69,14 +68,7 @@ sl_api_t slb; static str xhttp_event_callback = STR_NULL; -static cmd_export_t cmds[] = { - {"xhttp_reply", (cmd_function)w_xhttp_send_reply, - 4, fixup_xhttp_reply, 0, REQUEST_ROUTE}, - {"bind_xhttp", (cmd_function)bind_xhttp, - 0, 0, 0, ANY_ROUTE}, - {0, 0, 0, 0, 0} -}; - +/* clang-format off */ static pv_export_t mod_pvs[] = { {{"hu", (sizeof("hu")-1)}, /* */ PVT_OTHER, pv_get_huri, 0, @@ -85,6 +77,13 @@ static pv_export_t mod_pvs[] = { { {0, 0}, 0, 0, 0, 0, 0, 0, 0 } }; +static tr_export_t mod_trans[] = { + { {"url", sizeof("url")-1}, + xhttp_tr_parse_url }, + + { { 0, 0 }, 0 } +}; + static param_export_t params[] = { {"url_match", PARAM_STRING, &xhttp_url_match}, {"url_skip", PARAM_STRING, &xhttp_url_skip}, @@ -92,6 +91,14 @@ static param_export_t params[] = { {0, 0, 0} }; +static cmd_export_t cmds[] = { + {"xhttp_reply", (cmd_function)w_xhttp_send_reply, + 4, fixup_xhttp_reply, 0, REQUEST_ROUTE}, + {"bind_xhttp", (cmd_function)bind_xhttp, + 0, 0, 0, ANY_ROUTE}, + {0, 0, 0, 0, 0} +}; + /** module exports */ struct module_exports exports= { "xhttp", /* module name */ @@ -105,13 +112,7 @@ struct module_exports exports= { 0, /* per-child init function */ 0 /* module destroy function */ }; - -static tr_export_t mod_trans[] = { - { {"url", sizeof("url")-1}, - xhttp_tr_parse_url }, - - { { 0, 0 }, 0 } -}; +/* clang-format on */ /** * @@ -122,29 +123,27 @@ static int mod_init(void) int route_no; sr_kemi_eng_t *keng = NULL; - if(xhttp_event_callback.s!=NULL && xhttp_event_callback.len>0) { + if(xhttp_event_callback.s != NULL && xhttp_event_callback.len > 0) { keng = sr_kemi_eng_get(); - if(keng==NULL) { + if(keng == NULL) { LM_ERR("failed to find kemi engine\n"); return -1; } - xhttp_route_no=-1; + xhttp_route_no = -1; } else { - route_no=route_lookup(&event_rt, "xhttp:request"); - if (route_no==-1) - { + route_no = route_lookup(&event_rt, "xhttp:request"); + if(route_no == -1) { LM_ERR("failed to find event_route[xhttp:request]\n"); return -1; } - if (event_rt.rlist[route_no]==0) - { + if(event_rt.rlist[route_no] == 0) { LM_WARN("event_route[xhttp:request] is empty\n"); } - xhttp_route_no=route_no; + xhttp_route_no = route_no; } - + /* bind the SL API */ - if (sl_load_api(&slb)!=0) { + if(sl_load_api(&slb) != 0) { LM_ERR("cannot bind to SL API\n"); return -1; } @@ -154,24 +153,22 @@ static int mod_init(void) nsh.name = "xhttp"; nsh.destroy = 0; nsh.on_nonsip_req = xhttp_handler; - if (register_nonsip_msg_hook(&nsh)<0) - { + if(register_nonsip_msg_hook(&nsh) < 0) { LM_ERR("Failed to register non sip msg hooks\n"); return -1; } - if(xhttp_url_match!=NULL) - { + if(xhttp_url_match != NULL) { memset(&xhttp_url_match_regexp, 0, sizeof(regex_t)); - if (regcomp(&xhttp_url_match_regexp, xhttp_url_match, REG_EXTENDED)!=0) { + if(regcomp(&xhttp_url_match_regexp, xhttp_url_match, REG_EXTENDED) + != 0) { LM_ERR("bad match re %s\n", xhttp_url_match); return E_BAD_RE; } } - if(xhttp_url_skip!=NULL) - { + if(xhttp_url_skip != NULL) { memset(&xhttp_url_skip_regexp, 0, sizeof(regex_t)); - if (regcomp(&xhttp_url_skip_regexp, xhttp_url_skip, REG_EXTENDED)!=0) { + if(regcomp(&xhttp_url_skip_regexp, xhttp_url_skip, REG_EXTENDED) != 0) { LM_ERR("bad skip re %s\n", xhttp_url_skip); return E_BAD_RE; } @@ -180,30 +177,29 @@ static int mod_init(void) } -/** - * +/** + * */ -static int pv_get_huri(struct sip_msg *msg, pv_param_t *param, - pv_value_t *res) +static int pv_get_huri(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) { - if(msg==NULL || res==NULL) + if(msg == NULL || res == NULL) return -1; return pv_get_strval(msg, param, res, &msg->first_line.u.request.uri); } -/** - * +/** + * */ -static char* xhttp_to_sip(sip_msg_t* msg, int* new_msg_len) +static char *xhttp_to_sip(sip_msg_t *msg, int *new_msg_len) { unsigned int len, via_len; - char* via, *new_msg, *p; + char *via, *new_msg, *p; str ip, port; struct hostport hp; struct dest_info dst; - + ip.s = ip_addr2strz(&msg->rcv.src_ip); ip.len = strlen(ip.s); port.s = int2str(msg->rcv.src_port, &port.len); @@ -211,32 +207,29 @@ static char* xhttp_to_sip(sip_msg_t* msg, int* new_msg_len) hp.port = &port; init_dst_from_rcv(&dst, &msg->rcv); via = via_builder(&via_len, NULL, &dst, 0, 0, &hp); - if (via == 0) - { + if(via == 0) { LM_DBG("failed to build via\n"); return 0; } len = via_len + msg->len; p = new_msg = pkg_malloc(len + 1); - if (new_msg == 0) - { + if(new_msg == 0) { PKG_MEM_ERROR_FMT(" (%d bytes)\n", len); pkg_free(via); return 0; } /* new message: - * + * * Via: * */ - memcpy(p, msg->first_line.u.request.method.s, - msg->first_line.len); + memcpy(p, msg->first_line.u.request.method.s, msg->first_line.len); p += msg->first_line.len; memcpy(p, via, via_len); p += via_len; - memcpy(p, SIP_MSG_START(msg) + msg->first_line.len, - msg->len - msg->first_line.len); + memcpy(p, SIP_MSG_START(msg) + msg->first_line.len, + msg->len - msg->first_line.len); new_msg[len] = 0; pkg_free(via); *new_msg_len = len; @@ -244,11 +237,11 @@ static char* xhttp_to_sip(sip_msg_t* msg, int* new_msg_len) } -/** - * +/** + * */ -static int xhttp_process_request(sip_msg_t* orig_msg, - char* new_buf, unsigned int new_len) +static int xhttp_process_request( + sip_msg_t *orig_msg, char *new_buf, unsigned int new_len) { int ret; int backup_rt; @@ -257,10 +250,9 @@ static int xhttp_process_request(sip_msg_t* orig_msg, sr_kemi_eng_t *keng = NULL; str evrtname = str_init("xhttp:request"); - ret=0; + ret = 0; backup_rt = get_route_type(); - if (new_buf && new_len) - { + if(new_buf && new_len) { memset(&tmp_msg, 0, sizeof(sip_msg_t)); tmp_msg.buf = new_buf; tmp_msg.len = new_len; @@ -268,8 +260,7 @@ static int xhttp_process_request(sip_msg_t* orig_msg, tmp_msg.id = orig_msg->id; tmp_msg.set_global_address = orig_msg->set_global_address; tmp_msg.set_global_port = orig_msg->set_global_port; - if (parse_msg(new_buf, new_len, &tmp_msg) != 0) - { + if(parse_msg(new_buf, new_len, &tmp_msg) != 0) { LM_ERR("parse_msg failed\n"); goto error; } @@ -277,33 +268,31 @@ static int xhttp_process_request(sip_msg_t* orig_msg, } else { msg = orig_msg; } - - if ((msg->first_line.type != SIP_REQUEST) || (msg->via1 == 0) || - (msg->via1->error != PARSE_OK)) - { + + if((msg->first_line.type != SIP_REQUEST) || (msg->via1 == 0) + || (msg->via1->error != PARSE_OK)) { LM_CRIT("strange message: %.*s\n", msg->len, msg->buf); goto error; } set_route_type(EVENT_ROUTE); - if (exec_pre_script_cb(msg, REQUEST_CB_TYPE) == 0) - { + if(exec_pre_script_cb(msg, REQUEST_CB_TYPE) == 0) { goto done; } init_run_actions_ctx(&ra_ctx); - if(xhttp_route_no>=0) { - if (run_actions(&ra_ctx, event_rt.rlist[xhttp_route_no], msg) < 0) - { - ret=-1; + if(xhttp_route_no >= 0) { + if(run_actions(&ra_ctx, event_rt.rlist[xhttp_route_no], msg) < 0) { + ret = -1; LM_DBG("error while trying script\n"); goto done; } } else { keng = sr_kemi_eng_get(); - if(keng!=NULL) { - if(sr_kemi_route(keng, msg, EVENT_ROUTE, - &xhttp_event_callback, &evrtname)<0) { + if(keng != NULL) { + if(sr_kemi_route( + keng, msg, EVENT_ROUTE, &xhttp_event_callback, &evrtname) + < 0) { LM_ERR("error running event route kemi callback\n"); } } else { @@ -313,8 +302,7 @@ static int xhttp_process_request(sip_msg_t* orig_msg, done: exec_post_script_cb(msg, REQUEST_CB_TYPE); - if (msg != orig_msg) - { + if(msg != orig_msg) { free_sip_msg(msg); } set_route_type(backup_rt); @@ -325,72 +313,68 @@ error: } -/** - * +/** + * */ -static int xhttp_handler(sip_msg_t* msg) +static int xhttp_handler(sip_msg_t *msg) { int ret; - char* fake_msg; + char *fake_msg; int fake_msg_len; regmatch_t pmatch; char c; - ret=NONSIP_MSG_DROP; + ret = NONSIP_MSG_DROP; - if(!IS_HTTP(msg)) - { + if(!IS_HTTP(msg)) { /* oly http msg type */ return NONSIP_MSG_PASS; } - if(xhttp_url_skip!=NULL || xhttp_url_match!=NULL) - { + if(xhttp_url_skip != NULL || xhttp_url_match != NULL) { c = msg->first_line.u.request.uri.s[msg->first_line.u.request.uri.len]; - msg->first_line.u.request.uri.s[msg->first_line.u.request.uri.len] - = '\0'; - if (xhttp_url_skip!=NULL && - regexec(&xhttp_url_skip_regexp, msg->first_line.u.request.uri.s, - 1, &pmatch, 0)==0) - { + msg->first_line.u.request.uri.s[msg->first_line.u.request.uri.len] = + '\0'; + if(xhttp_url_skip != NULL + && regexec(&xhttp_url_skip_regexp, + msg->first_line.u.request.uri.s, 1, &pmatch, 0) + == 0) { LM_DBG("URL matched skip re\n"); - msg->first_line.u.request.uri.s[msg->first_line.u.request.uri.len] - = c; + msg->first_line.u.request.uri.s[msg->first_line.u.request.uri.len] = + c; return NONSIP_MSG_PASS; } - if (xhttp_url_match!=NULL && - regexec(&xhttp_url_match_regexp, msg->first_line.u.request.uri.s, - 1, &pmatch, 0)!=0) - { + if(xhttp_url_match != NULL + && regexec(&xhttp_url_match_regexp, + msg->first_line.u.request.uri.s, 1, &pmatch, 0) + != 0) { LM_DBG("URL not matched\n"); - msg->first_line.u.request.uri.s[msg->first_line.u.request.uri.len] - = c; + msg->first_line.u.request.uri.s[msg->first_line.u.request.uri.len] = + c; return NONSIP_MSG_PASS; } msg->first_line.u.request.uri.s[msg->first_line.u.request.uri.len] = c; } - if (msg->via1 == 0) - { + if(msg->via1 == 0) { fake_msg = xhttp_to_sip(msg, &fake_msg_len); - if (fake_msg == 0) - { + if(fake_msg == 0) { LM_ERR("out of memory\n"); - ret=NONSIP_MSG_ERROR; + ret = NONSIP_MSG_ERROR; } else { - DBG("new fake msg created (%d bytes):\n<%.*s>\n", - fake_msg_len, fake_msg_len, fake_msg); - if (xhttp_process_request(msg, fake_msg, fake_msg_len)<0) { - ret=NONSIP_MSG_ERROR; + DBG("new fake msg created (%d bytes):\n<%.*s>\n", fake_msg_len, + fake_msg_len, fake_msg); + if(xhttp_process_request(msg, fake_msg, fake_msg_len) < 0) { + ret = NONSIP_MSG_ERROR; } pkg_free(fake_msg); } return ret; } else { - LM_DBG("http msg unchanged (%d bytes):\n<%.*s>\n", - msg->len, msg->len, msg->buf); - if (xhttp_process_request(msg, 0, 0)<0) - ret=NONSIP_MSG_ERROR; + LM_DBG("http msg unchanged (%d bytes):\n<%.*s>\n", msg->len, msg->len, + msg->buf); + if(xhttp_process_request(msg, 0, 0) < 0) + ret = NONSIP_MSG_ERROR; return ret; } } @@ -399,28 +383,25 @@ static int xhttp_handler(sip_msg_t* msg) /** * */ -static int xhttp_send_reply(sip_msg_t *msg, int code, str *reason, - str *ctype, str *body) +static int xhttp_send_reply( + sip_msg_t *msg, int code, str *reason, str *ctype, str *body) { str tbuf; - if(ctype!=NULL && ctype->len>0) - { + if(ctype != NULL && ctype->len > 0) { /* add content-type */ - tbuf.len=sizeof("Content-Type: ") - 1 + ctype->len + CRLF_LEN; - tbuf.s=pkg_malloc(sizeof(char)*(tbuf.len)); + tbuf.len = sizeof("Content-Type: ") - 1 + ctype->len + CRLF_LEN; + tbuf.s = pkg_malloc(sizeof(char) * (tbuf.len)); - if (tbuf.s==0) - { + if(tbuf.s == 0) { PKG_MEM_ERROR; return -1; } memcpy(tbuf.s, "Content-Type: ", sizeof("Content-Type: ") - 1); - memcpy(tbuf.s+sizeof("Content-Type: ") - 1, ctype->s, ctype->len); - memcpy(tbuf.s+sizeof("Content-Type: ") - 1 + ctype->len, - CRLF, CRLF_LEN); - if (add_lump_rpl(msg, tbuf.s, tbuf.len, LUMP_RPL_HDR) == 0) - { + memcpy(tbuf.s + sizeof("Content-Type: ") - 1, ctype->s, ctype->len); + memcpy(tbuf.s + sizeof("Content-Type: ") - 1 + ctype->len, CRLF, + CRLF_LEN); + if(add_lump_rpl(msg, tbuf.s, tbuf.len, LUMP_RPL_HDR) == 0) { LM_ERR("failed to insert content-type lump\n"); pkg_free(tbuf.s); return -1; @@ -429,18 +410,15 @@ static int xhttp_send_reply(sip_msg_t *msg, int code, str *reason, LM_DBG("response with content-type: %.*s\n", ctype->len, ctype->s); } - if(body!=NULL && body->len>0) - { - if (add_lump_rpl(msg, body->s, body->len, LUMP_RPL_BODY) == 0) - { + if(body != NULL && body->len > 0) { + if(add_lump_rpl(msg, body->s, body->len, LUMP_RPL_BODY) == 0) { LM_ERR("Error while adding reply lump\n"); return -1; } LM_DBG("response with body: %.*s\n", body->len, body->s); } LM_DBG("sending out response: %d %.*s\n", code, reason->len, reason->s); - if (slb.sreply(msg, code, reason) < 0) - { + if(slb.sreply(msg, code, reason) < 0) { LM_ERR("Error while sending reply\n"); return -1; } @@ -450,83 +428,74 @@ static int xhttp_send_reply(sip_msg_t *msg, int code, str *reason, /** * */ -static int w_xhttp_send_reply(sip_msg_t* msg, char* pcode, char* preason, - char *pctype, char* pbody) +static int w_xhttp_send_reply( + sip_msg_t *msg, char *pcode, char *preason, char *pctype, char *pbody) { str body = {0, 0}; str reason = {"OK", 2}; str ctype = {"text/plain", 10}; int code = 200; - if(pcode==0 || preason==0 || pctype==0 || pbody==0) - { + if(pcode == 0 || preason == 0 || pctype == 0 || pbody == 0) { LM_ERR("invalid parameters\n"); return -1; } - if(fixup_get_ivalue(msg, (gparam_p)pcode, &code)!=0) - { + if(fixup_get_ivalue(msg, (gparam_p)pcode, &code) != 0) { LM_ERR("no reply code value\n"); return -1; } - if(code<100 || code>700) - { + if(code < 100 || code > 700) { LM_ERR("invalid code parameter\n"); return -1; } - if(fixup_get_svalue(msg, (gparam_p)preason, &reason)!=0) - { + if(fixup_get_svalue(msg, (gparam_p)preason, &reason) != 0) { LM_ERR("unable to get reason\n"); return -1; } - if(reason.s==NULL || reason.len == 0) - { + if(reason.s == NULL || reason.len == 0) { LM_ERR("invalid reason parameter\n"); return -1; } - if(fixup_get_svalue(msg, (gparam_p)pctype, &ctype)!=0) - { + if(fixup_get_svalue(msg, (gparam_p)pctype, &ctype) != 0) { LM_ERR("unable to get content type\n"); return -1; } - if(ctype.s==NULL) - { + if(ctype.s == NULL) { LM_ERR("invalid content-type parameter\n"); return -1; } - if(fixup_get_svalue(msg, (gparam_p)pbody, &body)!=0) - { + if(fixup_get_svalue(msg, (gparam_p)pbody, &body) != 0) { LM_ERR("unable to get body\n"); return -1; } - if(body.s==NULL) - { + if(body.s == NULL) { LM_ERR("invalid body parameter\n"); return -1; } - if(xhttp_send_reply(msg, code, &reason, &ctype, &body)<0) + if(xhttp_send_reply(msg, code, &reason, &ctype, &body) < 0) return -1; return 1; } -/** - * +/** + * */ -static int fixup_xhttp_reply(void** param, int param_no) +static int fixup_xhttp_reply(void **param, int param_no) { - if (param_no == 1) { - return fixup_igp_null(param, 1); - } else if (param_no == 2) { - return fixup_spve_null(param, 1); - } else if (param_no == 3) { - return fixup_spve_null(param, 1); - } else if (param_no == 4) { - return fixup_spve_null(param, 1); + if(param_no == 1) { + return fixup_igp_null(param, 1); + } else if(param_no == 2) { + return fixup_spve_null(param, 1); + } else if(param_no == 3) { + return fixup_spve_null(param, 1); + } else if(param_no == 4) { + return fixup_spve_null(param, 1); } return 0; } @@ -534,9 +503,9 @@ static int fixup_xhttp_reply(void** param, int param_no) /** * */ -int bind_xhttp(xhttp_api_t* api) +int bind_xhttp(xhttp_api_t *api) { - if (!api) { + if(!api) { ERR("Invalid parameter value\n"); return -1; } diff --git a/src/modules/xhttp/xhttp_trans.c b/src/modules/xhttp/xhttp_trans.c index 22e564788..e24409a53 100644 --- a/src/modules/xhttp/xhttp_trans.c +++ b/src/modules/xhttp/xhttp_trans.c @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2013 Crocodile RCS Ltd * * This file is part of Kamailio, a free SIP server. @@ -13,8 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ @@ -23,73 +23,82 @@ #include "../../core/trim.h" #include "xhttp_trans.h" -enum _tr_xhttp_type { TR_XHTTP_NONE = 0, TR_XHTTPURL, TR_XHTTPURLQUERYSTRING }; -enum _tr_xhttpurl_subtype { TR_XHTTPURL_NONE = 0, TR_XHTTPURL_PATH, - TR_XHTTPURL_QUERYSTRING}; -enum _tr_xhttpquerystring_subtype { TR_XHTTPUTLQUERYSTRING_NONE = 0, - TR_XHTTPURLQUERYSTRING_VALUE}; +enum _tr_xhttp_type +{ + TR_XHTTP_NONE = 0, + TR_XHTTPURL, + TR_XHTTPURLQUERYSTRING +}; +enum _tr_xhttpurl_subtype +{ + TR_XHTTPURL_NONE = 0, + TR_XHTTPURL_PATH, + TR_XHTTPURL_QUERYSTRING +}; +enum _tr_xhttpquerystring_subtype +{ + TR_XHTTPUTLQUERYSTRING_NONE = 0, + TR_XHTTPURLQUERYSTRING_VALUE +}; static str _httpurl_str = {0, 0}; static int _httpurl_querystring_pos = 0; -int xhttp_tr_eval_xhttpurl(struct sip_msg *msg, tr_param_t *tp, int subtype, - pv_value_t *val) +int xhttp_tr_eval_xhttpurl( + struct sip_msg *msg, tr_param_t *tp, int subtype, pv_value_t *val) { int pos = 0; - if (val == NULL || val->flags & PV_VAL_NULL) + if(val == NULL || val->flags & PV_VAL_NULL) return -1; - if (!(val->flags & PV_VAL_STR)) - { + if(!(val->flags & PV_VAL_STR)) { val->rs.s = int2str(val->ri, &val->rs.len); val->flags = PV_VAL_STR; } - if (_httpurl_str.len == 0 || _httpurl_str.len != val->rs.len - || strncmp(_httpurl_str.s, val->rs.s, val->rs.len) != 0) - { - if (val->rs.len > _httpurl_str.len) - { - if (_httpurl_str.s) pkg_free(_httpurl_str.s); - _httpurl_str.s = (char *) pkg_malloc( - (val->rs.len + 1) * sizeof(char)); - if (_httpurl_str.s == NULL) - { + if(_httpurl_str.len == 0 || _httpurl_str.len != val->rs.len + || strncmp(_httpurl_str.s, val->rs.s, val->rs.len) != 0) { + if(val->rs.len > _httpurl_str.len) { + if(_httpurl_str.s) + pkg_free(_httpurl_str.s); + _httpurl_str.s = + (char *)pkg_malloc((val->rs.len + 1) * sizeof(char)); + if(_httpurl_str.s == NULL) { PKG_MEM_ERROR; - memset(&_httpurl_str.s, 0, sizeof(str)); + memset(&_httpurl_str, 0, sizeof(str)); return -1; } } _httpurl_str.len = val->rs.len; memcpy(_httpurl_str.s, val->rs.s, val->rs.len); - while (pos < val->rs.len && val->rs.s[pos] != '?') pos++; + while(pos < val->rs.len && val->rs.s[pos] != '?') + pos++; _httpurl_querystring_pos = (pos >= val->rs.len) ? 0 : pos + 1; } - switch (subtype) - { - case TR_XHTTPURL_PATH: - val->rs.len = (_httpurl_querystring_pos == 0) - ? val->rs.len : _httpurl_querystring_pos - 1; - break; - - case TR_XHTTPURL_QUERYSTRING: - if (_httpurl_querystring_pos == 0) - { - val->rs.s[0] = '\0'; - val->rs.len = 0; + switch(subtype) { + case TR_XHTTPURL_PATH: + val->rs.len = (_httpurl_querystring_pos == 0) + ? val->rs.len + : _httpurl_querystring_pos - 1; break; - } - val->rs.s = &val->rs.s[_httpurl_querystring_pos]; - val->rs.len = val->rs.len - _httpurl_querystring_pos; - break; + case TR_XHTTPURL_QUERYSTRING: + if(_httpurl_querystring_pos == 0) { + val->rs.s[0] = '\0'; + val->rs.len = 0; + break; + } + + val->rs.s = &val->rs.s[_httpurl_querystring_pos]; + val->rs.len = val->rs.len - _httpurl_querystring_pos; + break; - default: - LM_ERR("unknown subtype %d\n", subtype); - return -1; + default: + LM_ERR("unknown subtype %d\n", subtype); + return -1; } return 0; @@ -100,7 +109,7 @@ char *xhttp_tr_parse_url(str *in, trans_t *t) char *p; str name; - if (in == NULL || in->s == NULL || t == NULL) + if(in == NULL || in->s == NULL || t == NULL) return NULL; p = in->s; @@ -108,33 +117,28 @@ char *xhttp_tr_parse_url(str *in, trans_t *t) t->type = TR_XHTTPURL; t->trf = xhttp_tr_eval_xhttpurl; - /* find next token */ - while (is_in_str(p, in) && *p != TR_PARAM_MARKER && *p != TR_RBRACKET) - { + /* find next token */ + while(is_in_str(p, in) && *p != TR_PARAM_MARKER && *p != TR_RBRACKET) { p++; } - if (*p == '\0') - { - LM_ERR("invalid transformation: %.*s\n", in->len, in->s); - goto error; - } - name.len = p - name.s; - trim(&name); + if(*p == '\0') { + LM_ERR("invalid transformation: %.*s\n", in->len, in->s); + goto error; + } + name.len = p - name.s; + trim(&name); - if (name.len == 4 && strncasecmp(name.s, "path", 4) == 0) - { + if(name.len == 4 && strncasecmp(name.s, "path", 4) == 0) { t->subtype = TR_XHTTPURL_PATH; goto done; - } - else if (name.len == 11 && strncasecmp(name.s, "querystring", 11) == 0) - { + } else if(name.len == 11 && strncasecmp(name.s, "querystring", 11) == 0) { t->subtype = TR_XHTTPURL_QUERYSTRING; goto done; } - LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s, - name.len, name.s, name.len); + LM_ERR("unknown transformation: %.*s/%.*s/%d!\n", in->len, in->s, name.len, + name.s, name.len); error: return NULL; diff --git a/src/modules/xhttp/xhttp_trans.h b/src/modules/xhttp/xhttp_trans.h index 0750be738..d0691da43 100644 --- a/src/modules/xhttp/xhttp_trans.h +++ b/src/modules/xhttp/xhttp_trans.h @@ -1,4 +1,4 @@ -/* +/* * Copyright (C) 2013 Crocodile RCS Ltd * * This file is part of Kamailio, a free SIP server. @@ -13,8 +13,8 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ diff --git a/src/modules/xmpp/README b/src/modules/xmpp/README index f860e969a..28c605ba4 100644 --- a/src/modules/xmpp/README +++ b/src/modules/xmpp/README @@ -228,8 +228,8 @@ Chapter 1. Admin Guide The domain of the SIP-to-XMPP gateway - it has to be in DNS or SIP UA has to use outbound proxy to SIP-to-XMPP gateway IP address. It has to - be used as domain in the the destination address of the messages sent - by SIP users to XMPP users: + be used as domain in the destination address of the messages sent by + SIP users to XMPP users: "sip:usernamejabber_server@gateway_domain". Default value is "sip-xmpp.example.org". diff --git a/src/modules/xmpp/doc/xmpp_admin.xml b/src/modules/xmpp/doc/xmpp_admin.xml index ab201c5a8..129acbc42 100644 --- a/src/modules/xmpp/doc/xmpp_admin.xml +++ b/src/modules/xmpp/doc/xmpp_admin.xml @@ -230,7 +230,7 @@ The domain of the SIP-to-XMPP gateway - it has to be in DNS or SIP UA has to use outbound proxy to SIP-to-XMPP gateway IP address. It has to be used - as domain in the the destination address of the messages sent by SIP users + as domain in the destination address of the messages sent by SIP users to XMPP users: "sip:usernamedelim]]>jabber_server@gateway_domain". diff --git a/utils/kamctl/dbtext/kamailio/version b/utils/kamctl/dbtext/kamailio/version index a733827f1..a9d31882d 100644 --- a/utils/kamctl/dbtext/kamailio/version +++ b/utils/kamctl/dbtext/kamailio/version @@ -1,72 +1,72 @@ id(int,auto) table_name(string) table_version(int) -version:1 -acc:5 -acc_cdrs:2 -active_watchers:12 -address:6 -aliases:8 -carrier_name:1 -carrierfailureroute:2 -carrierroute:3 -cpl:1 -dbaliases:1 -dialog:7 -dialog_vars:1 -dialplan:2 -dispatcher:4 -domain:2 -domain_attrs:1 -domain_name:1 -domainpolicy:2 -dr_gateways:3 -dr_groups:2 -dr_gw_lists:1 -dr_rules:3 -globalblacklist:1 -grp:2 -htable:2 -imc_members:1 -imc_rooms:1 -lcr_gw:3 -lcr_rule:3 -lcr_rule_target:1 -location:9 -location_attrs:1 -matrix:1 -missed_calls:4 -mohqcalls:1 -mohqueues:1 -mtree:1 -mtrees:2 -pdt:1 -pl_pipes:1 -presentity:5 -pua:7 -purplemap:1 -re_grp:1 -rls_presentity:1 -rls_watchers:3 -rtpengine:1 -rtpproxy:1 -sca_subscriptions:2 -secfilter:1 -silo:8 -sip_trace:4 -speed_dial:2 -subscriber:7 -topos_d:1 -topos_t:1 -trusted:6 -uacreg:4 -uid_credentials:7 -uid_domain:2 -uid_domain_attrs:1 -uid_global_attrs:1 -uid_uri:3 -uid_uri_attrs:2 -uid_user_attrs:3 -uri:1 -userblacklist:1 -usr_preferences:2 -watchers:3 -xcap:4 +0:version:1 +0:acc:5 +0:acc_cdrs:2 +0:active_watchers:12 +0:address:6 +0:aliases:8 +0:carrier_name:1 +0:carrierfailureroute:2 +0:carrierroute:3 +0:cpl:1 +0:dbaliases:1 +0:dialog:7 +0:dialog_vars:1 +0:dialplan:2 +0:dispatcher:4 +0:domain:2 +0:domain_attrs:1 +0:domain_name:1 +0:domainpolicy:2 +0:dr_gateways:3 +0:dr_groups:2 +0:dr_gw_lists:1 +0:dr_rules:3 +0:globalblacklist:1 +0:grp:2 +0:htable:2 +0:imc_members:1 +0:imc_rooms:1 +0:lcr_gw:3 +0:lcr_rule:3 +0:lcr_rule_target:1 +0:location:9 +0:location_attrs:1 +0:matrix:1 +0:missed_calls:4 +0:mohqcalls:1 +0:mohqueues:1 +0:mtree:1 +0:mtrees:2 +0:pdt:1 +0:pl_pipes:1 +0:presentity:5 +0:pua:7 +0:purplemap:1 +0:re_grp:1 +0:rls_presentity:1 +0:rls_watchers:3 +0:rtpengine:1 +0:rtpproxy:1 +0:sca_subscriptions:2 +0:secfilter:1 +0:silo:8 +0:sip_trace:4 +0:speed_dial:2 +0:subscriber:7 +0:topos_d:1 +0:topos_t:1 +0:trusted:6 +0:uacreg:4 +0:uid_credentials:7 +0:uid_domain:2 +0:uid_domain_attrs:1 +0:uid_global_attrs:1 +0:uid_uri:3 +0:uid_uri_attrs:2 +0:uid_user_attrs:3 +0:uri:1 +0:userblacklist:1 +0:usr_preferences:2 +0:watchers:3 +0:xcap:4 diff --git a/utils/kamctl/kamctl b/utils/kamctl/kamctl index 5be26efbc..a2d839b50 100755 --- a/utils/kamctl/kamctl +++ b/utils/kamctl/kamctl @@ -953,14 +953,9 @@ $AVP_USER_COLUMN='$OSERUSER' AND $AVP_DOMAIN_COLUMN='$OSERDOMAIN'" cisco_restart() { require_ctlengine myhost=`get_my_host` - CMDPARAMS="tm.t_uac_start NOTIFY $1 . . \"From:sip:daemon@$myhost\r\nTo:<$1>\r\nEvent:check-sync\r\nContact:sip:daemon@$myhost\r\n\"" + CMDPARAMS="= tm.t_uac_start NOTIFY \"$1\" \".\" \".\" \"From:sip:daemon@$myhost=CRLF=To:<$1>=CRLF=Event:check-sync=CRLF=Contact:sip:daemon@$myhost=CRLF=\"" - if [ $CTLENGINETYPE -eq 1 ] ; then - ctl_cmd_run $CMDPARAMS - else - RET=`ctl_cmd_run $CMDPARAMS | head -1` - print_status $RET - fi + ctl_cmd_run $CMDPARAMS } # @@ -1795,6 +1790,15 @@ ksr_srv() { mecho "list server rpc commands" ctl_cmd_run system.listMethods ;; + debug) + require_ctlengine + mecho "server debug level command" + if [ $# -lt 2 ] ; then + ctl_cmd_run corex.debug + else + ctl_cmd_run corex.debug $2 + fi + ;; version) require_ctlengine mecho "list server version" @@ -2036,13 +2040,8 @@ kamailio_stop() { options_ping() { myhost=`get_my_host` require_ctlengine - CMDPARAMS="tm.t_uac_start OPTIONS \"$1\" \".\" \".\" \"From:sip:daemon@$myhost"$'\r\n'"To:<$1>"$'\r\n'"Contact:sip:daemon@$myhost"$'\r\n'"\"" - if [ $CTLENGINETYPE -eq 1 ] ; then - ctl_cmd_run $CMDPARAMS - else - RET=`ctl_cmd_run $CMDPARAMS | head -1` - print_status $RET - fi + CMDPARAMS="= tm.t_uac_wait_block OPTIONS \"$1\" \".\" \".\" \"From:sip:daemon@$myhost=CRLF=To:<$1>=CRLF=Contact:sip:daemon@$myhost=CRLF=\"" + ctl_cmd_run $CMDPARAMS } # diff --git a/utils/kamctl/kamctl.base b/utils/kamctl/kamctl.base index bc8f212f7..b08856506 100644 --- a/utils/kamctl/kamctl.base +++ b/utils/kamctl/kamctl.base @@ -554,6 +554,7 @@ cat <] ........... control the server debug level srv version ................... show the server version EOF } diff --git a/utils/kamctl/kamctl.rpcfifo b/utils/kamctl/kamctl.rpcfifo index 743f15bc4..c8e532981 100644 --- a/utils/kamctl/kamctl.rpcfifo +++ b/utils/kamctl/kamctl.rpcfifo @@ -101,6 +101,12 @@ rpc_cmd() chmod a+w $path fi + PARAMEVAL="no" + if [ "$1" = "=" ]; then + PARAMEVAL="yes" + shift + fi + # construct the command now CMD="{\"jsonrpc\": \"2.0\", \"method\": \"$1\""; shift @@ -114,7 +120,12 @@ rpc_cmd() shift while [ -n "$1" ] ; do rpcparamval "${1}" - CMD="${CMD}, ${RPCVAL}" + if [ "$PARAMEVAL" = "yes" ]; then + CMDPARAM=`echo "$RPCVAL" | awk -F'=CRLF=' '{$1=$1}1' OFS='\r\n'` + CMD="${CMD}, ${CMDPARAM}" + else + CMD="${CMD}, ${RPCVAL}" + fi shift done CMD="${CMD}]" diff --git a/utils/pdbt/pdbt.c b/utils/pdbt/pdbt.c index 6521985b2..5a52cf8c7 100644 --- a/utils/pdbt/pdbt.c +++ b/utils/pdbt/pdbt.c @@ -297,7 +297,7 @@ int dt_write_tree(const struct dt_node_t *root, const char* filename) char number[25]; number[0] = '\0'; - fd = creat(filename, S_IRWXU); + fd = creat(filename, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (fd < 0) { LERR("cannot create file '%s'\n", filename); return -1; @@ -370,7 +370,7 @@ int save_mmap(struct dt_node_t *root, char *filename) { int fd; int n; - fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IRWXU); + fd = open(filename, O_RDWR|O_CREAT|O_TRUNC, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH); if (fd < 0) { LERR("cannot create file '%s'\n", filename); return -1;